diff --git a/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp b/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp index cbc1fd0f01..66629aac0b 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp @@ -1833,7 +1833,10 @@ sptr JsUIAbility::CallRequest() } napi_value remoteJsObj = nullptr; + std::string methodName = "onCallRequest"; + AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::BY_CALL, methodName); napi_call_function(env, obj, method, 0, nullptr, &remoteJsObj); + AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::BY_CALL, methodName); if (remoteJsObj == nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "null remoteJsObj"); return nullptr; diff --git a/frameworks/native/ability/native/ui_ability_thread.cpp b/frameworks/native/ability/native/ui_ability_thread.cpp index 98685a8a16..04114c47a8 100644 --- a/frameworks/native/ability/native/ui_ability_thread.cpp +++ b/frameworks/native/ability/native/ui_ability_thread.cpp @@ -623,7 +623,11 @@ void UIAbilityThread::CallRequest() retval = currentAbility->CallRequest(); }; + std::string entry = "UIAbilityThread::CallRequest Begin"; + FreezeUtil::GetInstance().AddLifecycleEvent(token_, entry); abilityHandler_->PostSyncTask(syncTask, "UIAbilityThread:CallRequest"); + std::string end = "UIAbilityThread::CallRequest End"; + FreezeUtil::GetInstance().AddLifecycleEvent(token_, end); AbilityManagerClient::GetInstance()->CallRequestDone(token_, retval); TAG_LOGD(AAFwkTag::UIABILITY, "end"); } diff --git a/services/abilitymgr/include/ability_record.h b/services/abilitymgr/include/ability_record.h index 147d4e9f12..b0c31173e5 100644 --- a/services/abilitymgr/include/ability_record.h +++ b/services/abilitymgr/include/ability_record.h @@ -1390,6 +1390,8 @@ private: void GetColdStartingWindowResource(std::shared_ptr &bg, uint32_t &bgColor); void SetAbilityStateInner(AbilityState state); #endif + void PostStartAbilityByCallTimeoutTask(bool isHalf); + void CancelStartAbilityByCallTimeoutTask() const; void SendAppStartupTypeEvent(const AppExecFwk::AppStartType startType); std::atomic isPreloadStart_ = false; // is ability started via preload diff --git a/services/abilitymgr/src/ability_record.cpp b/services/abilitymgr/src/ability_record.cpp index 596c98862b..959cc6b28a 100644 --- a/services/abilitymgr/src/ability_record.cpp +++ b/services/abilitymgr/src/ability_record.cpp @@ -21,6 +21,7 @@ #include "ability_resident_process_rdb.h" #include "ability_scheduler_stub.h" #include "app_exit_reason_data_manager.h" +#include "appfreeze_manager.h" #include "app_utils.h" #include "array_wrapper.h" #include "accesstoken_kit.h" @@ -120,6 +121,8 @@ const int RESTART_SCENEBOARD_DELAY = 500; constexpr int32_t DMS_UID = 5522; constexpr int32_t SCHEDULER_DIED_TIMEOUT = 60000; const std::string JSON_KEY_ERR_MSG = "errMsg"; +const int32_t BY_CALL_HALF_TIMEOUT_MS = 2500; +const int32_t BY_CALL_TIMEOUT_MS = 5000; auto g_addLifecycleEventTask = [](sptr token, std::string &methodName) { CHECK_POINTER_LOG(token, "token is nullptr"); @@ -3276,16 +3279,78 @@ void AbilityRecord::SetCallerSetProcess(const bool flag) isCallerSetProcess_.store(flag); } +void AbilityRecord::PostStartAbilityByCallTimeoutTask(bool isHalf) +{ + auto handler = DelayedSingleton::GetInstance()->GetTaskHandler(); + CHECK_POINTER(handler); + + auto timeoutTask = [isHalf, ability = shared_from_this()]() { + AppExecFwk::RunningProcessInfo processInfo; + std::string abilityName = ability->GetAbilityInfo().name; + std::string bundleName = ability->GetAbilityInfo().bundleName; + DelayedSingleton::GetInstance()->GetRunningProcessInfoByToken(ability->GetToken(), processInfo); + if (processInfo.pid_ == 0) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "ability:%{public}s, app fork fail/not run", abilityName.c_str()); + return; + } + int typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT; + std::string msgContent = "ability:" + abilityName + " "; + std::string eventName; + FreezeUtil::TimeoutState state = FreezeUtil::TimeoutState::BY_CALL; + msgContent = isHalf ? msgContent + "call request half timeout." : msgContent + "call request timeout."; + eventName = isHalf ? AppExecFwk::AppFreezeType::LIFECYCLE_HALF_TIMEOUT_WARNING + : AppExecFwk::AppFreezeType::LIFECYCLE_TIMEOUT_WARNING; + + TAG_LOGW(AAFwkTag::ABILITYMGR, "%{public}s: uid: %{public}d, pid: %{public}d, bundleName: %{public}s, " + "abilityName: %{public}s, msg: %{public}s", eventName.c_str(), processInfo.uid_, processInfo.pid_, + bundleName.c_str(), abilityName.c_str(), msgContent.c_str()); + + AppExecFwk::AppfreezeManager::ParamInfo info = { false, typeId, processInfo.pid_, eventName, bundleName }; + FreezeUtil::LifecycleFlow flow; + if (ability->GetToken() != nullptr) { + flow.token = ability->GetToken()->AsObject(); + flow.state = state; + } + info.msg = msgContent + "\nserver actions for ability:\n" + + FreezeUtil::GetInstance().GetLifecycleEvent(flow.token) + + "\nserver actions for app:\n" + FreezeUtil::GetInstance().GetAppLifecycleEvent(processInfo.pid_); + if (!isHalf) { + FreezeUtil::GetInstance().DeleteLifecycleEvent(flow.token); + FreezeUtil::GetInstance().DeleteAppLifecycleEvent(processInfo.pid_); + } + AppExecFwk::AppfreezeManager::GetInstance()->LifecycleTimeoutHandle(info, flow); + }; + auto timeoutMs = isHalf ? BY_CALL_HALF_TIMEOUT_MS : BY_CALL_TIMEOUT_MS; + std::string taskPrefix = isHalf ? "by_call_half_timeout_" : "by_call_timeout_"; + handler->SubmitTask(timeoutTask, taskPrefix + std::to_string(recordId_), timeoutMs); +} + void AbilityRecord::CallRequest() { CHECK_POINTER(scheduler_); // Async call request + std::string entry = "AbilityRecord::CallRequest Begin"; + FreezeUtil::GetInstance().AddLifecycleEvent(token_, entry); scheduler_->CallRequest(); + PostStartAbilityByCallTimeoutTask(true); + PostStartAbilityByCallTimeoutTask(false); +} + +void AbilityRecord::CancelStartAbilityByCallTimeoutTask() const +{ + auto handler = DelayedSingleton::GetInstance()->GetTaskHandler(); + if (!handler) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "fail get AbilityEventHandler"); + return; + } + handler->CancelTask("by_call_timeout_" + std::to_string(recordId_)); + handler->CancelTask("by_call_half_timeout_" + std::to_string(recordId_)); } bool AbilityRecord::CallRequestDone(const sptr &callStub) const { CHECK_POINTER_RETURN_BOOL(callContainer_); + CancelStartAbilityByCallTimeoutTask(); if (!callContainer_->CallRequestDone(callStub)) { TAG_LOGE(AAFwkTag::ABILITYMGR, "call failed"); return false; diff --git a/utils/global/freeze/include/freeze_util.h b/utils/global/freeze/include/freeze_util.h index def06b12dd..f084be95a7 100644 --- a/utils/global/freeze/include/freeze_util.h +++ b/utils/global/freeze/include/freeze_util.h @@ -30,7 +30,8 @@ public: LOAD, FOREGROUND, BACKGROUND, - CONNECT + CONNECT, + BY_CALL }; struct LifecycleFlow {