update background detect

Signed-off-by: acdemicJava <yinhuiling@h-partners.com>
This commit is contained in:
acdemicJava
2025-09-26 17:50:02 +08:00
parent de00984a53
commit ea43814d11
9 changed files with 74 additions and 35 deletions
@@ -121,7 +121,9 @@ void AppfreezeInner::GetMainHandlerDump(std::string& msgContent)
void AppfreezeInner::ChangeFaultDateInfo(FaultData& faultData, const std::string& msgContent)
{
faultData.errorObject.message += msgContent;
faultData.faultType = FaultDataType::APP_FREEZE;
faultData.isInForeground = GetAppInForeground();
bool isInBackGround = AppExecFwk::AppfreezeManager::GetInstance()->CheckInBackGround(faultData);
faultData.faultType = isInBackGround ? FaultDataType::BACKGROUND_WARNING : FaultDataType::APP_FREEZE;
faultData.notifyApp = false;
faultData.waitSaveState = false;
faultData.forceExit = false;
@@ -138,7 +140,8 @@ void AppfreezeInner::ChangeFaultDateInfo(FaultData& faultData, const std::string
if (isExit) {
faultData.forceExit = true;
faultData.waitSaveState = AppRecovery::GetInstance().IsEnabled();
AAFwk::ExitReason exitReason = {REASON_APP_FREEZE, "Kill Reason:" + faultData.errorObject.name};
std::string reason = isInBackGround ? "Background warning" : faultData.errorObject.name;
AAFwk::ExitReason exitReason = {REASON_APP_FREEZE, "Kill Reason:" + reason};
AbilityManagerClient::GetInstance()->RecordAppExitReason(exitReason);
}
NotifyANR(faultData);
@@ -153,7 +156,6 @@ void AppfreezeInner::AppfreezeHandleOverReportCount(bool isSixSecondEvent)
faultData.errorObject.message =
"\nFault time:" + AbilityRuntime::TimeUtil::FormatTime("%Y/%m/%d-%H:%M:%S") + "\n";
faultData.errorObject.message += "App main thread is not response!";
faultData.faultType = FaultDataType::APP_FREEZE;
int32_t pid = static_cast<int32_t>(getpid());
if (isSixSecondEvent) {
faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_6S;
@@ -181,7 +183,6 @@ void AppfreezeInner::AppfreezeHandleOverReportCount(bool isSixSecondEvent)
void AppfreezeInner::EnableFreezeSample(FaultData& newFaultData)
{
std::string eventName = newFaultData.errorObject.name;
newFaultData.isInForeground = GetAppInForeground();
if (eventName == AppFreezeType::THREAD_BLOCK_3S || eventName == AppFreezeType::LIFECYCLE_HALF_TIMEOUT) {
OHOS::HiviewDFX::Watchdog::GetInstance().StartSample(HALF_DURATION, HALF_INTERVAL);
TAG_LOGI(AAFwkTag::APPDFR, "start to sample freeze stack, eventName:%{public}s", eventName.c_str());
@@ -278,7 +279,6 @@ int AppfreezeInner::AcquireStack(const FaultData& info, bool onlyMainThread)
faultData.appfreezeInfo = it->appfreezeInfo;
faultData.appRunningUniqueId = it->appRunningUniqueId;
faultData.procStatm = it->procStatm;
faultData.isInForeground = it->isInForeground;
faultData.isEnableMainThreadSample = it->isEnableMainThreadSample;
faultData.schedTime = it->schedTime;
faultData.detectTime = it->detectTime;
@@ -299,7 +299,6 @@ void AppfreezeInner::ThreadBlock(std::atomic_bool& isSixSecondEvent, uint64_t sc
faultData.errorObject.message =
"\nFault time:" + AbilityRuntime::TimeUtil::FormatTime("%Y/%m/%d-%H:%M:%S") + "\n";
faultData.errorObject.message += "App main thread is not response!";
faultData.faultType = FaultDataType::APP_FREEZE;
bool onlyMainThread = false;
int32_t pid = static_cast<int32_t>(getpid());
faultData.pid = pid;
+4 -11
View File
@@ -171,10 +171,6 @@ void Watchdog::SetBundleInfo(const std::string& bundleName, const std::string& b
ChangeTimeOut(bundleName);
}
#endif
{
std::unique_lock<std::mutex> lock(cvMutex_);
bundleName_ = bundleName;
}
}
void Watchdog::SetBackgroundStatus(const bool isInBackground)
@@ -287,16 +283,13 @@ void Watchdog::ReportEvent()
}
if (isInBackground_ && backgroundReportCount_.load() < BACKGROUND_REPORT_COUNT_MAX) {
bool enableCheck = std::find(std::begin(CHECK_BACKGROUND_THREAD), std::end(CHECK_BACKGROUND_THREAD),
bundleName_) != std::end(CHECK_BACKGROUND_THREAD);
if (enableCheck) {
backgroundReportCount_++;
}
backgroundReportCount_++;
TAG_LOGI(AAFwkTag::APPDFR, "In Background, thread may be blocked in, not report time"
"currTime: %{public}" PRIu64 ", lastTime: %{public}" PRIu64 ", enableCheck: %{public}d",
static_cast<uint64_t>(now), static_cast<uint64_t>(lastWatchTime_), enableCheck);
"currTime: %{public}" PRIu64 ", lastTime: %{public}" PRIu64 ", count: %{public}d",
static_cast<uint64_t>(now), static_cast<uint64_t>(lastWatchTime_), backgroundReportCount_.load());
return;
}
backgroundReportCount_++;
if (!needReport_) {
return;
@@ -37,7 +37,8 @@ enum class FaultDataType {
APP_FREEZE,
CPU_LOAD,
PERFORMANCE_CONTROL,
RESOURCE_CONTROL
RESOURCE_CONTROL,
BACKGROUND_WARNING
};
enum AppStatus {
@@ -58,6 +59,7 @@ public:
static constexpr char APP_INPUT_BLOCK[] = "APP_INPUT_BLOCK";
static constexpr char BUSSINESS_THREAD_BLOCK_3S[] = "BUSSINESS_THREAD_BLOCK_3S";
static constexpr char BUSSINESS_THREAD_BLOCK_6S[] = "BUSSINESS_THREAD_BLOCK_6S";
static constexpr char BACKGROUND_WARNING[] = "BACKGROUND_WARNING";
};
/**
* @struct FaultData
@@ -129,7 +129,6 @@ private:
std::condition_variable cvWatchdog_;
static std::shared_ptr<EventHandler> appMainHandler_;
int64_t lastWatchTime_ = 0;
std::string bundleName_;
bool isSystemApp_ = true;
};
} // namespace AppExecFwk
@@ -108,6 +108,8 @@ public:
void ReportAppFreezeSysEvents(int32_t pid, const std::string& bundleName);
void RegisterAppKillTime(int32_t pid, uint64_t killTime);
void InitWarningCpuInfo(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo);
bool CheckInBackGround(const FaultData &faultData);
bool CheckAppfreezeHappend(int32_t pid, const std::string& eventName);
private:
struct PeerBinderInfo {
+23 -1
View File
@@ -835,7 +835,8 @@ bool AppfreezeManager::IsNeedIgnoreFreezeEvent(int32_t pid, const std::string& e
}
return true;
} else {
if (errorName == "THREAD_BLOCK_3S") {
if (errorName == AppFreezeType::THREAD_BLOCK_3S ||
errorName == AppFreezeType::BUSSINESS_THREAD_BLOCK_3S) {
return false;
}
SetFreezeState(pid, AppFreezeState::APPFREEZE_STATE_FREEZE, errorName);
@@ -1003,5 +1004,26 @@ std::string AppfreezeManager::GetFirstLine(const std::string &path)
inFile.close();
return firstLine;
}
bool AppfreezeManager::CheckInBackGround(const FaultData &faultData)
{
return faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_6S &&
!faultData.isInForeground;
}
bool AppfreezeManager::CheckAppfreezeHappend(int32_t pid, const std::string& eventName)
{
if (eventName == AppFreezeType::LIFECYCLE_TIMEOUT || eventName == AppFreezeType::APP_INPUT_BLOCK ||
eventName == AppFreezeType::THREAD_BLOCK_6S || eventName == AppFreezeType::THREAD_BLOCK_3S ||
eventName == AppFreezeType::BUSSINESS_THREAD_BLOCK_3S ||
eventName == AppFreezeType::BUSSINESS_THREAD_BLOCK_6S) {
if (IsNeedIgnoreFreezeEvent(pid, eventName)) {
TAG_LOGE(AAFwkTag::APPDFR, "appFreeze happend, pid:%{public}d, eventName:%{public}s",
pid, eventName.c_str());
return true;
}
}
return false;
}
} // namespace AAFwk
} // namespace OHOS
+18 -14
View File
@@ -7319,7 +7319,8 @@ void AppMgrServiceInner::AppRecoveryNotifyApp(int32_t pid, const std::string& bu
void AppMgrServiceInner::ParseInfoToAppfreeze(const FaultData &faultData, int32_t pid, int32_t uid,
const std::string &bundleName, const std::string &processName, const bool isOccurException)
{
if (faultData.faultType == FaultDataType::APP_FREEZE) {
if (faultData.faultType == FaultDataType::APP_FREEZE ||
faultData.faultType == FaultDataType::BACKGROUND_WARNING) {
AppfreezeManager::AppInfo info = {
.isOccurException = isOccurException,
.pid = pid,
@@ -7358,7 +7359,9 @@ int AppMgrServiceInner::GetExceptionTimerId(const FaultData &faultData, const st
TAG_LOGI(AAFwkTag::APPMGR, "Ffrt Exception faultData: %{public}s,pid: %{public}d "
"will exit because"" %{public}s", bundleName.c_str(), pid,
innerService->FaultTypeToString(faultData.faultType).c_str());
innerService->KillProcessByPid(pid, faultData.errorObject.name);
std::string reason = AppExecFwk::AppfreezeManager::GetInstance()->CheckInBackGround(faultData) ?
AppFreezeType::BACKGROUND_WARNING : faultData.errorObject.name;
innerService->KillProcessByPid(pid, reason);
return;
}
};
@@ -7448,7 +7451,7 @@ int32_t AppMgrServiceInner::NotifyAppFault(const FaultData &faultData)
return ERR_OK;
}
if (faultData.faultType == FaultDataType::APP_FREEZE) {
if (faultData.faultType == FaultDataType::APP_FREEZE || faultData.faultType == FaultDataType::BACKGROUND_WARNING) {
if (CheckAppFault(appRecord, faultData)) {
return ERR_OK;
}
@@ -7457,14 +7460,9 @@ int32_t AppMgrServiceInner::NotifyAppFault(const FaultData &faultData)
AppRecoveryNotifyApp(pid, bundleName, FaultDataType::APP_FREEZE, "recoveryTimeout");
}
}
if (eventName == AppFreezeType::LIFECYCLE_TIMEOUT || eventName == AppFreezeType::APP_INPUT_BLOCK ||
eventName == AppFreezeType::THREAD_BLOCK_6S || eventName == AppFreezeType::THREAD_BLOCK_3S ||
eventName == AppFreezeType::BUSSINESS_THREAD_BLOCK_3S || eventName == AppFreezeType::BUSSINESS_THREAD_BLOCK_6S) {
if (AppExecFwk::AppfreezeManager::GetInstance()->IsNeedIgnoreFreezeEvent(pid, eventName)) {
TAG_LOGE(AAFwkTag::APPDFR, "appFreeze happend, pid:%{public}d, eventName:%{public}s",
pid, eventName.c_str());
return ERR_OK;
}
if (AppExecFwk::AppfreezeManager::GetInstance()->CheckAppfreezeHappend(pid, eventName)) {
return ERR_OK;
}
if (appRunningManager_ && eventName.find("THREAD_BLOCK_") != std::string::npos) {
@@ -7522,7 +7520,9 @@ int32_t AppMgrServiceInner::KillFaultApp(int32_t pid, const std::string &bundleN
uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
AppExecFwk::AppfreezeManager::GetInstance()->RegisterAppKillTime(pid, now);
innerService->KillProcessByPid(pid, faultData.errorObject.name);
std::string reason = AppExecFwk::AppfreezeManager::GetInstance()->CheckInBackGround(faultData) ?
AppFreezeType::BACKGROUND_WARNING : faultData.errorObject.name;
innerService->KillProcessByPid(pid, reason);
return;
};
constexpr int32_t waitTime = 3500;
@@ -7549,7 +7549,7 @@ void AppMgrServiceInner::TimeoutNotifyApp(int32_t pid, int32_t uid,
#else
KillFaultApp(pid, bundleName, faultData, isNeedExit);
#endif
if (faultData.faultType == FaultDataType::APP_FREEZE) {
if (faultData.faultType == FaultDataType::APP_FREEZE || faultData.faultType == FaultDataType::BACKGROUND_WARNING) {
AppfreezeManager::AppInfo info = {
.pid = pid,
.uid = uid,
@@ -7589,7 +7589,8 @@ int32_t AppMgrServiceInner::TransformedNotifyAppFault(const AppFaultDataBySA &fa
std::to_string(pid) + "-" + std::to_string(SystemTimeMillisecond());
}
const int64_t timeout = 1000;
if (faultData.faultType == FaultDataType::APP_FREEZE) {
if (faultData.faultType == FaultDataType::APP_FREEZE ||
faultData.faultType == FaultDataType::BACKGROUND_WARNING) {
if (!AppExecFwk::AppfreezeManager::GetInstance()->IsHandleAppfreeze(bundleName) || record->IsDebugging()) {
return ERR_OK;
}
@@ -7708,6 +7709,9 @@ std::string AppMgrServiceInner::FaultTypeToString(AppExecFwk::FaultDataType type
case AppExecFwk::FaultDataType::RESOURCE_CONTROL:
typeStr = "RESOURCE_CONTROL";
break;
case AppExecFwk::FaultDataType::BACKGROUND_WARNING:
typeStr = "BACKGROUND_WARNING";
break;
default:
break;
}
@@ -436,5 +436,24 @@ HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_GetFirstLine_001, TestSize.L
appfreezeManager->GetFirstLine("/data/log/test");
EXPECT_TRUE(appfreezeManager != nullptr);
}
/**
* @tc.number: AppfreezeManagerTest_CheckAppfreezeHappend_001
* @tc.desc: add testcase
* @tc.type: FUNC
*/
HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_CheckAppfreezeHappend_001, TestSize.Level1)
{
bool ret = appfreezeManager->CheckAppfreezeHappend(getpid(), "CheckAppfreezeHappend");
EXPECT_EQ(ret, false);
ret = appfreezeManager->CheckAppfreezeHappend(getpid(), "BUSSINESS_THREAD_BLOCK_3S");
EXPECT_EQ(ret, false);
ret = appfreezeManager->CheckAppfreezeHappend(getpid(), "BUSSINESS_THREAD_BLOCK_6S");
EXPECT_EQ(ret, true);
appfreezeManager->CheckAppfreezeHappend(getpid(), "LIFECYCLE_TIMEOUT");
appfreezeManager->CheckAppfreezeHappend(getpid(), "THREAD_BLOCK_6S");
appfreezeManager->CheckAppfreezeHappend(getpid(), "APP_INPUT_BLOCK");
appfreezeManager->CheckAppfreezeHappend(getpid(), "THREAD_BLOCK_3S");
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -539,7 +539,6 @@ HWTEST_F(WatchdogTest, WatchdogTest_SetHiTraceChainId_001, TestSize.Level1)
HWTEST_F(WatchdogTest, WatchdogTest_CheckBgThread_000, TestSize.Level1)
{
watchdog_->isInBackground_.store(true);
watchdog_->bundleName_ = "com.ohos.sceneboard";
watchdog_->lastWatchTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::
system_clock::now().time_since_epoch()).count() - 3000; // 3000: test value
int count = 5; // 5: test value