mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 12:43:16 -04:00
Description:add abilitystagecontext applicationcontext context transfter
Sig:SIG_ApplicationFramework Feature or BugFix: Feature Binary Source: No Signed-off-by: zhangyafei.echo <zhangyafei12@huawei.com> Change-Id: I03ae6b16d51395b372752cf5ab5a8738faa726d9 Description:add context transfer dynamic Sig:SIG_ApplicationFramework Feature or BugFix: Feature Binary Source: No Signed-off-by: zhangyafei.echo <zhangyafei12@huawei.com> Change-Id: I60311120b492a947ab91a7035e304e55669c7988 Description:context transfer bugfix. Sig:SIG_ApplicationFramework Feature or BugFix: Feature Binary Source: No Signed-off-by: zhangyafei.echo <zhangyafei12@huawei.com> Change-Id: Iff2ffa198547d51805ca09dbf977ecaa31d92d38
This commit is contained in:
@@ -22,7 +22,6 @@ group("ani_packages") {
|
||||
"${ability_runtime_path}/frameworks/ets/ani/ani_wantagent_common:ani_wantagent_common",
|
||||
"${ability_runtime_path}/frameworks/ets/ani/app_manager:app_manager_ani",
|
||||
"${ability_runtime_path}/frameworks/ets/ani/application:application_ani",
|
||||
"${ability_runtime_path}/frameworks/ets/ani/app/ability_context:ability_context_ani_kit",
|
||||
"${ability_runtime_path}/frameworks/ets/ani/insight_intent/insight_intent_driver:insight_intent_driver_ani_kit",
|
||||
"${ability_runtime_path}/frameworks/ets/ani/native_constructor:context_ani",
|
||||
"${ability_runtime_path}/frameworks/ets/ani/uri_permission_manager:uri_permission_manager_ani_kit",
|
||||
|
||||
@@ -49,6 +49,7 @@ ohos_shared_library("ani_common") {
|
||||
"src/ani_common_start_options.cpp",
|
||||
"src/ani_common_util.cpp",
|
||||
"src/ani_common_want.cpp",
|
||||
"src/context_transfer.cpp",
|
||||
"src/ets_application_context_utils.cpp",
|
||||
"src/ets_context_utils.cpp",
|
||||
"src/ets_data_struct_converter.cpp",
|
||||
|
||||
@@ -74,6 +74,8 @@ bool SetDoublePropertyObject(ani_env *env, ani_object param, const char *name, d
|
||||
bool SetDoublePropertyValue(ani_env *env, ani_object param, const char *name, double value);
|
||||
bool SetStringArrayProperty(ani_env *env, ani_object param, const char *name, const std::vector<std::string> &values);
|
||||
bool SetRefProperty(ani_env *env, ani_object param, const char *name, ani_ref value);
|
||||
|
||||
bool GetStaticFieldString(ani_env *env, ani_class classObj, const char *fieldName, std::string &value);
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
#endif // OHOS_ABILITY_RUNTIME_ANI_COMMON_UTIL_H
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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_CONTEXT_TRANSFER_H
|
||||
#define OHOS_ABILITY_RUNTIME_CONTEXT_TRANSFER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ani.h"
|
||||
#include "context.h"
|
||||
#include "native_engine/native_engine.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
using CreateStaticObject = std::function<ani_object (ani_env *aniEnv, std::shared_ptr<Context> context)>;
|
||||
using CreateDynamicObject = std::function<napi_value (napi_env napiEnv, std::shared_ptr<Context> context)>;
|
||||
class ContextTransfer {
|
||||
public:
|
||||
static ContextTransfer &GetInstance();
|
||||
ContextTransfer() = default;
|
||||
~ContextTransfer() = default;
|
||||
|
||||
void RegisterStaticObjectCreator(const std::string &contextType, const CreateStaticObject &createFunc);
|
||||
ani_object GetStaticObject(const std::string &contextType, ani_env *aniEnv, std::shared_ptr<Context> context);
|
||||
|
||||
void RegisterDynamicObjectCreator(const std::string &contextType, const CreateDynamicObject &createFunc);
|
||||
napi_value GetDynamicObject(const std::string &contextType, napi_env napiEnv, std::shared_ptr<Context> context);
|
||||
|
||||
bool IsStaticCreatorExist(const std::string &contextType);
|
||||
bool IsDynamicCreatorExist(const std::string &contextType);
|
||||
|
||||
private:
|
||||
ContextTransfer(const ContextTransfer&) = delete;
|
||||
ContextTransfer(ContextTransfer&&) = delete;
|
||||
ContextTransfer& operator=(const ContextTransfer&) = delete;
|
||||
ContextTransfer& operator=(ContextTransfer&&) = delete;
|
||||
|
||||
std::mutex creatorMutex_;
|
||||
std::unordered_map<std::string, CreateStaticObject> staticCreators_;
|
||||
std::unordered_map<std::string, CreateDynamicObject> dynamicCreators_;
|
||||
};
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
#endif // OHOS_ABILITY_RUNTIME_CONTEXT_TRANSFER_H
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
static void ThrowInvalidParamError(ani_env *env, const std::string &message);
|
||||
static void ThrowErrorByNativeErr(ani_env *env, int32_t err);
|
||||
static void ThrowNotSystemAppError(ani_env *env);
|
||||
static void ThrowEtsTransferClassError(ani_env *env);
|
||||
|
||||
static ani_object CreateError(ani_env *env, const AbilityErrorCode &err);
|
||||
static ani_object CreateError(ani_env *env, ani_int code, const std::string &msg);
|
||||
|
||||
@@ -558,7 +558,7 @@ bool GetStringOrUndefined(ani_env *env, ani_object param, const char *name, std:
|
||||
ani_ref obj = nullptr;
|
||||
ani_boolean isUndefined = true;
|
||||
ani_status status = ANI_ERROR;
|
||||
|
||||
|
||||
if (env == nullptr || param == nullptr || name == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::ANI, "null env or param or name");
|
||||
return false;
|
||||
@@ -1181,5 +1181,42 @@ bool SetRefProperty(ani_env *env, ani_object param, const char *name, ani_ref va
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetStaticFieldString(ani_env *env, ani_class classObj, const char *fieldName, std::string &value)
|
||||
{
|
||||
if (env == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::JSNAPI, "null env");
|
||||
return false;
|
||||
}
|
||||
|
||||
ani_status status = ANI_ERROR;
|
||||
ani_static_field field {};
|
||||
if ((status = env->Class_FindStaticField(classObj, fieldName, &field)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::JSNAPI, "Class_FindStaticField status: %{public}d", status);
|
||||
return false;
|
||||
}
|
||||
|
||||
ani_ref obj = nullptr;
|
||||
if ((status = env->Class_GetStaticField_Ref(classObj, field, &obj)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::JSNAPI, "Class_GetStaticField_Ref status: %{public}d", status);
|
||||
return false;
|
||||
}
|
||||
|
||||
ani_boolean isUndefined = true;
|
||||
if ((status = env->Reference_IsUndefined(obj, &isUndefined)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::JSNAPI, "status: %{public}d", status);
|
||||
return false;
|
||||
}
|
||||
if (isUndefined) {
|
||||
TAG_LOGE(AAFwkTag::JSNAPI, "%{public}s : undefined", fieldName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AppExecFwk::GetStdString(env, reinterpret_cast<ani_string>(obj), value)) {
|
||||
TAG_LOGE(AAFwkTag::JSNAPI, "GetStdString failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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 "context_transfer.h"
|
||||
|
||||
#include "hilog_tag_wrapper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
ContextTransfer &ContextTransfer::GetInstance()
|
||||
{
|
||||
static ContextTransfer contextTransfer;
|
||||
return contextTransfer;
|
||||
}
|
||||
|
||||
void ContextTransfer::RegisterStaticObjectCreator(const std::string &contextType, const CreateStaticObject &createFunc)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "Reg static creator for %{public}s", contextType.c_str());
|
||||
std::lock_guard<std::mutex> lock(creatorMutex_);
|
||||
staticCreators_.emplace(contextType, createFunc);
|
||||
}
|
||||
|
||||
ani_object ContextTransfer::GetStaticObject(const std::string &contextType, ani_env *aniEnv,
|
||||
std::shared_ptr<Context> context)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "Get static creator for %{public}s", contextType.c_str());
|
||||
std::lock_guard<std::mutex> lock(creatorMutex_);
|
||||
auto it = staticCreators_.find(contextType);
|
||||
if (it != staticCreators_.end()) {
|
||||
return it->second(aniEnv, context);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ContextTransfer::RegisterDynamicObjectCreator(const std::string &contextType,
|
||||
const CreateDynamicObject &createFunc)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "Reg dynamic creator for %{public}s", contextType.c_str());
|
||||
std::lock_guard<std::mutex> lock(creatorMutex_);
|
||||
dynamicCreators_.emplace(contextType, createFunc);
|
||||
}
|
||||
|
||||
napi_value ContextTransfer::GetDynamicObject(const std::string &contextType, napi_env napiEnv,
|
||||
std::shared_ptr<Context> context)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "Get dynamic creator for %{public}s", contextType.c_str());
|
||||
std::lock_guard<std::mutex> lock(creatorMutex_);
|
||||
auto it = dynamicCreators_.find(contextType);
|
||||
if (it != dynamicCreators_.end()) {
|
||||
return it->second(napiEnv, context);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ContextTransfer::IsStaticCreatorExist(const std::string &contextType)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(creatorMutex_);
|
||||
auto it = staticCreators_.find(contextType);
|
||||
return it != staticCreators_.end();
|
||||
}
|
||||
|
||||
bool ContextTransfer::IsDynamicCreatorExist(const std::string &contextType)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(creatorMutex_);
|
||||
auto it = dynamicCreators_.find(contextType);
|
||||
return it != dynamicCreators_.end();
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
@@ -559,6 +559,13 @@ ani_object EtsApplicationContextUtils::CreateEtsApplicationContext(ani_env* aniE
|
||||
return nullptr;
|
||||
}
|
||||
ContextUtil::CreateEtsBaseContext(aniEnv, applicationContextClass, applicationContextObject, applicationContext);
|
||||
ani_ref* contextGlobalRef = new (std::nothrow) ani_ref;
|
||||
if ((status = aniEnv->GlobalReference_Create(applicationContextObject, contextGlobalRef)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "GlobalReference_Create failed status: %{public}d", status);
|
||||
delete contextGlobalRef;
|
||||
return nullptr;
|
||||
}
|
||||
applicationContext->Bind(contextGlobalRef);
|
||||
return applicationContextObject;
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
|
||||
@@ -26,6 +26,8 @@ constexpr const char *ERR_MSG_INVALID_NUM_PARAMS = "Parameter error. The number
|
||||
constexpr const char *NOT_SYSTEM_APP = "The application is not system-app, can not use system-api.";
|
||||
constexpr const char *BUSINESS_ERROR_CLASS = "L@ohos/base/BusinessError;";
|
||||
constexpr const char *ERROR_CLASS_NAME = "Lescompat/Error;";
|
||||
constexpr const char* ERROR_MSG_TRANSFER_CLASS_NOT_FOUND = "Unable to find the class for transferring.";
|
||||
constexpr int32_t ERROR_CODE_TRANSFER_CLASS_NOT_FOUND = 10200067;
|
||||
} // namespace
|
||||
|
||||
void EtsErrorUtil::ThrowError(ani_env *env, ani_object err)
|
||||
@@ -106,6 +108,12 @@ void EtsErrorUtil::ThrowNotSystemAppError(ani_env *env)
|
||||
env, static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_NOT_SYSTEM_APP), NOT_SYSTEM_APP));
|
||||
}
|
||||
|
||||
void EtsErrorUtil::ThrowEtsTransferClassError(ani_env *env)
|
||||
{
|
||||
EtsErrorUtil::ThrowError(env, EtsErrorUtil::CreateError(
|
||||
env, static_cast<int32_t>(ERROR_CODE_TRANSFER_CLASS_NOT_FOUND), ERROR_MSG_TRANSFER_CLASS_NOT_FOUND));
|
||||
}
|
||||
|
||||
void EtsErrorUtil::ThrowInvalidParamError(ani_env *env, const std::string &message)
|
||||
{
|
||||
if (env == nullptr) {
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
# 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/config/components/ets_frontend/ets2abc_config.gni")
|
||||
import("//build/ohos.gni")
|
||||
import("//foundation/ability/ability_runtime/ability_runtime.gni")
|
||||
|
||||
ohos_shared_library("ability_context_ani_kit") {
|
||||
branch_protector_ret = "pac_ret"
|
||||
sanitize = {
|
||||
cfi = true
|
||||
cfi_cross_dso = true
|
||||
cfi_vcall_icall_only = true
|
||||
debug = false
|
||||
}
|
||||
|
||||
include_dirs = [
|
||||
"./include",
|
||||
"${ability_runtime_path}/interfaces/inner_api",
|
||||
"${ability_runtime_path}/interfaces/kits/native/appkit",
|
||||
"${ability_runtime_path}/interfaces/kits/native/ability/native/ability_runtime",
|
||||
"${ability_runtime_services_path}/common/include",
|
||||
"${ability_runtime_path}/frameworks/ets/ani/ani_common/include",
|
||||
"${ability_runtime_path}/frameworks/ets/ani/ui_ability/include",
|
||||
]
|
||||
|
||||
configs = []
|
||||
|
||||
public_configs = []
|
||||
|
||||
sources = [ "./src/ets_ability_context_module.cpp" ]
|
||||
|
||||
cflags = []
|
||||
if (target_cpu == "arm") {
|
||||
cflags += [ "-DBINDER_IPC_32BIT" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
"${ability_runtime_innerkits_path}/ani_base_context:ani_base_context",
|
||||
"${ability_runtime_innerkits_path}/runtime:runtime",
|
||||
"${ability_runtime_native_path}/ability/native:abilitykit_native",
|
||||
"${ability_runtime_native_path}/ability/native:ui_ability_ani",
|
||||
"${ability_runtime_native_path}/ability:ability_context_native",
|
||||
"${ability_runtime_native_path}/appkit:app_context",
|
||||
"${ability_runtime_native_path}/appkit:app_context_utils",
|
||||
"${ability_runtime_native_path}/appkit:appkit_native",
|
||||
"${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"c_utils:utils",
|
||||
"hilog:libhilog",
|
||||
"hitrace:hitrace_meter",
|
||||
"napi:ace_napi",
|
||||
"runtime_core:ani",
|
||||
"runtime_core:ani_helpers",
|
||||
]
|
||||
|
||||
innerapi_tags = [ "platformsdk" ]
|
||||
subsystem_name = "ability"
|
||||
part_name = "ability_runtime"
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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_ETS_ABILITY_CONTEXT_MODULE_H
|
||||
#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_CONTEXT_MODULE_H
|
||||
|
||||
#include <memory>
|
||||
#include "ability_context.h"
|
||||
#include "ani.h"
|
||||
#include "native_engine/native_engine.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
class EtsAbilityContextModule {
|
||||
public:
|
||||
EtsAbilityContextModule() = default;
|
||||
~EtsAbilityContextModule() = default;
|
||||
|
||||
EtsAbilityContextModule(const EtsAbilityContextModule&) = delete;
|
||||
EtsAbilityContextModule(EtsAbilityContextModule&&) = delete;
|
||||
EtsAbilityContextModule& operator=(const EtsAbilityContextModule&) = delete;
|
||||
EtsAbilityContextModule& operator=(EtsAbilityContextModule&&) = delete;
|
||||
|
||||
static ani_object NativeTransferStatic(ani_env *aniEnv, ani_object aniObj, ani_object input, ani_object type);
|
||||
static ani_object NativeTransferDynamic(ani_env *aniEnv, ani_class aniCls, ani_object input);
|
||||
static napi_value GetOrCreateDynamicObject(napi_env napiEnv,
|
||||
std::shared_ptr<AbilityContext> abilityContext);
|
||||
|
||||
private:
|
||||
static bool IsInstanceOf(ani_env *aniEnv, ani_object aniObj);
|
||||
static std::unique_ptr<NativeReference> CreateNativeReference(napi_env napiEnv,
|
||||
std::shared_ptr<AbilityContext> abilityContext);
|
||||
static ani_object CreateDynamicObject(ani_env *aniEnv, ani_class aniCls,
|
||||
std::shared_ptr<AbilityContext> abilityContext);
|
||||
};
|
||||
|
||||
void EtsAbilityContextModuleInit(ani_env *aniEnv);
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_CONTEXT_MODULE_H
|
||||
@@ -1,387 +0,0 @@
|
||||
/*
|
||||
* 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 "ets_ability_context_module.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include "ability_context.h"
|
||||
#include "ani_base_context.h"
|
||||
#include "ani_common_util.h"
|
||||
#include "context_transfer.h"
|
||||
#include "ets_ability_context.h"
|
||||
#include "ets_error_utils.h"
|
||||
#include "hilog_tag_wrapper.h"
|
||||
#include "hitrace_meter.h"
|
||||
#include "interop_js/arkts_esvalue.h"
|
||||
#include "interop_js/arkts_interop_js_api.h"
|
||||
#include "interop_js/hybridgref_ani.h"
|
||||
#include "interop_js/hybridgref_napi.h"
|
||||
#include "js_ability_context.h"
|
||||
#include "js_runtime_utils.h"
|
||||
#include "native_engine/native_engine.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
namespace {
|
||||
constexpr const char *ETS_ABILITY_CONTEXT_CLASS_NAME = "Lapplication/UIAbilityContext/UIAbilityContext;";
|
||||
} // namespace
|
||||
|
||||
ani_object EtsAbilityContextModule::NativeTransferStatic(ani_env *aniEnv, ani_object, ani_object input,
|
||||
ani_object type)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "transfer static AbilityContext");
|
||||
if (aniEnv == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null aniEnv");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *unwrapResult = nullptr;
|
||||
bool success = arkts_esvalue_unwrap(aniEnv, input, &unwrapResult);
|
||||
if (!success) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "failed to unwrap");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
if (unwrapResult == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null unwrapResult");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto context = reinterpret_cast<std::weak_ptr<AbilityContext> *>(unwrapResult)->lock();
|
||||
if (context == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null AbilityContext");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto abilityContext = Context::ConvertTo<AbilityContext>(context);
|
||||
if (abilityContext == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "invalid abilityContext");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto &bindingObj = abilityContext->GetBindingObject();
|
||||
if (bindingObj == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null bindingObj");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto staticContext = bindingObj->Get<ani_ref>();
|
||||
if (staticContext != nullptr) {
|
||||
TAG_LOGI(AAFwkTag::CONTEXT, "there exist a staticContext");
|
||||
return reinterpret_cast<ani_object>(*staticContext);
|
||||
}
|
||||
|
||||
// if not exist, create a new one
|
||||
std::string contextType;
|
||||
if (!AppExecFwk::GetStdString(aniEnv, reinterpret_cast<ani_string>(type), contextType)) {
|
||||
TAG_LOGE(AAFwkTag::JSNAPI, "GetStdString failed");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "contextType %{public}s", contextType.c_str());
|
||||
|
||||
auto newContext = ContextTransfer::GetInstance().GetStaticObject(contextType, aniEnv, context);
|
||||
if (newContext == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "create abilityContext failed");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return newContext;
|
||||
}
|
||||
|
||||
std::unique_ptr<NativeReference> EtsAbilityContextModule::CreateNativeReference(napi_env napiEnv,
|
||||
std::shared_ptr<AbilityContext> abilityContext)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
if (napiEnv == nullptr || abilityContext == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null param");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto value = CreateJsAbilityContext(napiEnv, abilityContext);
|
||||
auto systemModule = JsRuntime::LoadSystemModuleByEngine(napiEnv, "application.AbilityContext", &value, 1);
|
||||
if (systemModule == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null systemModule");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value object = systemModule->GetNapiValue();
|
||||
if (!CheckTypeForNapiValue(napiEnv, object, napi_object)) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "check type failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto workContext = new (std::nothrow) std::weak_ptr<AbilityContext>(abilityContext);
|
||||
if (workContext == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null workContext");
|
||||
return nullptr;
|
||||
}
|
||||
auto status = napi_coerce_to_native_binding_object(napiEnv, object, DetachCallbackFunc, AttachJsUIAbilityContext,
|
||||
workContext, nullptr);
|
||||
if (status != napi_ok) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "coerce AbilityContext failed: %{public}d", status);
|
||||
delete workContext;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
status = napi_wrap(napiEnv, object, workContext,
|
||||
[](napi_env, void *data, void *) {
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "finalizer for weak_ptr AbilityContext");
|
||||
delete static_cast<std::weak_ptr<AbilityContext> *>(data);
|
||||
}, nullptr, nullptr);
|
||||
if (status != napi_ok) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "wrap failed: %{public}d", status);
|
||||
delete workContext;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return systemModule;
|
||||
}
|
||||
|
||||
napi_value EtsAbilityContextModule::GetOrCreateDynamicObject(napi_env napiEnv,
|
||||
std::shared_ptr<AbilityContext> abilityContext)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
if (napiEnv == nullptr || abilityContext == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null param");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// if sub-thread, create a new abilityContext and return
|
||||
if (getpid() != syscall(SYS_gettid)) {
|
||||
auto subThreadObj = static_cast<NativeReference *>(
|
||||
abilityContext->GetSubThreadObject(static_cast<void *>(napiEnv)));
|
||||
if (subThreadObj != nullptr) {
|
||||
return subThreadObj->Get();
|
||||
}
|
||||
auto subThreadRef = CreateNativeReference(napiEnv, abilityContext);
|
||||
if (subThreadRef == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto newObject = subThreadRef->Get();
|
||||
abilityContext->BindSubThreadObject(
|
||||
static_cast<void *>(napiEnv), static_cast<void *>(subThreadRef.release()));
|
||||
return newObject;
|
||||
}
|
||||
|
||||
// if main-thread, get bindingObj firstly
|
||||
auto &bindingObj = abilityContext->GetBindingObject();
|
||||
if (bindingObj == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null bindingObj");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// if main-thread bindingObj exist, return it directly
|
||||
auto dynamicContext = bindingObj->Get<NativeReference>();
|
||||
if (dynamicContext != nullptr) {
|
||||
TAG_LOGI(AAFwkTag::UIABILITY, "there exist a dynamicContext");
|
||||
return dynamicContext->Get();
|
||||
}
|
||||
|
||||
// if main-thread bindingObj didn't exist, return null
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ani_object EtsAbilityContextModule::NativeTransferDynamic(ani_env *aniEnv, ani_class aniCls, ani_object input)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "transfer dynamic AbilityContext");
|
||||
if (!IsInstanceOf(aniEnv, input)) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "not AbilityContext");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto context = AbilityRuntime::GetStageModeContext(aniEnv, input);
|
||||
if (context == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<AbilityContext> abilityContext = Context::ConvertTo<AbilityContext>(context);
|
||||
if (abilityContext == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "invalid abilityContext");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ani_object object = CreateDynamicObject(aniEnv, aniCls, abilityContext);
|
||||
if (object == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "invalid object");
|
||||
EtsErrorUtil::ThrowEtsTransferClassError(aniEnv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
ani_object EtsAbilityContextModule::CreateDynamicObject(ani_env *aniEnv, ani_class aniCls,
|
||||
std::shared_ptr<AbilityContext> abilityContext)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
std::string contextType;
|
||||
if (!AppExecFwk::GetStaticFieldString(aniEnv, aniCls, "contextType", contextType)) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "get context type failed");
|
||||
return nullptr;
|
||||
}
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "contextType %{public}s", contextType.c_str());
|
||||
|
||||
// get napiEnv from aniEnv
|
||||
napi_env napiEnv = {};
|
||||
if (!arkts_napi_scope_open(aniEnv, &napiEnv)) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "arkts_napi_scope_open failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// create normal ability context
|
||||
auto contextObj = ContextTransfer::GetInstance().GetDynamicObject(contextType, napiEnv, abilityContext);
|
||||
if (contextObj == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "create AbilityContext failed");
|
||||
arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hybridgref ref = nullptr;
|
||||
bool success = hybridgref_create_from_napi(napiEnv, contextObj, &ref);
|
||||
if (!success) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "hybridgref_create_from_napi failed");
|
||||
arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ani_object result = nullptr;
|
||||
success = hybridgref_get_esvalue(aniEnv, ref, &result);
|
||||
if (!success) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "hybridgref_get_esvalue failed");
|
||||
hybridgref_delete_from_napi(napiEnv, ref);
|
||||
arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hybridgref_delete_from_napi(napiEnv, ref);
|
||||
|
||||
if (!arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr)) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "arkts_napi_scope_close_n failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool EtsAbilityContextModule::IsInstanceOf(ani_env *aniEnv, ani_object aniObj)
|
||||
{
|
||||
ani_class cls {};
|
||||
ani_status status = ANI_ERROR;
|
||||
if (aniEnv == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null aniEnv");
|
||||
return false;
|
||||
}
|
||||
if ((status = aniEnv->FindClass(ETS_ABILITY_CONTEXT_CLASS_NAME, &cls)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "FindClass status: %{public}d", status);
|
||||
return false;
|
||||
}
|
||||
ani_boolean isInstanceOf = false;
|
||||
if ((status = aniEnv->Object_InstanceOf(aniObj, cls, &isInstanceOf)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "Object_InstanceOf status: %{public}d", status);
|
||||
return false;
|
||||
}
|
||||
return isInstanceOf;
|
||||
}
|
||||
|
||||
void EtsAbilityContextModuleInit(ani_env *aniEnv)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "Init AbilityContext kit");
|
||||
if (aniEnv == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null ani env");
|
||||
return;
|
||||
}
|
||||
|
||||
ani_class abilityContextCls = nullptr;
|
||||
auto status = aniEnv->FindClass(ETS_ABILITY_CONTEXT_CLASS_NAME, &abilityContextCls);
|
||||
if (status != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "FindClass AbilityContext failed status: %{public}d", status);
|
||||
return;
|
||||
}
|
||||
|
||||
std::array nativeFuncs = {
|
||||
ani_native_function { "nativeTransferStatic", "Lstd/interop/ESValue;Lstd/core/String;:Lstd/core/Object;",
|
||||
reinterpret_cast<void*>(EtsAbilityContextModule::NativeTransferStatic) },
|
||||
ani_native_function { "nativeTransferDynamic", "Lstd/core/Object;:Lstd/interop/ESValue;",
|
||||
reinterpret_cast<void*>(EtsAbilityContextModule::NativeTransferDynamic) },
|
||||
};
|
||||
status = aniEnv->Class_BindNativeMethods(abilityContextCls, nativeFuncs.data(), nativeFuncs.size());
|
||||
if (status != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "Class_BindNativeMethods failed status: %{public}d", status);
|
||||
return;
|
||||
}
|
||||
|
||||
ContextTransfer::GetInstance().RegisterStaticObjectCreator("UIAbilityContext",
|
||||
[](ani_env *aniEnv, std::shared_ptr<Context> context) -> ani_object {
|
||||
TAG_LOGE(AAFwkTag::APPKIT, "AbilityContext should be created during ability startup");
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
ContextTransfer::GetInstance().RegisterDynamicObjectCreator("UIAbilityContext",
|
||||
[](napi_env napiEnv, std::shared_ptr<Context> context) -> napi_value {
|
||||
auto abilityContext = Context::ConvertTo<AbilityContext>(context);
|
||||
if (abilityContext == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "invalid abilityContext");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto object = EtsAbilityContextModule::GetOrCreateDynamicObject(napiEnv, abilityContext);
|
||||
if (object == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "get or create object failed");
|
||||
return nullptr;
|
||||
}
|
||||
return object;
|
||||
});
|
||||
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "Init AbilityContext kit end");
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "ANI_Constructor");
|
||||
if (vm == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "null vm");
|
||||
return ANI_ERROR;
|
||||
}
|
||||
|
||||
ani_env *aniEnv = nullptr;
|
||||
ani_status status = vm->GetEnv(ANI_VERSION_1, &aniEnv);
|
||||
if (status != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "GetEnv failed status: %{public}d", status);
|
||||
return ANI_NOT_FOUND;
|
||||
}
|
||||
|
||||
EtsAbilityContextModuleInit(aniEnv);
|
||||
*result = ANI_VERSION_1;
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "ANI_Constructor finish");
|
||||
return ANI_OK;
|
||||
}
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
@@ -45,7 +45,6 @@ let unregisterToken = new object();
|
||||
export default class UIAbilityContext extends Context {
|
||||
static {
|
||||
loadLibrary("context_ani");
|
||||
loadLibrary("ability_context_ani_kit.z");
|
||||
}
|
||||
|
||||
private cleaner: Cleaner | null = null;
|
||||
@@ -81,24 +80,6 @@ export default class UIAbilityContext extends Context {
|
||||
destroyRegister.unregister(unregisterToken);
|
||||
}
|
||||
|
||||
private static native nativeTransferStatic(input: ESValue, type: string): Object;
|
||||
private static native nativeTransferDynamic(input: Object): ESValue;
|
||||
private static contextType: string = 'UIAbilityContext';
|
||||
|
||||
static transferStatic(input: Any): Object {
|
||||
let type: string = '';
|
||||
try {
|
||||
type = ESValue.wrap(input).getProperty('__context_impl__').getProperty('contextType').toString();
|
||||
} catch (err) {
|
||||
console.log('transferStatic err: ' + err.toString());
|
||||
}
|
||||
console.log('transferStatic type: ' + type);
|
||||
return UIAbilityContext.nativeTransferStatic(ESValue.wrap(input), type);
|
||||
}
|
||||
static transferDynamic(input: Object): Any {
|
||||
return UIAbilityContext.nativeTransferDynamic(input).unwrap();
|
||||
}
|
||||
|
||||
private native nativeStartAbilitySync(want: Want, callback: AsyncCallbackWrapper<void>): void;
|
||||
|
||||
private native nativeStartAbilitySync(want: Want, options: StartOptions, callback: AsyncCallbackWrapper<void>): void;
|
||||
|
||||
@@ -18,11 +18,14 @@
|
||||
#include <native_engine/native_engine.h>
|
||||
|
||||
#include "ability_manager_client.h"
|
||||
#include "hitrace_meter.h"
|
||||
#include "application_configuration_manager.h"
|
||||
#include "configuration_convertor.h"
|
||||
#include "bindable_sub_thread.h"
|
||||
#include "connection_manager.h"
|
||||
#include "dialog_request_callback_impl.h"
|
||||
#include "dialog_ui_extension_callback.h"
|
||||
#include "hilog_tag_wrapper.h"
|
||||
#include "hitrace_meter.h"
|
||||
#include "json_utils.h"
|
||||
#include "remote_object_wrapper.h"
|
||||
#include "request_constants.h"
|
||||
@@ -34,8 +37,6 @@
|
||||
#include "ui_content.h"
|
||||
#endif // SUPPORT_SCREEN
|
||||
#include "want_params_wrapper.h"
|
||||
#include "configuration_convertor.h"
|
||||
#include "application_configuration_manager.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
@@ -55,6 +56,11 @@ struct RequestResult {
|
||||
RequestDialogResultTask task;
|
||||
};
|
||||
|
||||
AbilityContextImpl::AbilityContextImpl()
|
||||
{
|
||||
subThreadObject_ = std::make_unique<BindableSubThread>();
|
||||
}
|
||||
|
||||
Global::Resource::DeviceType AbilityContextImpl::GetDeviceType() const
|
||||
{
|
||||
return (stageContext_ != nullptr) ? stageContext_->GetDeviceType() : Global::Resource::DeviceType::DEVICE_PHONE;
|
||||
|
||||
@@ -2223,6 +2223,9 @@ napi_value CreateJsAbilityContext(napi_env env, std::shared_ptr<AbilityContext>
|
||||
napi_set_named_property(env, object, "config", CreateJsConfiguration(env, *configuration));
|
||||
}
|
||||
|
||||
std::string type = "UIAbilityContext";
|
||||
napi_set_named_property(env, object, "contextType", CreateJsValue(env, type));
|
||||
|
||||
const char *moduleName = "JsAbilityContext";
|
||||
BindNativeFunction(env, object, "startAbility", moduleName, JsAbilityContext::StartAbility);
|
||||
BindNativeFunction(env, object, "openLink", moduleName, JsAbilityContext::OpenLink);
|
||||
|
||||
@@ -704,7 +704,7 @@ void UIAbility::BindHybridContext(const std::shared_ptr<AppExecFwk::OHOSApplicat
|
||||
TAG_LOGE(AAFwkTag::UIABILITY, "null appInfo");
|
||||
return;
|
||||
}
|
||||
if (appInfo->codeLanguage != AppExecFwk::Constants::CODE_LANGUAGE_HYBRID) {
|
||||
if (appInfo->arkTSMode != AppExecFwk::Constants::ARKTS_MODE_HYBRID) {
|
||||
TAG_LOGD(AAFwkTag::UIABILITY, "not hybrid app, no need to create hybrid context");
|
||||
return;
|
||||
}
|
||||
@@ -714,12 +714,12 @@ void UIAbility::BindHybridContext(const std::shared_ptr<AppExecFwk::OHOSApplicat
|
||||
TAG_LOGE(AAFwkTag::UIABILITY, "null abilityInfo");
|
||||
return;
|
||||
}
|
||||
if (abilityInfo->codeLanguage == AppExecFwk::Constants::CODE_LANGUAGE_1_1) {
|
||||
if (abilityInfo->arkTSMode == AppExecFwk::Constants::ARKTS_MODE_DYNAMIC) {
|
||||
BindEtsContext(application, record);
|
||||
} else if (abilityInfo->codeLanguage == AppExecFwk::Constants::CODE_LANGUAGE_1_2) {
|
||||
} else if (abilityInfo->arkTSMode == AppExecFwk::Constants::ARKTS_MODE_STATIC) {
|
||||
BindJsContext(application, record);
|
||||
} else {
|
||||
TAG_LOGE(AAFwkTag::UIABILITY, "unknown codeLanguage");
|
||||
TAG_LOGE(AAFwkTag::UIABILITY, "unknown arkTSMode");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -453,6 +453,7 @@ ohos_shared_library("app_context") {
|
||||
"${ability_runtime_native_path}/appkit/ability_runtime/context/ability_stage_context.cpp",
|
||||
"${ability_runtime_native_path}/appkit/ability_runtime/context/application_context.cpp",
|
||||
"${ability_runtime_native_path}/appkit/ability_runtime/context/application_state_change_callback.cpp",
|
||||
"${ability_runtime_native_path}/appkit/ability_runtime/context/bindable_sub_thread.cpp",
|
||||
"${ability_runtime_native_path}/appkit/ability_runtime/context/context_impl.cpp",
|
||||
"${ability_runtime_native_path}/appkit/ability_runtime/context/environment_callback.cpp",
|
||||
"${ability_runtime_native_path}/appkit/app/overlay_event_subscriber.cpp",
|
||||
|
||||
@@ -79,6 +79,15 @@ ETSAbilityStage::ETSAbilityStage(
|
||||
: etsRuntime_(etsRuntime), etsAbilityStageObj_(std::move(etsAbilityStageObj))
|
||||
{}
|
||||
|
||||
ETSAbilityStage::~ETSAbilityStage()
|
||||
{
|
||||
TAG_LOGI(AAFwkTag::APPKIT, "destructor");
|
||||
auto context = GetContext();
|
||||
if (context != nullptr) {
|
||||
context->Unbind();
|
||||
}
|
||||
}
|
||||
|
||||
void ETSAbilityStage::Init(const std::shared_ptr<Context> &context,
|
||||
const std::weak_ptr<AppExecFwk::OHOSApplication> application)
|
||||
{
|
||||
|
||||
@@ -36,21 +36,18 @@ ani_object ETSAbilityStageContext::CreateEtsAbilityStageContext(ani_env *env, st
|
||||
|
||||
ani_status status = ANI_OK;
|
||||
ani_class abilityStageCtxCls;
|
||||
status = env->FindClass(ETS_ABILITY_STAGE_CONTEXT_CLASS_NAME, &abilityStageCtxCls);
|
||||
if (status != ANI_OK) {
|
||||
if ((status = env->FindClass(ETS_ABILITY_STAGE_CONTEXT_CLASS_NAME, &abilityStageCtxCls)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::ABILITY, "call FindClass LAbilityStageContext failed, status:%{public}d", status);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ani_method method = nullptr;
|
||||
status = env->Class_FindMethod(abilityStageCtxCls, "<ctor>", ":V", &method);
|
||||
if (status != ANI_OK) {
|
||||
if ((status = env->Class_FindMethod(abilityStageCtxCls, "<ctor>", ":V", &method)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::ABILITY, "call Class_FindMethod ctor failed");
|
||||
return nullptr;
|
||||
}
|
||||
ani_object obj = nullptr;
|
||||
status = env->Object_New(abilityStageCtxCls, method, &obj);
|
||||
if (status != ANI_OK) {
|
||||
if ((status = env->Object_New(abilityStageCtxCls, method, &obj)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::ABILITY, "call Object_New abilityStageCtxCls failed");
|
||||
return nullptr;
|
||||
}
|
||||
@@ -63,13 +60,11 @@ ani_object ETSAbilityStageContext::CreateEtsAbilityStageContext(ani_env *env, st
|
||||
return nullptr;
|
||||
}
|
||||
ani_field contextField;
|
||||
status = env->Class_FindField(abilityStageCtxCls, "nativeContext", &contextField);
|
||||
if (status != ANI_OK) {
|
||||
if ((status = env->Class_FindField(abilityStageCtxCls, "nativeContext", &contextField)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::ABILITY, "call Class_FindField nativeContext failed");
|
||||
}
|
||||
ani_long nativeContextLong = (ani_long)workContext;
|
||||
status = env->Object_SetField_Long(obj, contextField, nativeContextLong);
|
||||
if (status != ANI_OK) {
|
||||
if ((status = env->Object_SetField_Long(obj, contextField, nativeContextLong)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::ABILITY, "call Object_SetField_Long contextField failed");
|
||||
delete workContext;
|
||||
return nullptr;
|
||||
@@ -77,6 +72,14 @@ ani_object ETSAbilityStageContext::CreateEtsAbilityStageContext(ani_env *env, st
|
||||
|
||||
ContextUtil::CreateEtsBaseContext(env, abilityStageCtxCls, obj, context);
|
||||
SetConfiguration(env, abilityStageCtxCls, obj, context);
|
||||
ani_ref* contextGlobalRef = new (std::nothrow) ani_ref;
|
||||
if ((status = env->GlobalReference_Create(obj, contextGlobalRef)) != ANI_OK) {
|
||||
TAG_LOGE(AAFwkTag::ABILITY, "GlobalReference_Create failed status: %{public}d", status);
|
||||
delete contextGlobalRef;
|
||||
delete workContext;
|
||||
return nullptr;
|
||||
}
|
||||
context->Bind(contextGlobalRef);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,10 @@ napi_value CreateJsAbilityStageContext(napi_env env, std::shared_ptr<AbilityRunt
|
||||
if (configuration != nullptr && CheckTypeForNapiValue(env, objValue, napi_object)) {
|
||||
napi_set_named_property(env, objValue, "config", CreateJsConfiguration(env, *configuration));
|
||||
}
|
||||
|
||||
std::string type = "AbilityStageContext";
|
||||
napi_set_named_property(env, objValue, "contextType", CreateJsValue(env, type));
|
||||
|
||||
return objValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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 "bindable_sub_thread.h"
|
||||
|
||||
#include "hilog_tag_wrapper.h"
|
||||
#include "native_engine/native_engine.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
namespace {
|
||||
struct HookData {
|
||||
std::weak_ptr<BindableSubThread> instance;
|
||||
napi_env env = nullptr;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
BindableSubThread::~BindableSubThread()
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "destructor");
|
||||
}
|
||||
|
||||
void BindableSubThread::BindSubThreadObject(void* napiEnv, void* object)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "bind sub thread object");
|
||||
uintptr_t key = reinterpret_cast<uintptr_t>(napiEnv);
|
||||
std::lock_guard guard(objectsMutex_);
|
||||
auto it = objects_.find(key);
|
||||
if (it != objects_.end()) {
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "object has bound");
|
||||
return;
|
||||
}
|
||||
|
||||
napi_env acutalEnv = static_cast<napi_env>(napiEnv);
|
||||
HookData* data = new (std::nothrow) HookData { weak_from_this(), acutalEnv };
|
||||
if (data == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "data err");
|
||||
return;
|
||||
}
|
||||
|
||||
napi_status ret = napi_add_env_cleanup_hook(acutalEnv,
|
||||
StaticRemoveSubThreadObject, data);
|
||||
if (ret != napi_status::napi_ok) {
|
||||
TAG_LOGE(AAFwkTag::CONTEXT, "add hook err");
|
||||
delete data;
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<void, void (*)(void*)> obj(object,
|
||||
[](void* ptr) {
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "delete sub thread ptr");
|
||||
delete static_cast<NativeReference*>(ptr);
|
||||
});
|
||||
objects_.emplace(key, std::move(obj));
|
||||
}
|
||||
|
||||
void* BindableSubThread::GetSubThreadObject(void* napiEnv)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "get sub thread object");
|
||||
uintptr_t key = reinterpret_cast<uintptr_t>(napiEnv);
|
||||
std::lock_guard guard(objectsMutex_);
|
||||
const auto& iter = objects_.find(key);
|
||||
if (iter == objects_.end()) {
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "not found target object");
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<void*>(iter->second.get());
|
||||
}
|
||||
|
||||
void BindableSubThread::RemoveSubThreadObject(void* napiEnv)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "remove sub thread object");
|
||||
uintptr_t key = reinterpret_cast<uintptr_t>(napiEnv);
|
||||
std::lock_guard guard(objectsMutex_);
|
||||
const auto& iter = objects_.find(key);
|
||||
if (iter == objects_.end()) {
|
||||
TAG_LOGW(AAFwkTag::CONTEXT, "not found target object");
|
||||
return;
|
||||
}
|
||||
objects_.erase(key);
|
||||
}
|
||||
|
||||
void BindableSubThread::RemoveAllObject()
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "remove all object");
|
||||
std::lock_guard guard(objectsMutex_);
|
||||
objects_.clear();
|
||||
}
|
||||
|
||||
void BindableSubThread::StaticRemoveSubThreadObject(void* arg)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::CONTEXT, "remove sub thread object");
|
||||
HookData* data = static_cast<HookData*>(arg);
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<BindableSubThread> instance = data->instance.lock();
|
||||
if (instance == nullptr) {
|
||||
TAG_LOGW(AAFwkTag::CONTEXT, "instance nullptr");
|
||||
delete data;
|
||||
return;
|
||||
}
|
||||
|
||||
instance->RemoveSubThreadObject(data->env);
|
||||
delete data;
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "ability_manager_client.h"
|
||||
#include "app_mgr_client.h"
|
||||
#include "application_context.h"
|
||||
#include "bindable_sub_thread.h"
|
||||
#include "bundle_mgr_helper.h"
|
||||
#include "bundle_mgr_proxy.h"
|
||||
#include "common_event_manager.h"
|
||||
@@ -91,6 +92,11 @@ const int AREA2 = 2;
|
||||
const int AREA3 = 3;
|
||||
const int AREA4 = 4;
|
||||
|
||||
ContextImpl::ContextImpl()
|
||||
{
|
||||
subThreadObject_ = std::make_unique<BindableSubThread>();
|
||||
}
|
||||
|
||||
ContextImpl::~ContextImpl()
|
||||
{
|
||||
UnsubscribeToOverlayEvents();
|
||||
|
||||
@@ -1757,6 +1757,10 @@ napi_value JsApplicationContextUtils::CreateJsApplicationContext(napi_env env)
|
||||
return nullptr;
|
||||
}
|
||||
napi_set_named_property(env, object, "index", applicationContextValue);
|
||||
|
||||
std::string type = "ApplicationContext";
|
||||
napi_set_named_property(env, object, "contextType", CreateJsValue(env, type));
|
||||
|
||||
BindNativeApplicationContextOne(env, object);
|
||||
BindNativeApplicationContextTwo(env, object);
|
||||
return object;
|
||||
|
||||
@@ -1000,6 +1000,10 @@ napi_value CreateJsBaseContext(napi_env env, std::shared_ptr<Context> context, b
|
||||
return nullptr;
|
||||
}
|
||||
napi_set_named_property(env, object, "index", contextValue);
|
||||
|
||||
std::string type = "Context";
|
||||
napi_set_named_property(env, object, "contextType", CreateJsValue(env, type));
|
||||
|
||||
const char *moduleName = "JsBaseContext";
|
||||
BindPropertyAndFunction(env, object, moduleName);
|
||||
return object;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
class AbilityContextImpl : public AbilityContext {
|
||||
public:
|
||||
AbilityContextImpl() = default;
|
||||
AbilityContextImpl();
|
||||
virtual ~AbilityContextImpl() = default;
|
||||
|
||||
Global::Resource::DeviceType GetDeviceType() const override;
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
const std::unique_ptr<Runtime>& runtime, const AppExecFwk::HapModuleInfo& hapModuleInfo);
|
||||
|
||||
ETSAbilityStage(ETSRuntime &etsRuntime, std::unique_ptr<AppExecFwk::ETSNativeReference> &&ETSAbilityStageObj);
|
||||
~ETSAbilityStage() override {}
|
||||
~ETSAbilityStage() override;
|
||||
|
||||
void Init(const std::shared_ptr<Context> &context,
|
||||
const std::weak_ptr<AppExecFwk::OHOSApplication> application) override;
|
||||
|
||||
@@ -40,6 +40,16 @@ public:
|
||||
objects_.emplace(typeName, std::move(obj));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Bind(T* object)
|
||||
{
|
||||
static_assert(IsValidType<T>(), "T must be ani_ref or NativeReference");
|
||||
const std::string typeName = GetTypeString<T>();
|
||||
std::lock_guard guard(objectsMutex_);
|
||||
std::unique_ptr<void, void (*)(void*)> obj(object, SimpleRelease<T>);
|
||||
objects_.emplace(typeName, std::move(obj));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T* Get()
|
||||
{
|
||||
@@ -105,6 +115,23 @@ private:
|
||||
std::mutex objectsMutex_;
|
||||
};
|
||||
|
||||
class BindingObjectSubThread {
|
||||
public:
|
||||
BindingObjectSubThread() = default;
|
||||
virtual ~BindingObjectSubThread() = default;
|
||||
|
||||
virtual void BindSubThreadObject(void* napiEnv, void* object);
|
||||
virtual void* GetSubThreadObject(void* napiEnv);
|
||||
virtual void RemoveSubThreadObject(void* napiEnv);
|
||||
virtual void RemoveAllObject();
|
||||
|
||||
private:
|
||||
BindingObjectSubThread(const BindingObjectSubThread&) = delete;
|
||||
BindingObjectSubThread(BindingObjectSubThread&&) = delete;
|
||||
BindingObjectSubThread& operator=(const BindingObjectSubThread&) = delete;
|
||||
BindingObjectSubThread& operator=(BindingObjectSubThread&&) = delete;
|
||||
};
|
||||
|
||||
class Bindable {
|
||||
public:
|
||||
virtual ~Bindable() = default;
|
||||
@@ -117,11 +144,23 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Bind(T* object)
|
||||
{
|
||||
if (object_) {
|
||||
object_->Bind(object);
|
||||
}
|
||||
}
|
||||
|
||||
void Unbind() const
|
||||
{
|
||||
if (object_) {
|
||||
object_->Unbind();
|
||||
}
|
||||
|
||||
if (subThreadObject_) {
|
||||
subThreadObject_->RemoveAllObject();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -130,6 +169,10 @@ public:
|
||||
if (object_) {
|
||||
object_->Unbind<T>();
|
||||
}
|
||||
|
||||
if (subThreadObject_) {
|
||||
subThreadObject_->RemoveAllObject();
|
||||
}
|
||||
}
|
||||
|
||||
const std::unique_ptr<BindingObject>& GetBindingObject() const
|
||||
@@ -137,8 +180,24 @@ public:
|
||||
return object_;
|
||||
}
|
||||
|
||||
void BindSubThreadObject(void* napiEnv, void* object)
|
||||
{
|
||||
if (subThreadObject_) {
|
||||
subThreadObject_->BindSubThreadObject(napiEnv, object);
|
||||
}
|
||||
}
|
||||
|
||||
void* GetSubThreadObject(void* napiEnv)
|
||||
{
|
||||
if (subThreadObject_) {
|
||||
return subThreadObject_->GetSubThreadObject(napiEnv);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
Bindable() = default;
|
||||
std::unique_ptr<BindingObjectSubThread> subThreadObject_ = nullptr;
|
||||
|
||||
private:
|
||||
std::unique_ptr<BindingObject> object_ = std::make_unique<BindingObject>();
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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_BINDABLE_SUB_THREAD_H
|
||||
#define OHOS_ABILITY_RUNTIME_BINDABLE_SUB_THREAD_H
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "bindable.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
class BindableSubThread : public BindingObjectSubThread,
|
||||
public std::enable_shared_from_this<BindableSubThread> {
|
||||
public:
|
||||
BindableSubThread() = default;
|
||||
virtual ~BindableSubThread();
|
||||
|
||||
void BindSubThreadObject(void* napiEnv, void* object) override;
|
||||
|
||||
void* GetSubThreadObject(void* napiEnv) override;
|
||||
|
||||
void RemoveSubThreadObject(void* napiEnv) override;
|
||||
|
||||
void RemoveAllObject() override;
|
||||
|
||||
static void StaticRemoveSubThreadObject(void* arg);
|
||||
|
||||
private:
|
||||
BindableSubThread(const BindableSubThread&) = delete;
|
||||
BindableSubThread(BindableSubThread&&) = delete;
|
||||
BindableSubThread& operator=(const BindableSubThread&) = delete;
|
||||
BindableSubThread& operator=(BindableSubThread&&) = delete;
|
||||
|
||||
std::mutex objectsMutex_;
|
||||
std::map<uintptr_t, std::unique_ptr<void, void (*)(void*)>> objects_;
|
||||
};
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
#endif // OHOS_ABILITY_RUNTIME_BINDABLE_SUB_THREAD_H
|
||||
@@ -40,7 +40,8 @@ class Configuration;
|
||||
namespace AbilityRuntime {
|
||||
class ApplicationContext;
|
||||
|
||||
class Context : public Bindable, public std::enable_shared_from_this<Context> {
|
||||
class Context : public Bindable,
|
||||
public std::enable_shared_from_this<Context> {
|
||||
public:
|
||||
Context() = default;
|
||||
~Context() override = default;
|
||||
|
||||
@@ -36,7 +36,7 @@ using GetDisplayConfigCallback = std::function<bool(uint64_t displayId, float &d
|
||||
#endif
|
||||
class ContextImpl : public Context {
|
||||
public:
|
||||
ContextImpl() = default;
|
||||
ContextImpl();
|
||||
virtual ~ContextImpl();
|
||||
|
||||
/**
|
||||
|
||||
@@ -146,14 +146,18 @@ ohos_unittest("context_impl_test") {
|
||||
"${ability_runtime_innerkits_path}/ability_manager:ability_manager",
|
||||
"${ability_runtime_innerkits_path}/app_manager:app_manager",
|
||||
"${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper",
|
||||
"${ability_runtime_innerkits_path}/error_utils:ability_runtime_error_util",
|
||||
"${ability_runtime_native_path}/ability/native:ability_thread",
|
||||
"${ability_runtime_native_path}/ability/native:abilitykit_native",
|
||||
"${ability_runtime_native_path}/ability/native:abilitykit_utils",
|
||||
"${ability_runtime_native_path}/ability/native:configuration_helper",
|
||||
"${ability_runtime_native_path}/ability/native:uiabilitykit_native",
|
||||
"${ability_runtime_native_path}/appkit:app_context",
|
||||
"${ability_runtime_native_path}/appkit:app_context_utils",
|
||||
"${ability_runtime_native_path}/appkit:appkit_manager_helper",
|
||||
"${ability_runtime_native_path}/appkit:appkit_native",
|
||||
"${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common",
|
||||
"${ability_runtime_path}/js_environment/frameworks/js_environment:js_environment",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
@@ -177,6 +181,7 @@ ohos_unittest("context_impl_test") {
|
||||
"napi:ace_napi",
|
||||
"resource_management:global_resmgr",
|
||||
"resource_management:librawfile",
|
||||
"runtime_core:ani",
|
||||
"samgr:samgr_proxy",
|
||||
"runtime_core:ani",
|
||||
]
|
||||
|
||||
@@ -24,8 +24,13 @@
|
||||
#include "hap_module_info.h"
|
||||
#include "hilog_tag_wrapper.h"
|
||||
#include "iremote_object.h"
|
||||
#include "js_context_utils.h"
|
||||
#include "js_runtime_utils.h"
|
||||
#include "js_runtime_lite.h"
|
||||
#include "mock_ability_token.h"
|
||||
#include "mock_bundle_manager.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "native_engine/native_engine.h"
|
||||
#include "sys_mgr_client.h"
|
||||
#include "system_ability_definition.h"
|
||||
|
||||
@@ -1878,5 +1883,40 @@ HWTEST_F(ContextImplTest, AppExecFwk_ContextImpl_InitPluginHapModuleInfo_003, Fu
|
||||
EXPECT_EQ(contextImpl->GetHapModuleInfo(), nullptr);
|
||||
GTEST_LOG_(INFO) << "AppExecFwk_ContextImpl_InitPluginHapModuleInfo_003 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AppExecFwk_ContextImpl_Bind_001
|
||||
* @tc.name: AppExecFwk_ContextImpl_Bind_001
|
||||
* @tc.desc: test Bind and UnBind function.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ContextImplTest, AppExecFwk_ContextImpl_Bind_001, Function | MediumTest | Level1)
|
||||
{
|
||||
TAG_LOGI(AAFwkTag::TEST, "ContextImpl_Bind_001 start");
|
||||
auto context = std::make_shared<AbilityRuntime::ContextImpl>();
|
||||
ASSERT_NE(context, nullptr);
|
||||
|
||||
std::shared_ptr<JsEnv::JsEnvironment> jsEnv = nullptr;
|
||||
Options options;
|
||||
auto errCode = AbilityRuntime::JsRuntimeLite::GetInstance().CreateJsEnv(options, jsEnv);
|
||||
EXPECT_NE(jsEnv, nullptr);
|
||||
napi_env napiEnv = reinterpret_cast<napi_env>(jsEnv->GetNativeEngine());
|
||||
EXPECT_NE(napiEnv, nullptr);
|
||||
|
||||
auto value = AbilityRuntime::CreateJsBaseContext(napiEnv, context);
|
||||
auto systemModule = AbilityRuntime::JsRuntime::LoadSystemModuleByEngine(napiEnv, "application.Context", &value, 1);
|
||||
EXPECT_NE(systemModule, nullptr);
|
||||
context->Bind(systemModule.get());
|
||||
|
||||
auto &bindingObj = context->GetBindingObject();
|
||||
ASSERT_NE(bindingObj, nullptr);
|
||||
|
||||
auto dynamicContext = bindingObj->Get<NativeReference>();
|
||||
EXPECT_NE(dynamicContext, nullptr);
|
||||
EXPECT_EQ(dynamicContext, systemModule.get());
|
||||
context->Unbind();
|
||||
|
||||
TAG_LOGI(AAFwkTag::TEST, "ContextImpl_Bind_001 end");
|
||||
}
|
||||
} // namespace AppExecFwk
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user