diff --git a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp index 6071ca92bfd750e6a87b86e67fb60f1f6539a24b..55582ae4cf1b95e1e07fbfdc2a9c5aa8cf265642 100755 --- a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp +++ b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp @@ -997,6 +997,7 @@ napi_value JsUIExtension::CallObjectMethod(const char *name, napi_value const *a return handleEscape.Escape(result); } TAG_LOGD(AAFwkTag::UI_EXT, "JsUIExtension CallFunction(%{public}s), success", name); + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); napi_call_function(env, obj, method, argc, argv, nullptr); return nullptr; } diff --git a/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp b/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp index 550f52f12f09012938fffcc61c06f9ace28d6b62..73f91ba8831bf40af26cdecf441b12781cea0ac2 100644 --- a/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp +++ b/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp @@ -54,6 +54,24 @@ constexpr const char *TASKPOOL_LOWER = "taskpool"; constexpr const char *CALLBACK_SUCCESS = "success"; constexpr const int32_t ARGC_ONE = 1; namespace { +void *DetachNewBaseContext(napi_env, void *nativeObject, void *) +{ + auto *origContext = static_cast *>(nativeObject); + if (origContext == nullptr) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "origContext is null"); + return nullptr; + } + TAG_LOGD(AAFwkTag::ABILITY_SIM, "New detached base context"); + auto *detachNewContext = new (std::nothrow) std::weak_ptr(*origContext); + return detachNewContext; +} + +void DetachFinalizeBaseContext(void *detachedObject, void *) +{ + TAG_LOGD(AAFwkTag::ABILITY_SIM, "Finalizer detached base context"); + delete static_cast *>(detachedObject); +} + void RegisterStopPreloadSoCallback(JsRuntime& jsRuntime) { std::shared_ptr startupManager = DelayedSingleton::GetInstance(); @@ -863,7 +881,6 @@ void JsAbilityStage::SetJsAbilityStage(const std::shared_ptr &context) return; } } - napi_value contextObj = CreateJsAbilityStageContext(env, context); shellContextRef_ = JsRuntime::LoadSystemModuleByEngine(env, "application.AbilityStageContext", &contextObj, 1); if (shellContextRef_ == nullptr) { @@ -876,8 +893,14 @@ void JsAbilityStage::SetJsAbilityStage(const std::shared_ptr &context) return; } auto workContext = new (std::nothrow) std::weak_ptr(context); - napi_coerce_to_native_binding_object( - env, contextObj, DetachCallbackFunc, AttachAbilityStageContext, workContext, nullptr); + auto coerceStatus = napi_coerce_to_native_binding_object( + env, contextObj, DetachNewBaseContext, AttachAbilityStageContext, workContext, nullptr); + if (coerceStatus != napi_ok) { + TAG_LOGW(AAFwkTag::APPKIT, "coerce ability stage context failed: %{public}d", coerceStatus); + delete workContext; + return; + } + napi_add_detached_finalizer(env, contextObj, DetachFinalizeBaseContext, nullptr); context->Bind(jsRuntime_, shellContextRef_.get()); if (obj != nullptr) { diff --git a/frameworks/native/appkit/ability_runtime/app/js_ability_stage_context.cpp b/frameworks/native/appkit/ability_runtime/app/js_ability_stage_context.cpp index 349241d864c0ac73db0905b3214dcc69be8c921b..5aa70ecee178aee7109cfb721ce9c0559d69c349 100644 --- a/frameworks/native/appkit/ability_runtime/app/js_ability_stage_context.cpp +++ b/frameworks/native/appkit/ability_runtime/app/js_ability_stage_context.cpp @@ -25,6 +25,26 @@ namespace OHOS { namespace AbilityRuntime { +namespace { +void* DetachNewAbilityStageContext(napi_env, void* nativeObject, void*) +{ + auto* origContext = static_cast *>(nativeObject); + if (origContext == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "origContext is null"); + return nullptr; + } + TAG_LOGD(AAFwkTag::APPKIT, "New detached abilityStage context"); + auto* detachNewContext = new (std::nothrow) std::weak_ptr(*origContext); + return detachNewContext; +} + +void DetachFinalizeAbilityStageContext(void* detachedObject, void*) +{ + TAG_LOGD(AAFwkTag::APPKIT, "Finalizer detached abilityStage context"); + delete static_cast *>(detachedObject); +} +} + void JsAbilityStageContext::ConfigurationUpdated(napi_env env, std::shared_ptr &jsContext, const std::shared_ptr &config) { @@ -96,14 +116,15 @@ napi_value AttachAbilityStageContext(napi_env env, void *value, void *hint) return nullptr; } + auto workContext = new (std::nothrow) std::weak_ptr(ptr); auto status = napi_coerce_to_native_binding_object( - env, contextObj, DetachCallbackFunc, AttachAbilityStageContext, value, nullptr); + env, contextObj, DetachNewAbilityStageContext, AttachAbilityStageContext, workContext, nullptr); if (status != napi_ok) { TAG_LOGW(AAFwkTag::APPKIT, "coerce ability stage context failed: %{public}d", status); return nullptr; } + napi_add_detached_finalizer(env, contextObj, DetachFinalizeAbilityStageContext, nullptr); - auto workContext = new (std::nothrow) std::weak_ptr(ptr); status = napi_wrap(env, contextObj, workContext, [](napi_env, void *data, void *) { TAG_LOGD(AAFwkTag::CONTEXT, "finalizer for weak_ptr ability stage context"); diff --git a/test/unittest/preload_uiext_state_observer_test/preload_uiext_state_observer_test.cpp b/test/unittest/preload_uiext_state_observer_test/preload_uiext_state_observer_test.cpp index 49acb23a0ac69c27b667c7d7b8a3acd6dd5240d5..27b869712fcd957a995fef2e011b53763c73ede3 100644 --- a/test/unittest/preload_uiext_state_observer_test/preload_uiext_state_observer_test.cpp +++ b/test/unittest/preload_uiext_state_observer_test/preload_uiext_state_observer_test.cpp @@ -136,5 +136,32 @@ HWTEST_F(PreloadUIextStateObserverTest, OnAppCacheStateChanged_001, Function | M EXPECT_TRUE(record == nullptr); GTEST_LOG_(INFO) << "OnAppCacheStateChanged_001 end"; } + +/** + * @tc.number: OnAppCacheStateChanged_002 + * @tc.name: OnAppCacheStateChanged + * @tc.desc: Test whether OnAppCacheStateChanged is called normally. + * @tc.type: FUNC + */ +HWTEST_F(PreloadUIextStateObserverTest, OnAppCacheStateChanged_002, Function | MediumTest | Level1) +{ + GTEST_LOG_(INFO) << "OnAppCacheStateChanged_002 start"; + Want want; + AppExecFwk::AbilityInfo abilityInfo; + AppExecFwk::ApplicationInfo applicationInfo; + std::shared_ptr abilityRecord = + std::make_shared(want, abilityInfo, applicationInfo); + auto extensionRecordSharedPtr = std::make_shared(abilityRecord); + auto hostPid = extensionRecordSharedPtr->hostPid_ = 10; + std::weak_ptr extensionRecord = extensionRecordSharedPtr; + PreLoadUIExtStateObserver preLoadUIExtStateObserver(extensionRecord); + AppExecFwk::AppStateData appStateData; + int32_t diedPid = appStateData.pid; + preLoadUIExtStateObserver.OnAppCacheStateChanged(appStateData); + auto record = preLoadUIExtStateObserver.extensionRecord_.lock(); + EXPECT_TRUE(record != nullptr); + EXPECT_TRUE(record->hostPid_ != diedPid); + GTEST_LOG_(INFO) << "OnAppCacheStateChanged_002 end"; +} } // namespace AbilityRuntime } // namespace OHOS