add interopAbilityMonitor

Co-Authored-By: Agent
Signed-off-by: 任国军 <renguojun1@h-partners.com>
This commit is contained in:
任国军
2026-04-14 09:37:30 +08:00
parent 402e9e8d8f
commit 71233dbf37
31 changed files with 1822 additions and 137 deletions
@@ -48,6 +48,7 @@ ohos_shared_library("ability_delegator_registry_ani_kit") {
"./src/ets_ability_delegator_registry.cpp",
"./src/ets_ability_delegator_utils.cpp",
"./src/ets_ability_monitor.cpp",
"./src/ets_interop_ability_monitor.cpp",
]
cflags = []
@@ -77,6 +78,7 @@ ohos_shared_library("ability_delegator_registry_ani_kit") {
"json:nlohmann_json_static",
"napi:ace_napi",
"runtime_core:ani",
"runtime_core:ani_helpers",
]
innerapi_tags = [ "platformsdk" ]
@@ -22,6 +22,7 @@
#include "ets_ability_delegator_registry.h"
#include "ets_ability_monitor.h"
#include "ets_ability_stage_monitor.h"
#include "ets_interop_ability_monitor.h"
#include "iability_monitor.h"
#include "ets_runtime.h"
#include "want.h"
@@ -97,6 +98,12 @@ public:
static ani_ref GetCurrentTopAbility(ani_env *env, [[maybe_unused]]ani_class aniClass, ani_object callback);
static void AddInteropAbilityMonitorSync(ani_env *env, [[maybe_unused]]ani_class aniClass,
ani_object monitorObj);
static void RemoveInteropAbilityMonitorSync(ani_env *env, [[maybe_unused]]ani_class aniClass,
ani_object monitorObj);
private:
static ani_object WrapShellCmdResult(ani_env *env, std::unique_ptr<AppExecFwk::ShellCmdResult> result);
@@ -131,6 +138,15 @@ private:
static void CleanAndFindMonitorRecord(ani_env *env, ani_object monitorObj);
static bool CheckMonitorPara(ani_env *env, ani_object monitorObj);
static bool ParseInteropMonitorPara(ani_env *env, ani_object monitorObj,
std::shared_ptr<EtsInteropAbilityMonitor> &monitorImpl);
static bool ParseInteropMonitorParaInner(ani_env *env, ani_object monitorObj,
std::shared_ptr<EtsInteropAbilityMonitor> &monitorImpl);
static std::shared_ptr<EtsInteropAbilityMonitor> CleanAndFindInteropMonitorRecord(
ani_env *env, ani_object monitorObj);
};
} // namespace AbilityDelegatorEts
} // namespace OHOS
@@ -0,0 +1,64 @@
/*
* 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_INTEROP_ABILITY_MONITOR_H
#define OHOS_ABILITY_RUNTIME_ETS_INTEROP_ABILITY_MONITOR_H
#include <memory>
#include <string>
#include "ani.h"
#include "ets_native_reference.h"
#include "iinterop_ability_monitor.h"
#include <node_api.h>
namespace OHOS {
namespace AbilityDelegatorEts {
class EtsInteropAbilityMonitor : public AppExecFwk::IInteropAbilityMonitor {
public:
explicit EtsInteropAbilityMonitor(const std::string &abilityName);
explicit EtsInteropAbilityMonitor(const std::string &abilityName, const std::string &moduleName);
~EtsInteropAbilityMonitor() = default;
void OnAbilityStart(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj) override;
void OnAbilityForeground(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj) override;
void OnAbilityBackground(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj) override;
void OnAbilityStop(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj) override;
void OnWindowStageCreate(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj) override;
void OnWindowStageRestore(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj) override;
void OnWindowStageDestroy(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj) override;
void SetEtsInteropAbilityMonitor(ani_env *env, ani_object &monitorObj);
void SetNapiEnv(napi_env env);
std::unique_ptr<AppExecFwk::ETSNativeReference> &GetEtsInteropAbilityMonitor()
{
return etsInteropMonitor_;
}
private:
void CallLifecycleCBFunction(const std::string &functionName,
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
ani_object ConvertAbilityToAniRef(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
ani_env *GetAniEnv();
ani_vm *vm_ = nullptr;
napi_env napiEnv_ = nullptr;
std::string abilityName_;
std::string moduleName_;
std::unique_ptr<AppExecFwk::ETSNativeReference> etsInteropMonitor_;
};
} // namespace AbilityDelegatorEts
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_ETS_INTEROP_ABILITY_MONITOR_H
@@ -39,6 +39,8 @@ std::map<std::weak_ptr<ETSNativeReference>, sptr<IRemoteObject>, std::owner_less
std::mutex g_mtxMonitorRecord;
std::mutex g_mtxStageMonitorRecord;
std::mutex g_mutexAbilityRecord;
std::map<std::shared_ptr<ETSNativeReference>, std::shared_ptr<EtsInteropAbilityMonitor>> g_interopMonitorRecord;
std::mutex g_mtxInteropMonitorRecord;
namespace {
constexpr const char* CONTEXT_CLASS_NAME = "application.Context.Context";
@@ -1268,5 +1270,175 @@ void EtsAbilityDelegator::CleanAndFindMonitorRecord(ani_env *env, ani_object mon
++iter;
}
}
void EtsAbilityDelegator::AddInteropAbilityMonitorSync(ani_env *env, [[maybe_unused]]ani_class aniClass,
ani_object monitorObj)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "AddInteropAbilityMonitorSync called");
if (env == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
return;
}
std::shared_ptr<EtsInteropAbilityMonitor> monitorImpl = nullptr;
if (!ParseInteropMonitorPara(env, monitorObj, monitorImpl)) {
TAG_LOGE(AAFwkTag::DELEGATOR, "ParseInteropMonitorPara failed");
AbilityRuntime::EtsErrorUtil::ThrowError(env,
static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
"Parse param monitor failed, monitor must be InteropAbilityMonitor.");
return;
}
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (delegator) {
monitorImpl->SetLanguage(AbilityRuntime::Runtime::Language::ETS);
delegator->AddInteropAbilityMonitor(monitorImpl);
} else {
TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
AbilityRuntime::EtsErrorUtil::ThrowError(env, COMMON_FAILED,
"Calling AddInteropAbilityMonitorSync failed.");
}
return;
}
void EtsAbilityDelegator::RemoveInteropAbilityMonitorSync(ani_env *env, [[maybe_unused]]ani_class aniClass,
ani_object monitorObj)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "RemoveInteropAbilityMonitorSync called");
if (env == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
return;
}
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
auto monitor = CleanAndFindInteropMonitorRecord(env, monitorObj);
if (delegator && monitor) {
delegator->RemoveInteropAbilityMonitor(monitor);
} else if (!delegator) {
TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
AbilityRuntime::EtsErrorUtil::ThrowError(env, COMMON_FAILED,
"Calling RemoveInteropAbilityMonitorSync failed.");
}
return;
}
bool EtsAbilityDelegator::ParseInteropMonitorPara(ani_env *env, ani_object monitorObj,
std::shared_ptr<EtsInteropAbilityMonitor> &monitorImpl)
{
if (env == nullptr || monitorObj == nullptr || !CheckMonitorPara(env, monitorObj)) {
TAG_LOGE(AAFwkTag::DELEGATOR, "env or monitorObj is nullptr");
return false;
}
{
std::unique_lock<std::mutex> lck(g_mtxInteropMonitorRecord);
TAG_LOGI(AAFwkTag::DELEGATOR, "interopMonitorRecord size: %{public}zu", g_interopMonitorRecord.size());
for (auto iter = g_interopMonitorRecord.begin(); iter != g_interopMonitorRecord.end();) {
if (iter->first.get() == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "interopMonitorRecord is nullptr");
iter = g_interopMonitorRecord.erase(iter);
continue;
}
std::shared_ptr<ETSNativeReference> etsMonitor = iter->first;
if (etsMonitor == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "etsMonitor is nullptr");
iter = g_interopMonitorRecord.erase(iter);
continue;
}
ani_boolean result = false;
ani_status status = env->Reference_StrictEquals(reinterpret_cast<ani_ref>(monitorObj),
etsMonitor->aniRef, &result);
if (status != ANI_OK) {
TAG_LOGE(AAFwkTag::DELEGATOR, "Reference_StrictEquals failed status: %{public}d", status);
}
if (result) {
TAG_LOGW(AAFwkTag::DELEGATOR, "interop monitor exist");
monitorImpl = iter->second;
return monitorImpl ? true : false;
}
++iter;
}
}
if (!ParseInteropMonitorParaInner(env, monitorObj, monitorImpl)) {
TAG_LOGE(AAFwkTag::DELEGATOR, "ParseInteropMonitorParaInner failed");
return false;
}
return true;
}
bool EtsAbilityDelegator::ParseInteropMonitorParaInner(ani_env *env, ani_object monitorObj,
std::shared_ptr<EtsInteropAbilityMonitor> &monitorImpl)
{
std::string strAbilityName = "";
if (!GetStringProperty(env, monitorObj, "abilityName", strAbilityName)) {
TAG_LOGE(AAFwkTag::DELEGATOR, "GetStringProperty abilityName failed");
return false;
}
std::string strModuleName = "";
auto interopMonitor = std::make_shared<EtsInteropAbilityMonitor>(strAbilityName);
if (GetStringProperty(env, monitorObj, "moduleName", strModuleName)) {
interopMonitor = std::make_shared<EtsInteropAbilityMonitor>(strAbilityName, strModuleName);
}
interopMonitor->SetEtsInteropAbilityMonitor(env, monitorObj);
auto *napiEnvPtr = reinterpret_cast<napi_env>(AppExecFwk::AbilityDelegatorRegistry::GetNapiEnv());
if (napiEnvPtr != nullptr) {
interopMonitor->SetNapiEnv(napiEnvPtr);
}
monitorImpl = interopMonitor;
ani_ref monitorRef = nullptr;
if (env->GlobalReference_Create(monitorObj, &monitorRef) != ANI_OK) {
TAG_LOGE(AAFwkTag::DELEGATOR, "GlobalReference_Create failed");
return false;
}
auto reference = std::make_shared<ETSNativeReference>();
if (reference != nullptr) {
reference->aniRef = monitorRef;
reference->aniObj = monitorObj;
}
{
std::unique_lock<std::mutex> lck(g_mtxInteropMonitorRecord);
g_interopMonitorRecord.emplace(reference, monitorImpl);
}
return true;
}
std::shared_ptr<EtsInteropAbilityMonitor> EtsAbilityDelegator::CleanAndFindInteropMonitorRecord(
ani_env *env, ani_object monitorObj)
{
if (env == nullptr || monitorObj == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "env or monitorObj is nullptr");
return nullptr;
}
std::unique_lock<std::mutex> lck(g_mtxInteropMonitorRecord);
for (auto iter = g_interopMonitorRecord.begin(); iter != g_interopMonitorRecord.end();) {
if (iter->first.get() == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "interopMonitorRecord is nullptr");
iter = g_interopMonitorRecord.erase(iter);
continue;
}
std::shared_ptr<ETSNativeReference> etsMonitor = iter->first;
if (etsMonitor == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "etsMonitor is nullptr");
iter = g_interopMonitorRecord.erase(iter);
continue;
}
ani_boolean result = false;
ani_status status = env->Reference_StrictEquals(reinterpret_cast<ani_ref>(monitorObj),
etsMonitor->aniRef, &result);
if (status != ANI_OK) {
TAG_LOGE(AAFwkTag::DELEGATOR, "Reference_StrictEquals failed status: %{public}d", status);
}
if (result) {
status = env->GlobalReference_Delete(etsMonitor->aniRef);
if (status != ANI_OK) {
TAG_LOGE(AAFwkTag::DELEGATOR, "GlobalReference_Delete failed status: %{public}d", status);
}
auto monitor = iter->second;
g_interopMonitorRecord.erase(iter);
return monitor;
}
++iter;
}
return nullptr;
}
} // namespace AbilityDelegatorEts
} // namespace OHOS
@@ -33,6 +33,8 @@ constexpr const char* WANT_ASYNCCALLBACK = "C{@ohos.app.ability.Want.Want}C{util
constexpr const char* ARGS_ABILITY_DELEGATOR_CLASS_NAME =
"application.abilityDelegatorArgs.AbilityDelegatorArgsInner";
constexpr const char* SIGNATURE_MONITOR_VOID = "C{application.AbilityMonitor.AbilityMonitor}:";
constexpr const char* INTEROP_MONITOR_VOID =
"C{application.InteropAbilityMonitor.InteropAbilityMonitor}:";
constexpr const char* SIGNATURE_MONITOR_NUMBER_ASYNCCALLBACK =
"C{application.AbilityMonitor.AbilityMonitor}lC{utils.AbilityUtils.AsyncCallbackWrapper}:";
constexpr const char* STAGEMONITOR_ASYNCCALLBACK_VOID =
@@ -55,25 +57,45 @@ constexpr const char* RECORD_SET_NAME =
"X{C{std.core.BaseEnum}C{std.core.Numeric}C{std.core.String}}Y:";
}
bool BindFunctions(ani_env *aniEnv, ani_class abilityDelegator)
auto GetBaseNativeFunctions()
{
if (aniEnv == nullptr) {
return false;
}
std::array functions = {
return std::array {
ani_native_function {"getAppContext", VOID_CONTEXT,
reinterpret_cast<void *>(EtsAbilityDelegator::GetAppContext)},
ani_native_function {"nativeExecuteShellCommand", STRING_NUMBER_ASYNCCALLBACK,
reinterpret_cast<void *>(EtsAbilityDelegator::ExecuteShellCommand)},
ani_native_function {"nativeFinishTest", STRING_NUMBER_ASYNCCALLBACK,
reinterpret_cast<void *>(EtsAbilityDelegator::FinishTest)},
ani_native_function {"printSync", STRING_VOID, reinterpret_cast<void *>(EtsAbilityDelegator::PrintSync)},
ani_native_function {"printSync", STRING_VOID,
reinterpret_cast<void *>(EtsAbilityDelegator::PrintSync)},
ani_native_function {"nativeStartAbility", WANT_ASYNCCALLBACK,
reinterpret_cast<void *>(EtsAbilityDelegator::StartAbility)},
ani_native_function {"printAsync", STRING_ASYNCCALLBACK_VOID,
reinterpret_cast<void *>(EtsAbilityDelegator::Print)},
ani_native_function {"getAbilityState", STRING_UIABILITY_NUMBER,
reinterpret_cast<void *>(EtsAbilityDelegator::GetAbilityState)},
ani_native_function {"nativeGetCurrentTopAbility", STRING_CALLBACK_UIABILITY,
reinterpret_cast<void *>(EtsAbilityDelegator::GetCurrentTopAbility)},
ani_native_function {"doAbilityForegroundAsync", STAGEMONITOR_UIABILITY_ASYNCCALLBACK,
reinterpret_cast<void *>(EtsAbilityDelegator::DoAbilityForeground)},
ani_native_function {"doAbilityForegroundOrBackgroundCheck", STAGEMONITOR_UIABILITY_CHECK,
reinterpret_cast<void *>(EtsAbilityDelegator::DoAbilityForegroundOrBackgroundCheck)},
ani_native_function {"doAbilityBackgroundAsync", STAGEMONITOR_UIABILITY_ASYNCCALLBACK,
reinterpret_cast<void *>(EtsAbilityDelegator::DoAbilityBackground)},
ani_native_function {"addInteropAbilityMonitorSync", INTEROP_MONITOR_VOID,
reinterpret_cast<void *>(EtsAbilityDelegator::AddInteropAbilityMonitorSync)},
ani_native_function {"removeInteropAbilityMonitorSync", INTEROP_MONITOR_VOID,
reinterpret_cast<void *>(EtsAbilityDelegator::RemoveInteropAbilityMonitorSync)}
};
}
auto GetMonitorNativeFunctions()
{
return std::array {
ani_native_function {"nativeAddAbilityMonitor", MONITOR_ASYNCCALLBACK_VOID,
reinterpret_cast<void *>(EtsAbilityDelegator::AddAbilityMonitor)},
ani_native_function {"addAbilityMonitorCheck", SIGNATURE_MONITOR_VOID,
reinterpret_cast<void *>(EtsAbilityDelegator::AddAbilityMonitorCheck)},
ani_native_function {"nativeStartAbility", WANT_ASYNCCALLBACK,
reinterpret_cast<void *>(EtsAbilityDelegator::StartAbility)},
ani_native_function {"addAbilityMonitorSync", SIGNATURE_MONITOR_VOID,
reinterpret_cast<void *>(EtsAbilityDelegator::AddAbilityMonitorSync)},
ani_native_function {"removeAbilityMonitorAsync", MONITOR_ASYNCCALLBACK_VOID,
@@ -97,20 +119,13 @@ bool BindFunctions(ani_env *aniEnv, ani_class abilityDelegator)
ani_native_function {"removeAbilityStageMonitorCheck", STAGEMONITOR_VOID,
reinterpret_cast<void *>(EtsAbilityDelegator::RemoveAbilityStageMonitorCheck)},
ani_native_function {"waitAbilityStageMonitorAsync", SIGNATURE_STAGEMONITOR_NUMBER_ASYNCCALLBACK,
reinterpret_cast<void *>(EtsAbilityDelegator::WaitAbilityStageMonitor)},
ani_native_function {"doAbilityForegroundAsync", STAGEMONITOR_UIABILITY_ASYNCCALLBACK,
reinterpret_cast<void *>(EtsAbilityDelegator::DoAbilityForeground)},
ani_native_function {"doAbilityForegroundOrBackgroundCheck", STAGEMONITOR_UIABILITY_CHECK,
reinterpret_cast<void *>(EtsAbilityDelegator::DoAbilityForegroundOrBackgroundCheck)},
ani_native_function {"doAbilityBackgroundAsync", STAGEMONITOR_UIABILITY_ASYNCCALLBACK,
reinterpret_cast<void *>(EtsAbilityDelegator::DoAbilityBackground)},
ani_native_function {"printAsync", STRING_ASYNCCALLBACK_VOID,
reinterpret_cast<void *>(EtsAbilityDelegator::Print)},
ani_native_function {"getAbilityState", STRING_UIABILITY_NUMBER,
reinterpret_cast<void *>(EtsAbilityDelegator::GetAbilityState)},
ani_native_function {"nativeGetCurrentTopAbility", STRING_CALLBACK_UIABILITY,
reinterpret_cast<void *>(EtsAbilityDelegator::GetCurrentTopAbility)}
reinterpret_cast<void *>(EtsAbilityDelegator::WaitAbilityStageMonitor)}
};
}
template<typename T>
bool BindNativeArray(ani_env *aniEnv, ani_class abilityDelegator, const T &functions)
{
ani_status status = aniEnv->Class_BindNativeMethods(abilityDelegator, functions.data(), functions.size());
if (status != ANI_OK) {
TAG_LOGE(AAFwkTag::DELEGATOR, "Class_BindNativeMethods failed status: %{public}d", status);
@@ -119,6 +134,19 @@ bool BindFunctions(ani_env *aniEnv, ani_class abilityDelegator)
return true;
}
bool BindFunctions(ani_env *aniEnv, ani_class abilityDelegator)
{
if (aniEnv == nullptr) {
return false;
}
auto baseFuncs = GetBaseNativeFunctions();
auto monitorFuncs = GetMonitorNativeFunctions();
if (!BindNativeArray(aniEnv, abilityDelegator, baseFuncs)) {
return false;
}
return BindNativeArray(aniEnv, abilityDelegator, monitorFuncs);
}
ani_object CreateEtsAbilityDelegator(ani_env *aniEnv)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "CreateEtsAbilityDelegator");
@@ -0,0 +1,233 @@
/*
* 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_interop_ability_monitor.h"
#include "ability_delegator_infos.h"
#include "ability_delegator_registry.h"
#include "ets_native_reference.h"
#include "hilog_tag_wrapper.h"
#include "interop_js/hybridgref_ani.h"
#include "interop_js/hybridgref_napi.h"
#include "native_engine/native_reference.h"
namespace OHOS {
namespace AbilityDelegatorEts {
using namespace OHOS::AbilityRuntime;
EtsInteropAbilityMonitor::EtsInteropAbilityMonitor(const std::string &abilityName)
: IInteropAbilityMonitor(abilityName), abilityName_(abilityName)
{}
EtsInteropAbilityMonitor::EtsInteropAbilityMonitor(const std::string &abilityName, const std::string &moduleName)
: IInteropAbilityMonitor(abilityName, moduleName), abilityName_(abilityName), moduleName_(moduleName)
{}
void EtsInteropAbilityMonitor::OnAbilityStart(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called OnAbilityStart");
CallLifecycleCBFunction("onAbilityCreate", abilityObj);
}
void EtsInteropAbilityMonitor::OnAbilityForeground(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called OnAbilityForeground");
CallLifecycleCBFunction("onAbilityForeground", abilityObj);
}
void EtsInteropAbilityMonitor::OnAbilityBackground(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called OnAbilityBackground");
CallLifecycleCBFunction("onAbilityBackground", abilityObj);
}
void EtsInteropAbilityMonitor::OnAbilityStop(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called OnAbilityStop");
CallLifecycleCBFunction("onAbilityDestroy", abilityObj);
}
void EtsInteropAbilityMonitor::OnWindowStageCreate(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called OnWindowStageCreate");
CallLifecycleCBFunction("onWindowStageCreate", abilityObj);
}
void EtsInteropAbilityMonitor::OnWindowStageRestore(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called OnWindowStageRestore");
CallLifecycleCBFunction("onWindowStageRestore", abilityObj);
}
void EtsInteropAbilityMonitor::OnWindowStageDestroy(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called OnWindowStageDestroy");
CallLifecycleCBFunction("onWindowStageDestroy", abilityObj);
}
void EtsInteropAbilityMonitor::SetEtsInteropAbilityMonitor(ani_env *env, ani_object &monitorObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called SetEtsInteropAbilityMonitor");
if (env == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "null env");
return;
}
etsInteropMonitor_ = std::make_unique<AppExecFwk::ETSNativeReference>();
ani_ref objRef = nullptr;
if (env->GlobalReference_Create(monitorObj, &objRef) != ANI_OK) {
TAG_LOGE(AAFwkTag::DELEGATOR, "GlobalReference_Create failed");
return;
}
ani_vm *aniVM = nullptr;
if (env->GetVM(&aniVM) != ANI_OK) {
TAG_LOGE(AAFwkTag::DELEGATOR, "GetVM failed");
return;
}
vm_ = aniVM;
if (etsInteropMonitor_ == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "null etsInteropMonitor_");
return;
}
etsInteropMonitor_->aniObj = monitorObj;
etsInteropMonitor_->aniRef = objRef;
}
void EtsInteropAbilityMonitor::SetNapiEnv(napi_env env)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called SetNapiEnv");
napiEnv_ = env;
}
ani_object EtsInteropAbilityMonitor::ConvertAbilityToAniRef(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
ani_env *aniEnv = GetAniEnv();
if (napiEnv_ == nullptr || aniEnv == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null napiEnv_ or aniEnv, fallback to null");
return nullptr;
}
auto property = abilityObj.lock();
if (property == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null property, fallback to null");
return nullptr;
}
auto jsProperty = std::static_pointer_cast<AppExecFwk::ADelegatorAbilityProperty>(property);
if (jsProperty == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null jsProperty, fallback to null");
return nullptr;
}
auto jsRef = jsProperty->object_.lock();
if (jsRef == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null jsRef, fallback to null");
return nullptr;
}
napi_value napiValue = jsRef->GetNapiValue();
if (napiValue == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null napiValue, fallback to null");
return nullptr;
}
hybridgref href = nullptr;
if (!hybridgref_create_from_napi(napiEnv_, napiValue, &href) || href == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "hybridgref_create_from_napi failed, fallback to null");
return nullptr;
}
ani_object result = nullptr;
bool success = hybridgref_get_esvalue(aniEnv, href, &result);
hybridgref_delete_from_napi(napiEnv_, href);
if (!success || result == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "hybridgref_get_esvalue failed, fallback to null");
return nullptr;
}
return result;
}
void EtsInteropAbilityMonitor::CallLifecycleCBFunction(const std::string &functionName,
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "CallLifecycleCBFunction, name: %{public}s start", functionName.c_str());
if (functionName.empty()) {
TAG_LOGE(AAFwkTag::DELEGATOR, "empty funcName");
return;
}
if (etsInteropMonitor_ == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "null etsInteropMonitor_");
return;
}
ani_env *env = GetAniEnv();
if (env == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "null env");
return;
}
ani_status status = ANI_OK;
ani_object monitorObj = reinterpret_cast<ani_object>(etsInteropMonitor_->aniRef);
ani_ref funRef;
status = env->Object_GetPropertyByName_Ref(monitorObj, functionName.c_str(), &funRef);
if (status != ANI_OK) {
TAG_LOGE(AAFwkTag::DELEGATOR, "Object_GetPropertyByName_Ref failed status: %{public}d", status);
return;
}
ani_boolean isValue = false;
ani_boolean isUndefined = false;
env->Reference_IsNullishValue(funRef, &isValue);
env->Reference_IsUndefined(funRef, &isUndefined);
if (isUndefined || isValue) {
return;
}
ani_fn_object onFn = reinterpret_cast<ani_fn_object>(funRef);
ani_ref abilityRef = reinterpret_cast<ani_ref>(ConvertAbilityToAniRef(abilityObj));
if (abilityRef == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null abilityRef, fallback to undefined");
env->GetUndefined(reinterpret_cast<ani_ref *>(&abilityRef));
}
std::vector<ani_ref> argv = { abilityRef };
ani_ref result;
if ((status = env->FunctionalObject_Call(onFn, 1, argv.data(), &result)) != ANI_OK) {
TAG_LOGE(AAFwkTag::DELEGATOR, "FunctionalObject_Call failed, status: %{public}d", status);
return;
}
}
ani_env *EtsInteropAbilityMonitor::GetAniEnv()
{
if (vm_ == nullptr) {
return nullptr;
}
ani_env *aniEnv = nullptr;
if (vm_->GetEnv(ANI_VERSION_1, &aniEnv) != ANI_OK) {
return nullptr;
}
return aniEnv;
}
} // namespace AbilityDelegatorEts
} // namespace OHOS
@@ -104,4 +104,4 @@ extern "C" ETS_EXPORT InteropObject* OHOS_CreateJsInteropObject(const Runtime &r
return new (std::nothrow) JsInteropObject(env, ref);
}
} // namespace AbilityRuntime
} // namespace OHOS
} // namespace OHOS
@@ -23,6 +23,9 @@
#include "ets_runtime.h"
namespace OHOS {
namespace AppExecFwk {
class AbilityDelegator;
} // namespace AppExecFwk
namespace AbilityRuntime {
struct InsightIntentExecutorInfo;
using AbilityHandler = AppExecFwk::AbilityHandler;
@@ -351,6 +354,10 @@ private:
bool CheckSatisfyTargetAPIVersion(int32_t targetAPIVersion);
bool BackPressDefaultValue();
void WriteLifecycleSwitchLog(const std::string lifecycleName);
void NotifyDelegatorProperty(
std::function<void(const std::shared_ptr<AppExecFwk::AbilityDelegator> &,
const std::shared_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &)> notifyFunc);
bool SetLastRequestWant(ani_env *env, ani_ref wantRef);
int32_t CallSaveState(ani_value args[], WantParams &wantParams, AppExecFwk::StateReason stateReason,
AppExecFwk::AbilityTransactionCallbackInfo<AppExecFwk::OnSaveStateResult> *callbackInfo);
@@ -512,6 +512,38 @@ void EtsUIAbility::WriteLifecycleSwitchLog(const std::string lifecycleName)
}
}
void EtsUIAbility::NotifyDelegatorProperty(
std::function<void(const std::shared_ptr<AppExecFwk::AbilityDelegator> &,
const std::shared_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &)> notifyFunc)
{
auto property = std::make_shared<AppExecFwk::EtsDelegatorAbilityProperty>();
property->language_ = AbilityRuntime::Runtime::Language::ETS;
if (!CreateProperty(abilityContext_, property)) {
return;
}
property->object_ = etsAbilityObj_;
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (delegator) {
notifyFunc(std::static_pointer_cast<AppExecFwk::AbilityDelegator>(delegator), property);
}
auto jsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::JS);
if (jsDelegator && jsDelegator != delegator) {
notifyFunc(std::static_pointer_cast<AppExecFwk::AbilityDelegator>(jsDelegator), property);
}
}
bool EtsUIAbility::SetLastRequestWant(ani_env *env, ani_ref wantRef)
{
ani_status status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantRef);
if (status != ANI_OK) {
TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status);
return false;
}
return true;
}
void EtsUIAbility::OnStart(const Want &want, sptr<AAFwk::SessionInfo> sessionInfo)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
@@ -544,7 +576,7 @@ void EtsUIAbility::OnStartInner(ani_env *env, const Want &want, sptr<AAFwk::Sess
return;
}
if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantObj)) != ANI_OK) {
TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status);
TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant status: %{public}d", status);
return;
}
SetSelfSpecifiedId(env, sessionInfo);
@@ -564,22 +596,14 @@ void EtsUIAbility::OnStartInner(ani_env *env, const Want &want, sptr<AAFwk::Sess
}
WriteLifecycleSwitchLog("onCreate");
CallObjectMethod(false, "onCreate", nullptr, wantObj, launchParamObj);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
auto property = std::make_shared<AppExecFwk::EtsDelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformStart");
property->object_ = etsAbilityObj_;
delegator->PostPerformStart(property);
}
NotifyDelegatorProperty([](const std::shared_ptr<AppExecFwk::AbilityDelegator> &d,
const std::shared_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &p) { d->PostPerformStart(p); });
applicationContext = AbilityRuntime::Context::GetApplicationContext();
if (applicationContext != nullptr) {
TAG_LOGD(AAFwkTag::UIABILITY, "call DispatchOnAbilityCreate");
EtsAbilityLifecycleCallbackArgs ability(etsAbilityObj_);
applicationContext->DispatchOnAbilityCreate(ability);
DISPATCH_ABILITY_INTEROP(OnAbilityCreate, applicationContext, etsRuntime_, ability);
}
TAG_LOGD(AAFwkTag::UIABILITY, "OnStart end");
}
int32_t EtsUIAbility::OnShare(WantParams &wantParam)
@@ -701,13 +725,21 @@ void EtsUIAbility::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callback
void EtsUIAbility::OnStopCallback()
{
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
auto property = std::make_shared<AppExecFwk::EtsDelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformStop");
property->language_ = AbilityRuntime::Runtime::Language::ETS;
if (CreateProperty(abilityContext_, property)) {
property->object_ = etsAbilityObj_;
delegator->PostPerformStop(property);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (delegator) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformStop");
delegator->PostPerformStop(property);
}
auto jsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::JS);
if (jsDelegator && jsDelegator != delegator) {
jsDelegator->PostPerformStop(property);
}
}
bool ret = ConnectionManager::GetInstance().DisconnectCaller(AbilityContext::token_);
if (ret) {
@@ -754,24 +786,15 @@ void EtsUIAbility::OnSceneCreated()
}
WriteLifecycleSwitchLog("onWindowStageCreate");
CallObjectMethod(false, "onWindowStageCreate", nullptr, etsAppWindowStage);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
auto property = std::make_shared<AppExecFwk::EtsDelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceCreated");
property->object_ = etsAbilityObj_;
delegator->PostPerformScenceCreated(property);
}
NotifyDelegatorProperty([](const std::shared_ptr<AppExecFwk::AbilityDelegator> &d,
const std::shared_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &p) { d->PostPerformScenceCreated(p); });
applicationContext = AbilityRuntime::Context::GetApplicationContext();
if (applicationContext != nullptr && etsAbilityObj_ != nullptr && etsWindowStageObj_ != nullptr) {
TAG_LOGD(AAFwkTag::UIABILITY, "call DispatchOnWindowStageCreate");
EtsAbilityLifecycleCallbackArgs ability(etsAbilityObj_);
EtsAbilityLifecycleCallbackArgs stage(etsWindowStageObj_);
applicationContext->DispatchOnWindowStageCreate(ability, stage);
DISPATCH_WINDOW_INTEROP(OnWindowStageCreate, applicationContext, etsRuntime_, ability, stage);
}
TAG_LOGD(AAFwkTag::UIABILITY, "OnSceneCreated end");
}
ani_object EtsUIAbility::GetEtsWindowStage()
@@ -882,13 +905,21 @@ void EtsUIAbility::onSceneDestroyed()
window->UnregisterDisplayMoveListener(abilityDisplayMoveListener_);
}
}
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
auto property = std::make_shared<AppExecFwk::EtsDelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceDestroyed");
property->language_ = AbilityRuntime::Runtime::Language::ETS;
if (CreateProperty(abilityContext_, property)) {
property->object_ = etsAbilityObj_;
delegator->PostPerformScenceDestroyed(property);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (delegator) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceDestroyed");
delegator->PostPerformScenceDestroyed(property);
}
auto jsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::JS);
if (jsDelegator && jsDelegator != delegator) {
jsDelegator->PostPerformScenceDestroyed(property);
}
}
applicationContext = AbilityRuntime::Context::GetApplicationContext();
@@ -926,40 +957,31 @@ void EtsUIAbility::CallOnForegroundFunc(const Want &want)
TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_");
return;
}
ani_status status = ANI_ERROR;
ani_ref wantRef = AppExecFwk::WrapWant(env, want);
if (wantRef == nullptr) {
TAG_LOGE(AAFwkTag::UIABILITY, "null wantObj");
return;
}
if (!SetLastRequestWant(env, wantRef)) {
return;
}
auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
if (applicationContext != nullptr) {
EtsAbilityLifecycleCallbackArgs ability(etsAbilityObj_);
applicationContext->DispatchOnAbilityWillForeground(ability);
}
if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantRef)) != ANI_OK) {
TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status);
return;
}
WriteLifecycleSwitchLog("onForeground");
CallObjectMethod(false, "onForeground", nullptr, wantRef);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
auto property = std::make_shared<AppExecFwk::EtsDelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformForeground");
property->object_ = etsAbilityObj_;
delegator->PostPerformForeground(property);
}
NotifyDelegatorProperty([](const std::shared_ptr<AppExecFwk::AbilityDelegator> &d,
const std::shared_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &p) {
d->PostPerformForeground(p);
});
applicationContext = AbilityRuntime::Context::GetApplicationContext();
if (applicationContext != nullptr) {
TAG_LOGD(AAFwkTag::UIABILITY, "call DispatchOnAbilityForeground");
EtsAbilityLifecycleCallbackArgs ability(etsAbilityObj_);
applicationContext->DispatchOnAbilityForeground(ability);
DISPATCH_ABILITY_INTEROP(OnAbilityForeground, applicationContext, etsRuntime_, ability);
}
TAG_LOGD(AAFwkTag::UIABILITY, "CallOnForegroundFunc end");
}
void EtsUIAbility::OnBackground()
@@ -974,13 +996,21 @@ void EtsUIAbility::OnBackground()
WriteLifecycleSwitchLog("onBackground");
CallObjectMethod(false, "onBackground", nullptr);
UIAbility::OnBackground();
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
auto property = std::make_shared<AppExecFwk::EtsDelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformBackground");
property->language_ = AbilityRuntime::Runtime::Language::ETS;
if (CreateProperty(abilityContext_, property)) {
property->object_ = etsAbilityObj_;
delegator->PostPerformBackground(property);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (delegator) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformBackground");
delegator->PostPerformBackground(property);
}
auto jsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::JS);
if (jsDelegator && jsDelegator != delegator) {
jsDelegator->PostPerformBackground(property);
}
}
applicationContext = AbilityRuntime::Context::GetApplicationContext();
@@ -18,6 +18,7 @@ import { AbilityDelegatorArgs as _AbilityDelegatorArgs } from 'application.abili
import { AbilityMonitor as _AbilityMonitor } from 'application.AbilityMonitor';
import { AbilityStageMonitor as _AbilityStageMonitor } from 'application.AbilityStageMonitor';
import { ShellCmdResult as _ShellCmdResult } from 'application.shellCmdResult';
import { InteropAbilityMonitor as _InteropAbilityMonitor} from 'application.InteropAbilityMonitor';
export default namespace abilityDelegatorRegistry {
loadLibraryWithPermissionCheck("ability_delegator_registry_ani_kit.z", "@ohos.app.ability.abilityDelegatorRegistry")
@@ -38,4 +39,5 @@ export default namespace abilityDelegatorRegistry {
export type AbilityMonitor = _AbilityMonitor;
export type ShellCmdResult = _ShellCmdResult;
export type AbilityStageMonitor = _AbilityStageMonitor;
export type InteropAbilityMonitor = _InteropAbilityMonitor;
}
+18
View File
@@ -796,6 +796,23 @@ ohos_prebuilt_etc("ability_delegator_ability_monitor_abc_etc") {
deps = [ ":ability_delegator_ability_monitor_abc" ]
}
generate_static_abc("ability_delegator_interop_ability_monitor_abc") {
base_url = "."
files = [ "./application/InteropAbilityMonitor.ets" ]
is_boot_abc = "True"
device_dst_file =
"/system/framework/ability_delegator_interop_ability_monitor_abc.abc"
}
ohos_prebuilt_etc("ability_delegator_interop_ability_monitor_abc_etc") {
source = "$target_out_dir/ability_delegator_interop_ability_monitor_abc.abc"
module_install_dir = "framework"
subsystem_name = "ability"
part_name = "ability_runtime"
deps = [ ":ability_delegator_interop_ability_monitor_abc" ]
}
generate_static_abc("ability_runtime_ability_stage_monitor_abc") {
base_url = "./"
files = [ "./application/AbilityStageMonitor.ets" ]
@@ -2098,6 +2115,7 @@ group("ets_packages") {
":ability_application_abc_etc",
":ability_delegator_abc_etc",
":ability_delegator_ability_monitor_abc_etc",
":ability_delegator_interop_ability_monitor_abc_etc",
":ability_delegator_application_testRunner_abc_etc",
":ability_delegator_args_abc_etc",
":ability_delegator_registry_abc_etc",
@@ -14,6 +14,7 @@
*/
import { AbilityMonitor } from 'application.AbilityMonitor';
import { InteropAbilityMonitor } from 'application.InteropAbilityMonitor';
import Want from '@ohos.app.ability.Want';
import Context from 'application.Context';
import { BusinessError, AsyncCallback } from '@ohos.base';
@@ -97,6 +98,10 @@ export interface AbilityDelegator {
getCurrentTopAbility(callback: AsyncCallback<UIAbility>);
getCurrentTopAbility(): Promise<UIAbility>;
addInteropAbilityMonitorSync(monitor: InteropAbilityMonitor): void;
removeInteropAbilityMonitorSync(monitor: InteropAbilityMonitor): void;
}
class AbilityDelegatorInner implements AbilityDelegator {
@@ -154,6 +159,10 @@ class AbilityDelegatorInner implements AbilityDelegator {
public native getAbilityState(ability: UIAbility): int;
public native addInteropAbilityMonitorSync(monitor: InteropAbilityMonitor): void;
public native removeInteropAbilityMonitorSync(monitor: InteropAbilityMonitor): void;
public native nativeStartAbility(want: Want, callback: AsyncCallbackWrapper<void>): void;
finishTest(msg: string, code: long, callback: AsyncCallback<void>): void {
@@ -509,4 +518,5 @@ class AbilityDelegatorInner implements AbilityDelegator {
});
return p;
}
}
@@ -0,0 +1,48 @@
/*
* 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 UIAbility from '@ohos.app.ability.UIAbility';
export default interface InteropAbilityMonitor {
moduleName: string;
abilityName: string;
onAbilityCreate: (ability: UIAbility) => void;
onAbilityForeground: (ability: UIAbility) => void;
onAbilityBackground: (ability: UIAbility) => void;
onAbilityDestroy: (ability: UIAbility) => void;
onWindowStageCreate: (ability: UIAbility) => void;
onWindowStageRestore: (ability: UIAbility) => void;
onWindowStageDestroy: (ability: UIAbility) => void;
}
class InteropAbilityMonitorInner implements InteropAbilityMonitor {
moduleName: string = "";
abilityName: string = "";
onAbilityCreate: (ability: UIAbility) => void = (ability: UIAbility) => {
};
onAbilityForeground: (ability: UIAbility) => void = (ability: UIAbility) => {
};
onAbilityBackground: (ability: UIAbility) => void = (ability: UIAbility) => {
};
onAbilityDestroy: (ability: UIAbility) => void = (ability: UIAbility) => {
};
onWindowStageCreate: (ability: UIAbility) => void = (ability: UIAbility) => {
};
onWindowStageRestore: (ability: UIAbility) => void = (ability: UIAbility) => {
};
onWindowStageDestroy: (ability: UIAbility) => void = (ability: UIAbility) => {
};
}
@@ -27,14 +27,17 @@ template("delegator") {
"${ability_runtime_path}/interfaces/kits/native/appkit/ability_delegator/",
"${ability_runtime_path}/interfaces/kits/native/ability/native",
"${ability_runtime_path}/tools/aa/include",
"${ability_runtime_path}/frameworks/ets/ani/ani_common/include",
]
sources = [
"ability_monitor.cpp",
"interop_ability_monitor.cpp",
"js_ability_delegator.cpp",
"js_ability_delegator_registry.cpp",
"js_ability_delegator_utils.cpp",
"js_ability_monitor.cpp",
"js_interop_ability_monitor.cpp",
"native_module.cpp",
]
@@ -50,6 +53,7 @@ template("delegator") {
"${ability_runtime_native_path}/ability/native:abilitykit_native",
"${ability_runtime_native_path}/appkit:app_context_utils",
"${ability_runtime_native_path}/appkit:appkit_delegator",
"${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common",
]
external_deps = [
@@ -64,6 +68,8 @@ template("delegator") {
"ipc:ipc_napi",
"ipc:ipc_single",
"napi:ace_napi",
"runtime_core:ani",
"runtime_core:ani_helpers",
]
cflags_cc = []
@@ -0,0 +1,125 @@
/*
* 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 "interop_ability_monitor.h"
#include "js_ability_delegator_utils.h"
#include "hilog_tag_wrapper.h"
namespace OHOS {
namespace AbilityDelegatorJs {
using namespace OHOS::AbilityRuntime;
InteropAbilityMonitor::InteropAbilityMonitor(const std::string &name,
const std::shared_ptr<JsInteropAbilityMonitor> &jsInteropAbilityMonitor)
: IInteropAbilityMonitor(name), jsInteropMonitor_(jsInteropAbilityMonitor)
{}
InteropAbilityMonitor::InteropAbilityMonitor(const std::string &name, const std::string &moduleName,
const std::shared_ptr<JsInteropAbilityMonitor> &jsInteropAbilityMonitor)
: IInteropAbilityMonitor(name, moduleName), jsInteropMonitor_(jsInteropAbilityMonitor)
{}
void InteropAbilityMonitor::OnAbilityStart(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called");
if (jsInteropMonitor_ == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "jsInteropMonitor_ is nullptr");
return;
}
jsInteropMonitor_->OnAbilityCreate(abilityObj);
}
void InteropAbilityMonitor::OnAbilityForeground(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called");
if (jsInteropMonitor_ == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "jsInteropMonitor_ is nullptr");
return;
}
jsInteropMonitor_->OnAbilityForeground(abilityObj);
}
void InteropAbilityMonitor::OnAbilityBackground(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called");
if (jsInteropMonitor_ == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "jsInteropMonitor_ is nullptr");
return;
}
jsInteropMonitor_->OnAbilityBackground(abilityObj);
}
void InteropAbilityMonitor::OnAbilityStop(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called");
if (jsInteropMonitor_ == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "jsInteropMonitor_ is nullptr");
return;
}
jsInteropMonitor_->OnAbilityDestroy(abilityObj);
}
void InteropAbilityMonitor::OnWindowStageCreate(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called");
if (jsInteropMonitor_ == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "jsInteropMonitor_ is nullptr");
return;
}
jsInteropMonitor_->OnWindowStageCreate(abilityObj);
}
void InteropAbilityMonitor::OnWindowStageRestore(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called");
if (jsInteropMonitor_ == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "jsInteropMonitor_ is nullptr");
return;
}
jsInteropMonitor_->OnWindowStageRestore(abilityObj);
}
void InteropAbilityMonitor::OnWindowStageDestroy(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "called");
if (jsInteropMonitor_ == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "jsInteropMonitor_ is nullptr");
return;
}
jsInteropMonitor_->OnWindowStageDestroy(abilityObj);
}
} // namespace AbilityDelegatorJs
} // namespace OHOS
@@ -0,0 +1,50 @@
/*
* 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_INTEROP_ABILITY_MONITOR_H
#define OHOS_ABILITY_RUNTIME_INTEROP_ABILITY_MONITOR_H
#include <memory>
#include "iinterop_ability_monitor.h"
#include "js_interop_ability_monitor.h"
#include "native_engine/native_reference.h"
namespace OHOS {
namespace AbilityDelegatorJs {
using namespace OHOS::AppExecFwk;
class InteropAbilityMonitor : public IInteropAbilityMonitor {
public:
InteropAbilityMonitor(const std::string &name,
const std::shared_ptr<JsInteropAbilityMonitor> &jsInteropAbilityMonitor);
InteropAbilityMonitor(const std::string &name, const std::string &moduleName,
const std::shared_ptr<JsInteropAbilityMonitor> &jsInteropAbilityMonitor);
~InteropAbilityMonitor() = default;
void OnAbilityStart(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj) override;
void OnAbilityForeground(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj) override;
void OnAbilityBackground(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj) override;
void OnAbilityStop(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj) override;
void OnWindowStageCreate(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj) override;
void OnWindowStageRestore(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj) override;
void OnWindowStageDestroy(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj) override;
private:
std::shared_ptr<JsInteropAbilityMonitor> jsInteropMonitor_;
};
} // namespace AbilityDelegatorJs
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_INTEROP_ABILITY_MONITOR_H
@@ -53,6 +53,7 @@ std::map<std::shared_ptr<NativeReference>, std::shared_ptr<AbilityStageMonitor>>
std::map<std::weak_ptr<NativeReference>, sptr<IRemoteObject>, std::owner_less<>> g_abilityRecord;
std::mutex g_mutexAbilityRecord;
std::mutex g_mtxStageMonitorRecord;
std::map<std::shared_ptr<NativeReference>, std::shared_ptr<InteropAbilityMonitor>> g_interopMonitorRecord;
enum ERROR_CODE {
INCORRECT_PARAMETERS = 401,
@@ -262,6 +263,16 @@ napi_value JSAbilityDelegator::SetMockList(napi_env env, napi_callback_info info
GET_NAPI_INFO_AND_CALL(env, info, JSAbilityDelegator, OnSetMockList);
}
napi_value JSAbilityDelegator::AddInteropAbilityMonitorSync(napi_env env, napi_callback_info info)
{
GET_NAPI_INFO_AND_CALL(env, info, JSAbilityDelegator, OnAddInteropAbilityMonitorSync);
}
napi_value JSAbilityDelegator::RemoveInteropAbilityMonitorSync(napi_env env, napi_callback_info info)
{
GET_NAPI_INFO_AND_CALL(env, info, JSAbilityDelegator, OnRemoveInteropAbilityMonitorSync);
}
napi_value JSAbilityDelegator::OnAddAbilityMonitor(napi_env env, NapiCallbackInfo& info)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "argc: %{public}d", static_cast<int32_t>(info.argc));
@@ -1558,5 +1569,111 @@ void JSAbilityDelegator::RemoveStageMonitorRecord(napi_env env, napi_value value
}
}
}
napi_value JSAbilityDelegator::OnAddInteropAbilityMonitorSync(napi_env env, NapiCallbackInfo& info)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "argc: %{public}d", static_cast<int32_t>(info.argc));
HandleScope handleScope(env);
if (info.argc < ARGC_ONE) {
TAG_LOGE(AAFwkTag::DELEGATOR, "invalid argc");
return ThrowJsError(env, INCORRECT_PARAMETERS,
"Parse param monitor failed, monitor must be InteropAbilityMonitor.");
}
std::shared_ptr<InteropAbilityMonitor> monitor = nullptr;
if (!ParseInteropMonitorPara(env, info.argv[INDEX_ZERO], monitor)) {
TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
return ThrowJsError(env, INCORRECT_PARAMETERS,
"Parse param monitor failed, monitor must be InteropAbilityMonitor.");
}
auto delegator = AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::JS);
if (delegator) {
monitor->SetLanguage(AbilityRuntime::Runtime::Language::JS);
delegator->AddInteropAbilityMonitor(monitor);
} else {
ThrowError(env, COMMON_FAILED, "Calling AddInteropAbilityMonitorSync failed.");
}
return CreateJsUndefined(env);
}
napi_value JSAbilityDelegator::OnRemoveInteropAbilityMonitorSync(napi_env env, NapiCallbackInfo& info)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "argc: %{public}d", static_cast<int32_t>(info.argc));
HandleScope handleScope(env);
if (info.argc < ARGC_ONE) {
TAG_LOGE(AAFwkTag::DELEGATOR, "invalid argc");
return ThrowJsError(env, INCORRECT_PARAMETERS,
"Parse monitor failed, removeInteropAbilityMonitorSync must be InteropAbilityMonitor.");
}
auto delegator = AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::JS);
if (!delegator) {
ThrowError(env, COMMON_FAILED, "Calling RemoveInteropAbilityMonitorSync failed.");
return CreateJsUndefined(env);
}
for (auto iter = g_interopMonitorRecord.begin(); iter != g_interopMonitorRecord.end(); ++iter) {
std::shared_ptr<NativeReference> jsMonitor = iter->first;
bool isEquals = false;
napi_strict_equals(env, info.argv[INDEX_ZERO], jsMonitor->GetNapiValue(), &isEquals);
if (isEquals) {
delegator->RemoveInteropAbilityMonitor(iter->second);
g_interopMonitorRecord.erase(iter);
break;
}
}
return CreateJsUndefined(env);
}
napi_value JSAbilityDelegator::ParseInteropMonitorPara(napi_env env, napi_value value,
std::shared_ptr<InteropAbilityMonitor> &monitor)
{
TAG_LOGI(AAFwkTag::DELEGATOR, "interopMonitorRecord size: %{public}zu", g_interopMonitorRecord.size());
HandleScope handleScope(env);
for (auto iter = g_interopMonitorRecord.begin(); iter != g_interopMonitorRecord.end(); ++iter) {
std::shared_ptr<NativeReference> jsMonitor = iter->first;
bool isEquals = false;
napi_strict_equals(env, value, jsMonitor->GetNapiValue(), &isEquals);
if (isEquals) {
TAG_LOGW(AAFwkTag::DELEGATOR, "interop monitor exist");
monitor = iter->second;
return monitor ? CreateJsNull(env) : nullptr;
}
}
napi_value abilityNameValue = nullptr;
napi_get_named_property(env, value, "abilityName", &abilityNameValue);
if (abilityNameValue == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "null abilityNameValue");
return nullptr;
}
std::string abilityName;
if (!ConvertFromJsValue(env, abilityNameValue, abilityName)) {
return nullptr;
}
std::string moduleName = "";
napi_value moduleNameValue = nullptr;
napi_get_named_property(env, value, "moduleName", &moduleNameValue);
if (moduleNameValue != nullptr && !ConvertFromJsValue(env, moduleNameValue, moduleName)) {
TAG_LOGW(AAFwkTag::DELEGATOR, "get property moduleName failed");
moduleName = "";
}
auto jsInteropMonitor = std::make_shared<JsInteropAbilityMonitor>(abilityName, moduleName);
jsInteropMonitor->SetJsInteropAbilityMonitor(env, value);
auto *aniEnvVoid = AppExecFwk::AbilityDelegatorRegistry::GetAniEnv();
if (aniEnvVoid != nullptr) {
jsInteropMonitor->SetAniEnv(aniEnvVoid);
}
monitor = std::make_shared<InteropAbilityMonitor>(abilityName, moduleName, jsInteropMonitor);
std::shared_ptr<NativeReference> reference = nullptr;
napi_ref ref = nullptr;
napi_create_reference(env, value, 1, &ref);
reference.reset(reinterpret_cast<NativeReference*>(ref));
g_interopMonitorRecord.emplace(reference, monitor);
return CreateJsNull(env);
}
} // namespace AbilityDelegatorJs
} // namespace OHOS
@@ -22,6 +22,8 @@
#include "ability_stage_monitor.h"
#include "js_ability_delegator_registry.h"
#include "js_ability_monitor.h"
#include "interop_ability_monitor.h"
#include "js_interop_ability_monitor.h"
#include "js_runtime_utils.h"
#include "want.h"
@@ -243,6 +245,24 @@ public:
*/
static napi_value SetMockList(napi_env env, napi_callback_info info);
/**
* Sync adds interop ability monitor.
*
* @param env Indicates the native engine.
* @param info Indicates the parameters from js.
* @return exec result.
*/
static napi_value AddInteropAbilityMonitorSync(napi_env env, napi_callback_info info);
/**
* Sync removes interop ability monitor.
*
* @param env Indicates the native engine.
* @param info Indicates the parameters from js.
* @return exec result.
*/
static napi_value RemoveInteropAbilityMonitorSync(napi_env env, napi_callback_info info);
private:
napi_value OnAddAbilityMonitor(napi_env env, NapiCallbackInfo& info);
napi_value OnAddAbilityMonitorSync(napi_env env, NapiCallbackInfo& info);
@@ -265,6 +285,8 @@ private:
napi_value OnDoAbilityBackground(napi_env env, NapiCallbackInfo& info);
napi_value OnFinishTest(napi_env env, NapiCallbackInfo& info);
napi_value OnSetMockList(napi_env env, NapiCallbackInfo& info);
napi_value OnAddInteropAbilityMonitorSync(napi_env env, NapiCallbackInfo& info);
napi_value OnRemoveInteropAbilityMonitorSync(napi_env env, NapiCallbackInfo& info);
private:
napi_value CreateAbilityObject(napi_env env, const sptr<IRemoteObject> &remoteObject);
@@ -298,6 +320,8 @@ private:
void AddStageMonitorRecord(
napi_env env, napi_value value, const std::shared_ptr<AbilityStageMonitor> &monitor);
void RemoveStageMonitorRecord(napi_env env, napi_value value);
napi_value ParseInteropMonitorPara(napi_env env, napi_value value,
std::shared_ptr<InteropAbilityMonitor> &monitor);
};
} // namespace AbilityDelegatorJs
} // namespace OHOS
@@ -66,6 +66,10 @@ napi_value CreateJsAbilityDelegator(napi_env env)
BindNativeFunction(env, objValue, "removeAbilityStageMonitorSync",
moduleName, JSAbilityDelegator::RemoveAbilityStageMonitorSync);
BindNativeFunction(env, objValue, "setMockList", moduleName, JSAbilityDelegator::SetMockList);
BindNativeFunction(env, objValue, "addInteropAbilityMonitorSync", moduleName,
JSAbilityDelegator::AddInteropAbilityMonitorSync);
BindNativeFunction(env, objValue, "removeInteropAbilityMonitorSync", moduleName,
JSAbilityDelegator::RemoveInteropAbilityMonitorSync);
return handleEscape.Escape(objValue);
}
@@ -0,0 +1,174 @@
/*
* 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 "js_interop_ability_monitor.h"
#include "ability_delegator_infos.h"
#include "hilog_tag_wrapper.h"
#include "js_ability_delegator_utils.h"
#include "js_interop_object.h"
#include "napi/native_common.h"
namespace OHOS {
namespace AbilityDelegatorJs {
using namespace OHOS::AbilityRuntime;
JsInteropAbilityMonitor::JsInteropAbilityMonitor(const std::string &abilityName) : abilityName_(abilityName)
{}
JsInteropAbilityMonitor::JsInteropAbilityMonitor(const std::string &abilityName, const std::string &moduleName)
: abilityName_(abilityName), moduleName_(moduleName)
{}
void JsInteropAbilityMonitor::OnAbilityCreate(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "called");
CallLifecycleCBFunction("onAbilityCreate", abilityObj);
}
void JsInteropAbilityMonitor::OnAbilityForeground(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "called");
CallLifecycleCBFunction("onAbilityForeground", abilityObj);
}
void JsInteropAbilityMonitor::OnAbilityBackground(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "called");
CallLifecycleCBFunction("onAbilityBackground", abilityObj);
}
void JsInteropAbilityMonitor::OnAbilityDestroy(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "called");
CallLifecycleCBFunction("onAbilityDestroy", abilityObj);
}
void JsInteropAbilityMonitor::OnWindowStageCreate(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "called");
CallLifecycleCBFunction("onWindowStageCreate", abilityObj);
}
void JsInteropAbilityMonitor::OnWindowStageRestore(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "called");
CallLifecycleCBFunction("onWindowStageRestore", abilityObj);
}
void JsInteropAbilityMonitor::OnWindowStageDestroy(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "called");
CallLifecycleCBFunction("onWindowStageDestroy", abilityObj);
}
void JsInteropAbilityMonitor::SetJsInteropAbilityMonitor(napi_env env, napi_value monitor)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "called");
env_ = env;
napi_ref ref = nullptr;
napi_create_reference(env, monitor, 1, &ref);
jsInteropMonitor_ = std::unique_ptr<NativeReference>(reinterpret_cast<NativeReference *>(ref));
}
void JsInteropAbilityMonitor::SetAniEnv(void *aniEnv)
{
TAG_LOGD(AAFwkTag::DELEGATOR, "called");
aniEnvVoid_ = aniEnv;
}
napi_value JsInteropAbilityMonitor::ConvertAbilityToNapiValue(
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
if (aniEnvVoid_ == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null aniEnvVoid_, fallback to null");
return CreateJsNull(env_);
}
auto property = abilityObj.lock();
if (property == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null property, fallback to null");
return CreateJsNull(env_);
}
auto etsProperty = std::static_pointer_cast<AppExecFwk::EtsDelegatorAbilityProperty>(property);
if (etsProperty == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null etsProperty, fallback to null");
return CreateJsNull(env_);
}
auto etsRef = etsProperty->object_.lock();
if (etsRef == nullptr || etsRef->aniRef == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null etsRef, fallback to null");
return CreateJsNull(env_);
}
auto *aniEnv = reinterpret_cast<ani_env *>(aniEnvVoid_);
auto interopObj = std::make_shared<JsInteropObject>(aniEnv, etsRef);
if (interopObj == nullptr || !interopObj->IsFromAni()) {
TAG_LOGW(AAFwkTag::DELEGATOR, "create JsInteropObject failed, fallback to null");
return CreateJsNull(env_);
}
napi_value result = interopObj->GetNapiValue(env_);
if (result == nullptr) {
TAG_LOGW(AAFwkTag::DELEGATOR, "GetNapiValue failed, fallback to null");
return CreateJsNull(env_);
}
return result;
}
napi_value JsInteropAbilityMonitor::CallLifecycleCBFunction(const std::string &functionName,
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj)
{
if (functionName.empty()) {
TAG_LOGE(AAFwkTag::DELEGATOR, "empty funcName");
return nullptr;
}
if (!jsInteropMonitor_) {
TAG_LOGE(AAFwkTag::DELEGATOR, "null jsInteropMonitor");
return nullptr;
}
napi_value obj = jsInteropMonitor_->GetNapiValue();
if (obj == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "null obj");
return nullptr;
}
napi_value method = nullptr;
napi_get_named_property(env_, obj, functionName.data(), &method);
if (method == nullptr) {
TAG_LOGE(AAFwkTag::DELEGATOR, "null method: %{public}s", functionName.data());
return nullptr;
}
napi_value abilityValue = ConvertAbilityToNapiValue(abilityObj);
napi_value argv[] = { abilityValue };
napi_value callResult = nullptr;
napi_call_function(env_, obj, method, ArraySize(argv), argv, &callResult);
return callResult;
}
} // namespace AbilityDelegatorJs
} // namespace OHOS
@@ -0,0 +1,63 @@
/*
* 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_JS_INTEROP_ABILITY_MONITOR_H
#define OHOS_ABILITY_RUNTIME_JS_INTEROP_ABILITY_MONITOR_H
#include <memory>
#include <string>
#include "ability_delegator_infos.h"
#include "js_interop_object.h"
#include "native_engine/native_reference.h"
namespace OHOS {
namespace AbilityDelegatorJs {
class JsInteropAbilityMonitor {
public:
explicit JsInteropAbilityMonitor(const std::string &abilityName);
explicit JsInteropAbilityMonitor(const std::string &abilityName, const std::string &moduleName);
~JsInteropAbilityMonitor() = default;
void OnAbilityCreate(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
void OnAbilityForeground(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
void OnAbilityBackground(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
void OnAbilityDestroy(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
void OnWindowStageCreate(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
void OnWindowStageRestore(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
void OnWindowStageDestroy(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
void SetJsInteropAbilityMonitor(napi_env env, napi_value monitor);
void SetAniEnv(void *aniEnv);
std::unique_ptr<NativeReference> &GetJsInteropAbilityMonitor()
{
return jsInteropMonitor_;
}
private:
napi_value CallLifecycleCBFunction(const std::string &functionName,
const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
napi_value ConvertAbilityToNapiValue(const std::weak_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &abilityObj);
private:
std::string abilityName_ = "";
std::string moduleName_ = "";
napi_env env_ = nullptr;
void *aniEnvVoid_ = nullptr;
std::unique_ptr<NativeReference> jsInteropMonitor_ = nullptr;
};
} // namespace AbilityDelegatorJs
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_JS_INTEROP_ABILITY_MONITOR_H
@@ -554,13 +554,21 @@ void JsUIAbility::OnStart(const Want &want, sptr<AAFwk::SessionInfo> sessionInfo
void JsUIAbility::HandleAbilityDelegatorStart()
{
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
if (!CreateProperty(abilityContext_, property)) {
return;
}
property->object_ = jsAbilityObj_;
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
if (delegator) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformStart");
property->object_ = jsAbilityObj_;
delegator->PostPerformStart(property);
}
auto etsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (etsDelegator && etsDelegator != delegator) {
etsDelegator->PostPerformStart(property);
}
}
void JsUIAbility::WriteLifecycleSwitchLog(const std::string lifecycleName)
@@ -684,12 +692,19 @@ void JsUIAbility::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackI
void JsUIAbility::OnStopCallback()
{
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformStop");
if (CreateProperty(abilityContext_, property)) {
property->object_ = jsAbilityObj_;
delegator->PostPerformStop(property);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
if (delegator) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformStop");
delegator->PostPerformStop(property);
}
auto etsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (etsDelegator && etsDelegator != delegator) {
etsDelegator->PostPerformStop(property);
}
}
bool ret = ConnectionManager::GetInstance().DisconnectCaller(AbilityContext::token_);
@@ -737,12 +752,19 @@ void JsUIAbility::OnSceneCreated()
AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
}
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformSceneCreated");
if (CreateProperty(abilityContext_, property)) {
property->object_ = jsAbilityObj_;
delegator->PostPerformScenceCreated(property);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
if (delegator) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformSceneCreated");
delegator->PostPerformScenceCreated(property);
}
auto etsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (etsDelegator && etsDelegator != delegator) {
etsDelegator->PostPerformScenceCreated(property);
}
}
applicationContext = AbilityRuntime::Context::GetApplicationContext();
@@ -781,12 +803,19 @@ void JsUIAbility::OnSceneRestored()
applicationContext->DispatchOnWindowStageRestore(ability, stage);
}
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceRestored");
if (CreateProperty(abilityContext_, property)) {
property->object_ = jsAbilityObj_;
delegator->PostPerformScenceRestored(property);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
if (delegator) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceRestored");
delegator->PostPerformScenceRestored(property);
}
auto etsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (etsDelegator && etsDelegator != delegator) {
etsDelegator->PostPerformScenceRestored(property);
}
}
}
@@ -830,12 +859,19 @@ void JsUIAbility::onSceneDestroyed()
}
}
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceDestroyed");
if (CreateProperty(abilityContext_, property)) {
property->object_ = jsAbilityObj_;
delegator->PostPerformScenceDestroyed(property);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
if (delegator) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceDestroyed");
delegator->PostPerformScenceDestroyed(property);
}
auto etsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (etsDelegator && etsDelegator != delegator) {
etsDelegator->PostPerformScenceDestroyed(property);
}
}
applicationContext = AbilityRuntime::Context::GetApplicationContext();
@@ -899,12 +935,19 @@ void JsUIAbility::CallOnForegroundFunc(const Want &want)
CallObjectMethod("onForeground", &jsWant, 1);
AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformForeground");
if (CreateProperty(abilityContext_, property)) {
property->object_ = jsAbilityObj_;
delegator->PostPerformForeground(property);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
if (delegator) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformForeground");
delegator->PostPerformForeground(property);
}
auto etsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (etsDelegator && etsDelegator != delegator) {
etsDelegator->PostPerformForeground(property);
}
}
applicationContext = AbilityRuntime::Context::GetApplicationContext();
@@ -934,12 +977,19 @@ void JsUIAbility::OnBackground()
UIAbility::OnBackground();
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
if (delegator && CreateProperty(abilityContext_, property)) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformBackground");
if (CreateProperty(abilityContext_, property)) {
property->object_ = jsAbilityObj_;
delegator->PostPerformBackground(property);
auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
if (delegator) {
TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformBackground");
delegator->PostPerformBackground(property);
}
auto etsDelegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
AbilityRuntime::Runtime::Language::ETS);
if (etsDelegator && etsDelegator != delegator) {
etsDelegator->PostPerformBackground(property);
}
}
applicationContext = AbilityRuntime::Context::GetApplicationContext();
+1
View File
@@ -627,6 +627,7 @@ ohos_shared_library("appkit_delegator") {
"${ability_runtime_native_path}/appkit/ability_delegator/delegator_thread.cpp",
"${ability_runtime_native_path}/appkit/ability_delegator/iability_delegator.cpp",
"${ability_runtime_native_path}/appkit/ability_delegator/iability_monitor.cpp",
"${ability_runtime_native_path}/appkit/ability_delegator/iinterop_ability_monitor.cpp",
"${ability_runtime_native_path}/appkit/ability_delegator/iability_stage_monitor.cpp",
"${ability_runtime_native_path}/appkit/ability_delegator/runner_runtime/ets_test_runner_instance.cpp",
"${ability_runtime_native_path}/appkit/ability_delegator/runner_runtime/js_test_runner.cpp",
@@ -54,6 +54,23 @@ void AbilityDelegator::AddAbilityMonitor(const std::shared_ptr<IAbilityMonitor>
abilityMonitors_.emplace_back(monitor);
}
void AbilityDelegator::AddInteropAbilityMonitor(const std::shared_ptr<IInteropAbilityMonitor> &monitor)
{
if (!monitor) {
TAG_LOGW(AAFwkTag::DELEGATOR, "invalid params");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
auto pos = std::find(interopAbilityMonitors_.begin(), interopAbilityMonitors_.end(), monitor);
if (pos != interopAbilityMonitors_.end()) {
TAG_LOGW(AAFwkTag::DELEGATOR, "interop monitor added");
return;
}
interopAbilityMonitors_.emplace_back(monitor);
}
void AbilityDelegator::AddAbilityStageMonitor(const std::shared_ptr<IAbilityStageMonitor> &monitor)
{
if (!monitor) {
@@ -83,6 +100,20 @@ void AbilityDelegator::RemoveAbilityMonitor(const std::shared_ptr<IAbilityMonito
}
}
void AbilityDelegator::RemoveInteropAbilityMonitor(const std::shared_ptr<IInteropAbilityMonitor> &monitor)
{
if (!monitor) {
TAG_LOGW(AAFwkTag::DELEGATOR, "invalid params");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
auto pos = std::find(interopAbilityMonitors_.begin(), interopAbilityMonitors_.end(), monitor);
if (pos != interopAbilityMonitors_.end()) {
interopAbilityMonitors_.erase(pos);
}
}
void AbilityDelegator::RemoveAbilityStageMonitor(const std::shared_ptr<IAbilityStageMonitor> &monitor)
{
if (!monitor) {
@@ -100,6 +131,7 @@ void AbilityDelegator::ClearAllMonitors()
{
std::unique_lock<std::mutex> lck(mutexMonitor_);
abilityMonitors_.clear();
interopAbilityMonitors_.clear();
}
size_t AbilityDelegator::GetMonitorsNum()
@@ -379,11 +411,6 @@ void AbilityDelegator::PostPerformStart(const std::shared_ptr<BaseDelegatorAbili
ProcessAbilityProperties(ability);
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
TAG_LOGW(AAFwkTag::DELEGATOR, "empty abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
@@ -392,6 +419,15 @@ void AbilityDelegator::PostPerformStart(const std::shared_ptr<BaseDelegatorAbili
monitor->OnAbilityStart(ability);
}
}
for (auto &monitor : interopAbilityMonitors_) {
if (!monitor) {
continue;
}
if (IsFromOtherRuntime(monitor, ability) && monitor->Match(ability, true)) {
monitor->OnAbilityStart(ability);
}
}
}
void AbilityDelegator::PostPerformStageStart(const std::shared_ptr<BaseDelegatorAbilityStageProperty> &abilityStage)
@@ -428,11 +464,6 @@ void AbilityDelegator::PostPerformScenceCreated(const std::shared_ptr<BaseDelega
ProcessAbilityProperties(ability);
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
TAG_LOGW(AAFwkTag::DELEGATOR, "invalid abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
@@ -441,6 +472,15 @@ void AbilityDelegator::PostPerformScenceCreated(const std::shared_ptr<BaseDelega
monitor->OnWindowStageCreate(ability);
}
}
for (auto &monitor : interopAbilityMonitors_) {
if (!monitor) {
continue;
}
if (IsFromOtherRuntime(monitor, ability) && monitor->Match(ability, true)) {
monitor->OnWindowStageCreate(ability);
}
}
}
void AbilityDelegator::PostPerformScenceRestored(const std::shared_ptr<BaseDelegatorAbilityProperty> &ability)
@@ -455,11 +495,6 @@ void AbilityDelegator::PostPerformScenceRestored(const std::shared_ptr<BaseDeleg
ProcessAbilityProperties(ability);
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
@@ -468,6 +503,15 @@ void AbilityDelegator::PostPerformScenceRestored(const std::shared_ptr<BaseDeleg
monitor->OnWindowStageRestore(ability);
}
}
for (auto &monitor : interopAbilityMonitors_) {
if (!monitor) {
continue;
}
if (IsFromOtherRuntime(monitor, ability) && monitor->Match(ability, true)) {
monitor->OnWindowStageRestore(ability);
}
}
}
void AbilityDelegator::PostPerformScenceDestroyed(const std::shared_ptr<BaseDelegatorAbilityProperty> &ability)
@@ -482,11 +526,6 @@ void AbilityDelegator::PostPerformScenceDestroyed(const std::shared_ptr<BaseDele
ProcessAbilityProperties(ability);
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
TAG_LOGW(AAFwkTag::DELEGATOR, "null abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
@@ -495,6 +534,15 @@ void AbilityDelegator::PostPerformScenceDestroyed(const std::shared_ptr<BaseDele
monitor->OnWindowStageDestroy(ability);
}
}
for (auto &monitor : interopAbilityMonitors_) {
if (!monitor) {
continue;
}
if (IsFromOtherRuntime(monitor, ability) && monitor->Match(ability, true)) {
monitor->OnWindowStageDestroy(ability);
}
}
}
void AbilityDelegator::PostPerformForeground(const std::shared_ptr<BaseDelegatorAbilityProperty> &ability)
@@ -509,11 +557,6 @@ void AbilityDelegator::PostPerformForeground(const std::shared_ptr<BaseDelegator
ProcessAbilityProperties(ability);
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
TAG_LOGW(AAFwkTag::DELEGATOR, "invalid abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
@@ -522,6 +565,15 @@ void AbilityDelegator::PostPerformForeground(const std::shared_ptr<BaseDelegator
monitor->OnAbilityForeground(ability);
}
}
for (auto &monitor : interopAbilityMonitors_) {
if (!monitor) {
continue;
}
if (IsFromOtherRuntime(monitor, ability) && monitor->Match(ability, true)) {
monitor->OnAbilityForeground(ability);
}
}
}
void AbilityDelegator::PostPerformBackground(const std::shared_ptr<BaseDelegatorAbilityProperty> &ability)
@@ -536,11 +588,6 @@ void AbilityDelegator::PostPerformBackground(const std::shared_ptr<BaseDelegator
ProcessAbilityProperties(ability);
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
TAG_LOGW(AAFwkTag::DELEGATOR, "invalid abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
@@ -549,6 +596,15 @@ void AbilityDelegator::PostPerformBackground(const std::shared_ptr<BaseDelegator
monitor->OnAbilityBackground(ability);
}
}
for (auto &monitor : interopAbilityMonitors_) {
if (!monitor) {
continue;
}
if (IsFromOtherRuntime(monitor, ability) && monitor->Match(ability, true)) {
monitor->OnAbilityBackground(ability);
}
}
}
void AbilityDelegator::PostPerformStop(const std::shared_ptr<BaseDelegatorAbilityProperty> &ability)
@@ -563,11 +619,6 @@ void AbilityDelegator::PostPerformStop(const std::shared_ptr<BaseDelegatorAbilit
ProcessAbilityProperties(ability);
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
TAG_LOGW(AAFwkTag::DELEGATOR, "invalid abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
@@ -577,6 +628,15 @@ void AbilityDelegator::PostPerformStop(const std::shared_ptr<BaseDelegatorAbilit
}
}
for (auto &monitor : interopAbilityMonitors_) {
if (!monitor) {
continue;
}
if (IsFromOtherRuntime(monitor, ability) && monitor->Match(ability, true)) {
monitor->OnAbilityStop(ability);
}
}
RemoveAbilityProperty(ability);
CallClearFunc(ability);
}
@@ -760,5 +820,14 @@ inline void AbilityDelegator::CallClearFunc(const std::shared_ptr<BaseDelegatorA
clearFunc_(ability);
}
}
bool AbilityDelegator::IsFromOtherRuntime(const std::shared_ptr<IInteropAbilityMonitor> &monitor,
const std::shared_ptr<BaseDelegatorAbilityProperty> &ability)
{
if (!monitor || !ability) {
return false;
}
return monitor->GetLanguage() != ability->language_;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -20,6 +20,8 @@ namespace AppExecFwk {
std::map<AbilityRuntime::Runtime::Language, std::shared_ptr<IAbilityDelegator>>
AbilityDelegatorRegistry::abilityDelegator_ {};
std::shared_ptr<AbilityDelegatorArgs> AbilityDelegatorRegistry::abilityDelegatorArgs_ {};
void *AbilityDelegatorRegistry::napiEnv_ = nullptr;
void *AbilityDelegatorRegistry::aniEnv_ = nullptr;
std::shared_ptr<AbilityDelegator> AbilityDelegatorRegistry::GetAbilityDelegator(
const AbilityRuntime::Runtime::Language &language)
@@ -55,5 +57,21 @@ void AbilityDelegatorRegistry::RegisterInstance(const std::shared_ptr<IAbilityDe
abilityDelegatorArgs_ = args;
abilityDelegator_.insert_or_assign(language, delegator);
}
void AbilityDelegatorRegistry::SetRuntimeEnvs(void *napiEnv, void *aniEnv)
{
napiEnv_ = napiEnv;
aniEnv_ = aniEnv;
}
void *AbilityDelegatorRegistry::GetNapiEnv()
{
return napiEnv_;
}
void *AbilityDelegatorRegistry::GetAniEnv()
{
return aniEnv_;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -0,0 +1,126 @@
/*
* 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 <chrono>
#include "hilog_tag_wrapper.h"
#include "iinterop_ability_monitor.h"
using namespace std::chrono_literals;
namespace OHOS {
namespace AppExecFwk {
IInteropAbilityMonitor::IInteropAbilityMonitor(const std::string &abilityName) : abilityName_(abilityName)
{}
IInteropAbilityMonitor::IInteropAbilityMonitor(const std::string &abilityName,
const std::string &moduleName) : abilityName_(abilityName), moduleName_(moduleName)
{}
bool IInteropAbilityMonitor::Match(const std::shared_ptr<BaseDelegatorAbilityProperty> &ability, bool isNotify)
{
if (!ability) {
TAG_LOGW(AAFwkTag::DELEGATOR, "invalid ability property");
return false;
}
const auto &aName = ability->name_;
if (abilityName_.empty() || aName.empty()) {
TAG_LOGW(AAFwkTag::DELEGATOR, "invalid name");
return false;
}
if (abilityName_.compare(aName)) {
TAG_LOGW(AAFwkTag::DELEGATOR, "different name");
return false;
}
const auto &aModuleName = ability->moduleName_;
if (!moduleName_.empty() && moduleName_.compare(aModuleName) != 0) {
TAG_LOGE(AAFwkTag::DELEGATOR, "different moduleName, %{public}s and %{public}s",
moduleName_.c_str(), aModuleName.c_str());
return false;
}
TAG_LOGI(AAFwkTag::DELEGATOR, "ability name : %{public}s, isNotify : %{public}s",
abilityName_.data(), (isNotify ? "true" : "false"));
if (isNotify) {
TAG_LOGI(AAFwkTag::DELEGATOR, "notify ability matched");
{
std::lock_guard<std::mutex> matchLock(mMatch_);
matchedAbility_ = ability;
}
cvMatch_.notify_one();
}
return true;
}
std::shared_ptr<BaseDelegatorAbilityProperty> IInteropAbilityMonitor::WaitForAbility()
{
return WaitForAbility(MAX_TIME_OUT);
}
std::shared_ptr<BaseDelegatorAbilityProperty> IInteropAbilityMonitor::WaitForAbility(const int64_t timeoutMs)
{
auto realTime = timeoutMs;
if (timeoutMs <= 0) {
TAG_LOGW(AAFwkTag::DELEGATOR, "timeout should not number");
realTime = MAX_TIME_OUT;
}
std::unique_lock<std::mutex> matchLock(mMatch_);
auto condition = [this] { return this->matchedAbility_ != nullptr; };
if (!cvMatch_.wait_for(matchLock, realTime * 1ms, condition)) {
TAG_LOGW(AAFwkTag::DELEGATOR, "wait ability timeout");
}
return matchedAbility_;
}
void IInteropAbilityMonitor::OnAbilityStart(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj)
{}
void IInteropAbilityMonitor::OnAbilityForeground(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj)
{}
void IInteropAbilityMonitor::OnAbilityBackground(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj)
{}
void IInteropAbilityMonitor::OnAbilityStop(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj)
{}
void IInteropAbilityMonitor::OnWindowStageCreate(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj)
{}
void IInteropAbilityMonitor::OnWindowStageRestore(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj)
{}
void IInteropAbilityMonitor::OnWindowStageDestroy(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj)
{}
void IInteropAbilityMonitor::SetLanguage(const AbilityRuntime::Runtime::Language &language)
{
language_ = language;
}
AbilityRuntime::Runtime::Language IInteropAbilityMonitor::GetLanguage() const
{
return language_;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -2650,8 +2650,44 @@ bool MainThread::PrepareAbilityDelegator(const std::shared_ptr<UserTestRecord> &
auto delegator = IAbilityDelegator::Create(application_->GetRuntime(), application_->GetAppContext(),
std::move(testRunner), record->observer);
AbilityDelegatorRegistry::RegisterInstance(delegator, args, application_->GetRuntime()->GetLanguage());
{
void *napiEnvVoid = nullptr;
void *aniVmVoid = nullptr;
auto &curRuntime = application_->GetRuntime();
bool isHybrid = applicationInfo_ &&
applicationInfo_->arkTSMode == AbilityRuntime::CODE_LANGUAGE_ARKTS_HYBRID;
if (isHybrid && curRuntime->GetLanguage() == AbilityRuntime::Runtime::Language::ETS) {
auto &etsRuntime = static_cast<AbilityRuntime::ETSRuntime &>(*curRuntime);
auto aniEnv = etsRuntime.GetAniEnv();
if (aniEnv != nullptr) {
aniVmVoid = reinterpret_cast<void *>(aniEnv);
}
const auto &jsRuntime = etsRuntime.GetJsRuntime();
if (jsRuntime) {
napiEnvVoid = reinterpret_cast<void *>(
static_cast<AbilityRuntime::JsRuntime &>(*jsRuntime).GetNapiEnv());
}
} else if (isHybrid && curRuntime->GetLanguage() == AbilityRuntime::Runtime::Language::JS) {
napiEnvVoid = reinterpret_cast<void *>(
static_cast<AbilityRuntime::JsRuntime &>(*curRuntime).GetNapiEnv());
}
AbilityDelegatorRegistry::SetRuntimeEnvs(napiEnvVoid, aniVmVoid);
}
delegator->SetApiTargetVersion(targetVersion);
delegator->Prepare();
if (applicationInfo_ && applicationInfo_->arkTSMode == AbilityRuntime::CODE_LANGUAGE_ARKTS_HYBRID) {
auto currentLanguage = application_->GetRuntime()->GetLanguage();
auto targetLanguage = AbilityRuntime::Runtime::Language::JS;
if (currentLanguage == AbilityRuntime::Runtime::Language::JS) {
targetLanguage = AbilityRuntime::Runtime::Language::ETS;
}
auto interopTestRunner = TestRunner::Create(application_->GetRuntime(), args, false);
auto interopDelegator = IAbilityDelegator::Create(application_->GetRuntime(),
application_->GetAppContext(), std::move(interopTestRunner), record->observer);
AbilityDelegatorRegistry::RegisterInstance(interopDelegator, args, targetLanguage);
interopDelegator->SetApiTargetVersion(targetVersion);
interopDelegator->Prepare();
}
} else { // FA model
TAG_LOGD(AAFwkTag::APPKIT, "FA model");
AbilityRuntime::Runtime::Options options;
@@ -33,6 +33,7 @@
#include "context.h"
#include "delegator_thread.h"
#include "iability_monitor.h"
#include "iinterop_ability_monitor.h"
#include "iability_stage_monitor.h"
#include "shell_cmd_result.h"
#include "test_runner.h"
@@ -97,6 +98,13 @@ public:
*/
void AddAbilityMonitor(const std::shared_ptr<IAbilityMonitor> &monitor);
/**
* Adds interop monitor for monitoring the lifecycle state changes of the ability.
*
* @param monitor, Indicates the interop monitor object.
*/
void AddInteropAbilityMonitor(const std::shared_ptr<IInteropAbilityMonitor> &monitor);
/**
* Adds monitor for monitoring the lifecycle state changes of the abilityStage.
*
@@ -111,6 +119,13 @@ public:
*/
void RemoveAbilityMonitor(const std::shared_ptr<IAbilityMonitor> &monitor);
/**
* Removes interop ability monitor.
*
* @param monitor, Indicates the specified interop monitor object.
*/
void RemoveInteropAbilityMonitor(const std::shared_ptr<IInteropAbilityMonitor> &monitor);
/**
* Removes abilityStage monitor.
*
@@ -333,6 +348,8 @@ private:
std::shared_ptr<BaseDelegatorAbilityProperty> FindPropertyByToken(const sptr<IRemoteObject> &token);
std::shared_ptr<BaseDelegatorAbilityProperty> FindPropertyByName(const std::string &name);
inline void CallClearFunc(const std::shared_ptr<BaseDelegatorAbilityProperty> &ability);
bool IsFromOtherRuntime(const std::shared_ptr<IInteropAbilityMonitor> &monitor,
const std::shared_ptr<BaseDelegatorAbilityProperty> &ability);
private:
static constexpr size_t INFORMATION_MAX_LENGTH {1000};
@@ -347,6 +364,7 @@ private:
std::unique_ptr<DelegatorThread> delegatorThread_;
std::list<std::shared_ptr<BaseDelegatorAbilityProperty>> abilityProperties_;
std::vector<std::shared_ptr<IAbilityMonitor>> abilityMonitors_;
std::vector<std::shared_ptr<IInteropAbilityMonitor>> interopAbilityMonitors_;
std::vector<std::shared_ptr<IAbilityStageMonitor>> abilityStageMonitors_;
ClearFunc clearFunc_;
@@ -19,6 +19,7 @@
#include <string>
#include "ability_lifecycle_executor.h"
#include "iremote_object.h"
#include "runtime.h"
class NativeReference;
@@ -36,6 +37,8 @@ struct BaseDelegatorAbilityProperty {
std::string fullName_;
// lifecycle state of ability
AbilityLifecycleExecutor::LifecycleState lifecycleState_ {AbilityLifecycleExecutor::LifecycleState::UNINITIALIZED};
// runtime language source of ability
AbilityRuntime::Runtime::Language language_ {AbilityRuntime::Runtime::Language::JS};
};
struct ADelegatorAbilityProperty : public BaseDelegatorAbilityProperty {
std::weak_ptr<NativeReference> object_;
@@ -65,9 +65,15 @@ public:
const std::shared_ptr<IAbilityDelegator> &delegator, const std::shared_ptr<AbilityDelegatorArgs> &args,
const AbilityRuntime::Runtime::Language &language);
static void SetRuntimeEnvs(void *napiEnv, void *aniEnv);
static void *GetNapiEnv();
static void *GetAniEnv();
private:
static std::map<AbilityRuntime::Runtime::Language, std::shared_ptr<IAbilityDelegator>> abilityDelegator_;
static std::shared_ptr<AbilityDelegatorArgs> abilityDelegatorArgs_;
static void *napiEnv_;
static void *aniEnv_;
};
} // namespace AppExecFwk
} // namespace OHOS
@@ -0,0 +1,165 @@
/*
* 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_IINTEROP_ABILITY_MONITOR_H
#define OHOS_ABILITY_RUNTIME_IINTEROP_ABILITY_MONITOR_H
#include <condition_variable>
#include <memory>
#include <mutex>
#include <string>
#include "ability_delegator_infos.h"
#include "runtime.h"
namespace OHOS {
namespace AppExecFwk {
class IInteropAbilityMonitor {
public:
/**
* Indicates that the default timeout is 5 seconds.
*/
static constexpr int64_t MAX_TIME_OUT {5000};
public:
/**
* A constructor used to create a IInteropAbilityMonitor instance with the input parameter passed.
*
* @param abilityName Indicates the specified ability name for monitoring the lifecycle state changes
* of the ability.
*/
explicit IInteropAbilityMonitor(const std::string &abilityName);
/**
* A constructor used to create a IInteropAbilityMonitor instance with the input parameter passed.
*
* @param abilityName Indicates the specified ability name for monitoring the lifecycle state changes
* @param moduleName Indicates the specified ability moduleName for monitoring the lifecycle state changes
* of the ability.
*/
explicit IInteropAbilityMonitor(const std::string &abilityName, const std::string &moduleName);
/**
* Sets the runtime language source of this interop monitor.
*
* @param language Indicates the runtime language.
*/
void SetLanguage(const AbilityRuntime::Runtime::Language &language);
/**
* Gets the runtime language source of this interop monitor.
*
* @return the runtime language.
*/
AbilityRuntime::Runtime::Language GetLanguage() const;
/**
* Default deconstructor used to deconstruct.
*/
virtual ~IInteropAbilityMonitor() = default;
/**
* Match the monitored Ability objects when newAbility objects are started or
* the lifecycle states of monitored abilities have changed.
*
* @param ability Indicates the ability.
* @param isNotify Indicates whether to notify the matched ability to the object who waited.
* @return true if match is successful; returns false otherwise.
*/
virtual bool Match(const std::shared_ptr<BaseDelegatorAbilityProperty> &ability, bool isNotify = false);
/**
* Waits for and returns the started Ability object that matches the conditions specified in this monitor
* within 5 seconds.
* The current thread will be blocked until the 5-second default timer expires.
*
* @return the Ability object if any object has started is matched within 5 seconds; returns null otherwise.
*/
virtual std::shared_ptr<BaseDelegatorAbilityProperty> WaitForAbility();
/**
* Waits for and returns the started Ability object that matches the conditions specified in this monitor
* within the specified time.
* The current thread will be blocked until the timer specified by timeoutMillisecond expires.
*
* @param timeoutMs Indicates the maximum amount of time to wait, in milliseconds.
* The value must be a positive integer.
* @return the Ability object if any object has started is matched within the specified time;
* returns null otherwise.
*/
virtual std::shared_ptr<BaseDelegatorAbilityProperty> WaitForAbility(const int64_t timeoutMs);
/**
* Called when ability is started.
*
* @param abilityObj Indicates the ability object.
*/
virtual void OnAbilityStart(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj);
/**
* Called when ability is in foreground.
*
* @param abilityObj Indicates the ability object.
*/
virtual void OnAbilityForeground(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj);
/**
* Called when ability is in background.
*
* @param abilityObj Indicates the ability object.
*/
virtual void OnAbilityBackground(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj);
/**
* Called when ability is stopped.
*
* @param abilityObj Indicates the ability object.
*/
virtual void OnAbilityStop(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj);
/**
* Called when window stage is created.
*
* @param abilityObj Indicates the ability object.
*/
virtual void OnWindowStageCreate(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj);
/**
* Called when window stage is restored.
*
* @param abilityObj Indicates the ability object.
*/
virtual void OnWindowStageRestore(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj);
/**
* Called when window stage is destroyed.
*
* @param abilityObj Indicates the ability object.
*/
virtual void OnWindowStageDestroy(const std::weak_ptr<BaseDelegatorAbilityProperty> &abilityObj);
private:
std::string abilityName_;
std::string moduleName_;
std::shared_ptr<BaseDelegatorAbilityProperty> matchedAbility_;
AbilityRuntime::Runtime::Language language_ {AbilityRuntime::Runtime::Language::JS};
std::condition_variable cvMatch_;
std::mutex mMatch_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_IINTEROP_ABILITY_MONITOR_H