From da4fcd0ad763e637a7d8e942f7e9661e6b91531a Mon Sep 17 00:00:00 2001 From: hhl Date: Sat, 30 Aug 2025 15:52:37 +0800 Subject: [PATCH] update sample stack Signed-off-by: hhl --- ability_runtime.gni | 1 + frameworks/native/appkit/BUILD.gn | 5 + .../native/appkit/dfr/appfreeze_inner.cpp | 57 ++- frameworks/native/appkit/dfr/watchdog.cpp | 1 + interfaces/inner_api/app_manager/BUILD.gn | 7 + .../app_manager/include/appmgr/fault_data.h | 9 + .../app_manager/src/appmgr/fault_data.cpp | 14 + .../kits/native/appkit/dfr/appfreeze_inner.h | 9 +- .../include/appfreeze_cpu_freq_manager.h | 33 +- .../appdfr/include/appfreeze_event_report.h | 61 +++ .../appdfr/include/appfreeze_fault_data.h | 39 ++ services/appdfr/include/appfreeze_manager.h | 12 +- services/appdfr/include/cpu_data_processor.h | 37 +- .../{appfreeze_data.h => cpu_sys_config.h} | 33 +- .../appdfr/src/appfreeze_cpu_freq_manager.cpp | 376 ++++++++--------- .../appdfr/src/appfreeze_event_report.cpp | 122 ++++++ services/appdfr/src/appfreeze_fault_data.cpp | 55 +++ services/appdfr/src/appfreeze_manager.cpp | 159 ++++---- services/appdfr/src/cpu_data_processor.cpp | 17 +- services/appdfr/src/cpu_sys_config.cpp | 65 +++ services/appmgr/BUILD.gn | 5 + services/appmgr/src/app_mgr_service_inner.cpp | 12 + test/unittest/dfr_test/BUILD.gn | 2 + .../appfreeze_cpu_freq_manager_test.cpp | 165 +++++--- .../appfreeze_event_report_test/BUILD.gn | 46 +++ .../appfreeze_event_report_test.cpp | 381 ++++++++++++++++++ .../dfr_test/appfreeze_inner_test/BUILD.gn | 6 + .../appfreeze_inner_test.cpp | 24 ++ .../dfr_test/appfreeze_manager_test/BUILD.gn | 4 + .../appfreeze_manager_test.cpp | 82 +++- .../dfr_test/appfreeze_state_test/BUILD.gn | 1 + .../cpu_data_processor_test.cpp | 53 +-- .../dfr_test/cpu_sys_config_test/BUILD.gn | 45 +++ .../cpu_sys_config_test.cpp | 209 ++++++++++ test/unittest/fault_data/BUILD.gn | 5 + test/unittest/fault_data/fault_data_test.cpp | 37 ++ 36 files changed, 1708 insertions(+), 481 deletions(-) create mode 100644 services/appdfr/include/appfreeze_event_report.h create mode 100644 services/appdfr/include/appfreeze_fault_data.h rename services/appdfr/include/{appfreeze_data.h => cpu_sys_config.h} (59%) create mode 100644 services/appdfr/src/appfreeze_event_report.cpp create mode 100644 services/appdfr/src/appfreeze_fault_data.cpp create mode 100644 services/appdfr/src/cpu_sys_config.cpp create mode 100644 test/unittest/dfr_test/appfreeze_event_report_test/BUILD.gn create mode 100644 test/unittest/dfr_test/appfreeze_event_report_test/appfreeze_event_report_test.cpp create mode 100644 test/unittest/dfr_test/cpu_sys_config_test/BUILD.gn create mode 100644 test/unittest/dfr_test/cpu_sys_config_test/cpu_sys_config_test.cpp diff --git a/ability_runtime.gni b/ability_runtime.gni index 44e557da33d..1005cdc933d 100644 --- a/ability_runtime.gni +++ b/ability_runtime.gni @@ -126,6 +126,7 @@ declare_args() { ability_runtime_hiperf_enable = true ability_runtime_screenlock_enable = true ability_runtime_udmf_enable = true + ability_runtime_appfreeze_fault_data_enable = true if (!defined(global_parts_info) || defined(global_parts_info.account_os_account)) { diff --git a/frameworks/native/appkit/BUILD.gn b/frameworks/native/appkit/BUILD.gn index c75d32c058e..022b09972b0 100644 --- a/frameworks/native/appkit/BUILD.gn +++ b/frameworks/native/appkit/BUILD.gn @@ -179,6 +179,7 @@ ohos_shared_library("appkit_native") { "${ability_runtime_path}/utils/global/freeze:freeze_util", "${ability_runtime_services_path}/common:app_util", "${ability_runtime_services_path}/common:event_report", + "${ability_runtime_services_path}/common:task_handler_wrap", ] external_deps = [ @@ -327,6 +328,10 @@ ohos_shared_library("appkit_native") { defines += [ "ABILITY_RUNTIME_HITRACE_ENABLE" ] } + if (ability_runtime_appfreeze_fault_data_enable) { + defines += [ "ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE" ] + } + cflags_cc = [] if (os_dlp_part_enabled) { cflags_cc += [ "-DWITH_DLP" ] diff --git a/frameworks/native/appkit/dfr/appfreeze_inner.cpp b/frameworks/native/appkit/dfr/appfreeze_inner.cpp index 4b66b4a2109..f23d94396a0 100644 --- a/frameworks/native/appkit/dfr/appfreeze_inner.cpp +++ b/frameworks/native/appkit/dfr/appfreeze_inner.cpp @@ -39,13 +39,20 @@ namespace { constexpr int32_t HALF_DURATION = 3000; constexpr int32_t HALF_INTERVAL = 300; const bool BETA_VERSION = OHOS::system::GetParameter("const.logsystem.versiontype", "unknown") == "beta"; +static constexpr const char *const IN_FOREGROUND = "Yes"; +static constexpr const char *const IN_BACKGROUND = "No"; +constexpr int32_t APPFREEZE_INNER_TASKWORKER_NUM = 1; } std::weak_ptr AppfreezeInner::appMainHandler_; std::shared_ptr AppfreezeInner::instance_ = nullptr; std::mutex AppfreezeInner::singletonMutex_; AppfreezeInner::AppfreezeInner() -{} +{ + appfreezeInnerTaskHandler_ = AAFwk::TaskHandlerWrap::CreateConcurrentQueueHandler( + "app_freeze_inner_task_queue", APPFREEZE_INNER_TASKWORKER_NUM, AAFwk::TaskQoS::USER_INITIATED); + appfreezeInnerTaskHandler_->SetPrintTaskLog(true); +} AppfreezeInner::~AppfreezeInner() {} @@ -151,6 +158,9 @@ void AppfreezeInner::AppfreezeHandleOverReportCount(bool isSixSecondEvent) if (isSixSecondEvent) { faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_6S; faultData.procStatm = GetProcStatm(pid); +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + faultData.freezeData.isInForeground = GetAppInForeground() ? IN_FOREGROUND : IN_BACKGROUND; +#endif } else { if (!BETA_VERSION) { int32_t ret = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AAFWK, "HIVIEW_HALF_FREEZE_LOG", @@ -159,6 +169,7 @@ void AppfreezeInner::AppfreezeHandleOverReportCount(bool isSixSecondEvent) " ret:%{public}d", pid, ret); } faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_3S; + EnableFreezeSample(faultData.errorObject.name); } if (!IsHandleAppfreeze()) { NotifyANR(faultData); @@ -170,18 +181,31 @@ void AppfreezeInner::AppfreezeHandleOverReportCount(bool isSixSecondEvent) return; } +std::string AppfreezeInner::EnableFreezeSample(const std::string& eventName) +{ + std::string outFile; + if (eventName == AppFreezeType::THREAD_BLOCK_3S || eventName == AppFreezeType::LIFECYCLE_HALF_TIMEOUT) { + OHOS::HiviewDFX::Watchdog::GetInstance().StartSample(HALF_DURATION, HALF_INTERVAL, outFile); + TAG_LOGI(AAFwkTag::APPDFR, "sample freeze stack start, eventName:%{public}s outFile:%{public}s", + eventName.c_str(), outFile.c_str()); + } + return outFile; +} + int AppfreezeInner::AppfreezeHandle(const FaultData& faultData, bool onlyMainThread) { if (!IsHandleAppfreeze()) { NotifyANR(faultData); return -1; } - auto reportFreeze = [faultData, onlyMainThread]() { + std::string eventName = faultData.errorObject.name; + std::string outFile = EnableFreezeSample(eventName); + auto reportFreeze = [faultData, onlyMainThread, outFile]() { if (faultData.errorObject.name == "") { TAG_LOGE(AAFwkTag::APPDFR, "null name"); return; } - AppExecFwk::AppfreezeInner::GetInstance()->AcquireStack(faultData, onlyMainThread); + AppExecFwk::AppfreezeInner::GetInstance()->AcquireStack(faultData, onlyMainThread, outFile); }; { @@ -190,8 +214,8 @@ int AppfreezeInner::AppfreezeHandle(const FaultData& faultData, bool onlyMainThr constexpr int HANDLING_MIN_SIZE = 1; if (handlinglist_.size() <= HANDLING_MIN_SIZE) { TAG_LOGW(AAFwkTag::APPDFR, "submit reportAppFreeze, eventName:%{public}s, startTime:%{public}s\n", - faultData.errorObject.name.c_str(), AbilityRuntime::TimeUtil::DefaultCurrentTimeStr().c_str()); - ffrt::submit(reportFreeze, {}, {}, ffrt::task_attr().name("reportAppFreeze")); + eventName.c_str(), AbilityRuntime::TimeUtil::DefaultCurrentTimeStr().c_str()); + appfreezeInnerTaskHandler_->SubmitTask(reportFreeze, "reportFreeze"); } } return 0; @@ -207,7 +231,7 @@ bool AppfreezeInner::IsExitApp(const std::string& name) return false; } -int AppfreezeInner::AcquireStack(const FaultData& info, bool onlyMainThread) +int AppfreezeInner::AcquireStack(const FaultData& info, bool onlyMainThread, const std::string& outFile) { HITRACE_METER_FMT(HITRACE_TAG_APP, "AppfreezeInner::AcquireStack name:%s", info.errorObject.name.c_str()); std::string msgContent; @@ -237,9 +261,12 @@ int AppfreezeInner::AcquireStack(const FaultData& info, bool onlyMainThread) faultData.timeoutMarkers = it->timeoutMarkers; faultData.eventId = it->eventId; faultData.needKillProcess = it->needKillProcess; - faultData.appfreezeInfo = it->appfreezeInfo; + faultData.appfreezeInfo = outFile; faultData.appRunningUniqueId = it->appRunningUniqueId; faultData.procStatm = it->procStatm; +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + faultData.freezeData = it->freezeData; +#endif ChangeFaultDateInfo(faultData, msgContent); } return 0; @@ -262,6 +289,9 @@ void AppfreezeInner::ThreadBlock(std::atomic_bool& isSixSecondEvent) isSixSecondEvent.store(false); #endif faultData.procStatm = GetProcStatm(pid); +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + faultData.freezeData.isInForeground = GetAppInForeground() ? IN_FOREGROUND : IN_BACKGROUND; +#endif } else { if (!BETA_VERSION) { int32_t ret = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AAFWK, "HIVIEW_HALF_FREEZE_LOG", @@ -271,9 +301,6 @@ void AppfreezeInner::ThreadBlock(std::atomic_bool& isSixSecondEvent) } faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_3S; isSixSecondEvent.store(true); - std::string outFile; - OHOS::HiviewDFX::Watchdog::GetInstance().StartSample(HALF_DURATION, HALF_INTERVAL, outFile); - faultData.appfreezeInfo = outFile; } if (!IsHandleAppfreeze()) { @@ -317,6 +344,16 @@ void AppfreezeInner::SetAppDebug(bool isAppDebug) isAppDebug_ = isAppDebug; } +void AppfreezeInner::SetAppInForeground(bool isInForeground) +{ + isInForeground_ = isInForeground; +} + +bool AppfreezeInner::GetAppInForeground() +{ + return isInForeground_; +} + void MainHandlerDumper::Dump(const std::string &message) { dumpInfo += message; diff --git a/frameworks/native/appkit/dfr/watchdog.cpp b/frameworks/native/appkit/dfr/watchdog.cpp index 5e6a810d735..f0f705c6e77 100644 --- a/frameworks/native/appkit/dfr/watchdog.cpp +++ b/frameworks/native/appkit/dfr/watchdog.cpp @@ -172,6 +172,7 @@ void Watchdog::SetBackgroundStatus(const bool isInBackground) std::unique_lock lock(cvMutex_); isInBackground_.store(isInBackground); OHOS::HiviewDFX::Watchdog::GetInstance().SetForeground(!isInBackground); + AppExecFwk::AppfreezeInner::GetInstance()->SetAppInForeground(!isInBackground); } void Watchdog::AllowReportEvent() diff --git a/interfaces/inner_api/app_manager/BUILD.gn b/interfaces/inner_api/app_manager/BUILD.gn index d83479d9bdf..ae7455049d3 100644 --- a/interfaces/inner_api/app_manager/BUILD.gn +++ b/interfaces/inner_api/app_manager/BUILD.gn @@ -52,10 +52,13 @@ ohos_shared_library("app_manager") { ] sources = [ + "${ability_runtime_services_path}/appdfr/src/appfreeze_event_report.cpp", "${ability_runtime_services_path}/appdfr/src/appfreeze_cpu_freq_manager.cpp", "${ability_runtime_services_path}/appdfr/src/appfreeze_manager.cpp", + "${ability_runtime_services_path}/appdfr/src/appfreeze_fault_data.cpp", "${ability_runtime_services_path}/appdfr/src/appfreeze_util.cpp", "${ability_runtime_services_path}/appdfr/src/cpu_data_processor.cpp", + "${ability_runtime_services_path}/appdfr/src/cpu_sys_config.cpp", "src/appmgr/ability_controller_proxy.cpp", "src/appmgr/ability_controller_stub.cpp", "src/appmgr/ability_debug_response_proxy.cpp", @@ -187,6 +190,10 @@ ohos_shared_library("app_manager") { defines += [ "ABILITY_RUNTIME_HITRACE_ENABLE" ] } + if (ability_runtime_appfreeze_fault_data_enable) { + defines += [ "ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE" ] + } + innerapi_tags = [ "platformsdk" ] subsystem_name = "ability" part_name = "ability_runtime" diff --git a/interfaces/inner_api/app_manager/include/appmgr/fault_data.h b/interfaces/inner_api/app_manager/include/appmgr/fault_data.h index a9427a266c5..3df2881854f 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/fault_data.h +++ b/interfaces/inner_api/app_manager/include/appmgr/fault_data.h @@ -21,6 +21,9 @@ #include "ierror_observer.h" #include "iremote_object.h" #include "parcel.h" +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE +#include "appfreeze_fault_data.h" +#endif namespace OHOS { namespace AppExecFwk { @@ -79,6 +82,9 @@ struct FaultData : public Parcelable { std::string appfreezeInfo; std::string appRunningUniqueId; std::string procStatm; +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + AppfreezeFaultData freezeData; +#endif }; /** @@ -107,6 +113,9 @@ struct AppFaultDataBySA : public Parcelable { std::string appfreezeInfo; std::string appRunningUniqueId; std::string procStatm; +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + AppfreezeFaultData freezeData; +#endif }; } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/app_manager/src/appmgr/fault_data.cpp b/interfaces/inner_api/app_manager/src/appmgr/fault_data.cpp index 4f4129e1f62..9ed81b18238 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/fault_data.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/fault_data.cpp @@ -87,6 +87,9 @@ bool FaultData::ReadContent(Parcel &parcel) return false; } procStatm = strValue; +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + return freezeData.Unmarshalling(parcel); +#endif return true; } @@ -133,6 +136,10 @@ bool FaultData::WriteContent(Parcel &parcel) const TAG_LOGE(AAFwkTag::APPMGR, "ProcStatm [%{public}s] write string failed.", procStatm.c_str()); return false; } + +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + return freezeData.Marshalling(parcel); +#endif return true; } @@ -273,6 +280,9 @@ bool AppFaultDataBySA::ReadContent(Parcel &parcel) return false; } procStatm = strValue; +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + return freezeData.Unmarshalling(parcel); +#endif return true; } @@ -314,6 +324,10 @@ bool AppFaultDataBySA::WriteContent(Parcel &parcel) const TAG_LOGE(AAFwkTag::APPMGR, "ProcStatm [%{public}s] write string failed.", procStatm.c_str()); return false; } + +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + return freezeData.Marshalling(parcel); +#endif return true; } diff --git a/interfaces/kits/native/appkit/dfr/appfreeze_inner.h b/interfaces/kits/native/appkit/dfr/appfreeze_inner.h index 8b4c04da7c6..7c228b6c259 100644 --- a/interfaces/kits/native/appkit/dfr/appfreeze_inner.h +++ b/interfaces/kits/native/appkit/dfr/appfreeze_inner.h @@ -29,6 +29,7 @@ #include "app_mgr_interface.h" #include "application_impl.h" #include "fault_data.h" +#include "task_handler_wrap.h" namespace OHOS { namespace AppExecFwk { @@ -45,8 +46,10 @@ public: void AppfreezeHandleOverReportCount(bool isSixSecondEvent); void GetMainHandlerDump(std::string& msgContent); int AppfreezeHandle(const FaultData& faultInfo, bool onlyMainThread); - int AcquireStack(const FaultData& faultInfo, bool onlyMainThread); + int AcquireStack(const FaultData& faultInfo, bool onlyMainThread, const std::string& outFile = ""); void SetAppDebug(bool isAppDebug); + void SetAppInForeground(bool isInForeground); + private: static std::weak_ptr appMainHandler_; std::weak_ptr applicationInfo_; @@ -55,12 +58,16 @@ private: bool IsExitApp(const std::string& name); bool IsHandleAppfreeze(); std::string GetProcStatm(int32_t pid); + bool GetAppInForeground(); + std::string EnableFreezeSample(const std::string& eventName); static std::mutex singletonMutex_; static std::shared_ptr instance_; bool isAppDebug_ = false; + bool isInForeground_ = true; std::mutex handlingMutex_; std::list handlinglist_; + std::shared_ptr appfreezeInnerTaskHandler_; }; class MainHandlerDumper : public Dumper { diff --git a/services/appdfr/include/appfreeze_cpu_freq_manager.h b/services/appdfr/include/appfreeze_cpu_freq_manager.h index 347380617c2..f024662d80a 100644 --- a/services/appdfr/include/appfreeze_cpu_freq_manager.h +++ b/services/appdfr/include/appfreeze_cpu_freq_manager.h @@ -17,8 +17,8 @@ #include #include +#include -#include "appfreeze_data.h" #include "cpu_data_processor.h" #include "ffrt.h" #include "singleton.h" @@ -33,32 +33,33 @@ public: ~AppfreezeCpuFreqManager(); static AppfreezeCpuFreqManager &GetInstance(); - bool InitCpuDataProcessor(const std::string &eventType, int32_t pid, int32_t uid, - const std::string &stackPath); - std::string WriteCpuInfoToFile(const std::string &eventType, const std::string &bundleName, - int32_t uid, int32_t pid, const std::string &eventName); + bool InsertCpuDetailInfo(const std::string &type, int32_t pid); + std::string GetCpuInfoPath(const std::string &type, const std::string &bundleName, + int32_t uid, int32_t pid); private: - void ClearOldCpuData(uint64_t curTime); - bool IsSkipTask(uint64_t curTime, const std::string &key, int32_t pid); - bool ReadCpuDataByNum(int32_t num, std::vector& parseDatas, TotalTime& totalTime); + bool RemoveOldInfo(); + CpuDataProcessor GetCpuDetailInfo(int32_t pid); + bool GetInfoByCpuCount(int32_t num, std::vector& parseDatas, TotalTime& totalTime); void ParseCpuData(std::vector>& datas, std::vector& totalTimeLists); std::string GetCpuStr(int code, std::vector& freqPairs, float percentage); - bool GetCpuTotalValue(size_t i, std::vector totalTimeList, - std::vector blockTotalTimeList, TotalTime& totalTime); + bool GetCpuTotalValue(size_t i, const std::vector& totalTimeList, + const std::vector& blockTotalTimeList, TotalTime& totalTime); uint64_t GetProcessCpuTime(int32_t pid); uint64_t GetDeviceRuntime(); - std::string GetStartTime(uint64_t start); uint64_t GetAppCpuTime(int32_t pid); double GetOptimalCpuTime(int32_t pid); + std::string GetTimeStampStr(uint64_t start); std::string GetStaticInfoHead(); - std::string GetStaticInfo(int32_t pid, CpuStartTime cpuStartTime); - std::string GetCpuInfoContent(const std::vector> &handlingHalfCpuData, - const std::vector &totalTimeList); + std::string GetConsumeTimeInfo(int32_t pid, CpuConsumeTime warnTimes, CpuConsumeTime blockTimes); + std::string GetCpuInfoContent(const std::vector &warnTotalTimeList, + const std::vector> &warnCpuDetailInfo, + const std::vector &blockTotalTimeList, + const std::vector> &blockCpuDetailInfo); bool IsContainHalfData(const std::string &key, CpuDataProcessor &cpuData, int32_t pid); - void WriteDfxLogToFile(const std::string &filePath, const std::string &bundleName); + std::string GetFreezeLogHead(const std::string &bundleName); + uint64_t GetInterval(uint64_t warnTime, uint64_t blockTime); - static std::shared_ptr instance_; static ffrt::mutex freezeInfoMutex_; static int cpuCount_; static std::map cpuInfoMap_; diff --git a/services/appdfr/include/appfreeze_event_report.h b/services/appdfr/include/appfreeze_event_report.h new file mode 100644 index 00000000000..9302abe2527 --- /dev/null +++ b/services/appdfr/include/appfreeze_event_report.h @@ -0,0 +1,61 @@ +/* + * 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_APPFREEZE_EVENT_REPORT_H +#define OHOS_ABILITY_RUNTIME_APPFREEZE_EVENT_REPORT_H + +#include + +#include "hisysevent.h" + +using HiSysEventType = OHOS::HiviewDFX::HiSysEvent::EventType; +using HiSysEvent = OHOS::HiviewDFX::HiSysEvent; + +namespace OHOS { +namespace AppExecFwk { +struct AppfreezeEventInfo { + int tid = 0; + int pid = 0; + int uid = 0; + int eventId = -1; + std::string bundleName; + std::string processName; + std::string binderInfo; + std::string freezeMemory; + std::string appRunningUniqueId; + std::string errorStack; + std::string errorName; + std::string errorMessage; + std::string freezeInfoFile; + std::string hitraceInfo; + std::string foregroundState; +}; + +class AppfreezeEventReport { +public: + static int SendAppfreezeEvent(const std::string &eventName, HiSysEventType type, + const AppfreezeEventInfo &eventInfo); + +private: + static int LogAppInputBlockEvent(const std::string &name, HiSysEventType type, + const AppfreezeEventInfo &eventInfo); + static int LogThreadBlockEvent(const std::string &name, HiSysEventType type, + const AppfreezeEventInfo &eventInfo); + static int LogGeneralEvent(const std::string &name, HiSysEventType type, + const AppfreezeEventInfo &eventInfo); +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_APPFREEZE_EVENT_REPORT_H diff --git a/services/appdfr/include/appfreeze_fault_data.h b/services/appdfr/include/appfreeze_fault_data.h new file mode 100644 index 00000000000..12d8850df66 --- /dev/null +++ b/services/appdfr/include/appfreeze_fault_data.h @@ -0,0 +1,39 @@ +/* + * 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_APPFREEZE_FAULT_DATA_H +#define OHOS_ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_H + +#include + +#include "parcel.h" + +namespace OHOS { +namespace AppExecFwk { +/** + * @struct AppfreezeFaultData + * AppfreezeFaultData is used to save information about faultdata. + */ +struct AppfreezeFaultData : public Parcelable { + virtual bool Marshalling(Parcel &parcel) const override; + static AppfreezeFaultData *Unmarshalling(Parcel &parcel); + bool ReadFromParcel(Parcel &parcel); + + // params + std::string isInForeground; +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_H \ No newline at end of file diff --git a/services/appdfr/include/appfreeze_manager.h b/services/appdfr/include/appfreeze_manager.h index c7e6c10c033..6a7194d5802 100644 --- a/services/appdfr/include/appfreeze_manager.h +++ b/services/appdfr/include/appfreeze_manager.h @@ -88,6 +88,7 @@ public: void RemoveDeathProcess(std::string bundleName); void ResetAppfreezeState(int32_t pid, const std::string& bundleName); bool IsValidFreezeFilter(int32_t pid, const std::string& bundleName); + void InitWarningCpuInfo(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo); private: struct PeerBinderInfo { @@ -109,13 +110,6 @@ private: int layer; }; - struct HitraceInfo { - std::string hiTraceChainId; - std::string spanId; - std::string pspanId; - std::string traceFlag; - }; - AppfreezeManager& operator=(const AppfreezeManager&) = delete; AppfreezeManager(const AppfreezeManager&) = delete; std::map> BinderParser(std::ifstream& fin, std::string& stack, @@ -135,7 +129,7 @@ private: std::string CatcherStacktrace(int pid, const std::string& stack) const; FaultData GetFaultNotifyData(const FaultData& faultData, int pid); int AcquireStack(const FaultData& faultData, const AppInfo& appInfo, const std::string& memoryContent); - std::string ReportAppfreezeCpuInfo(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo); + std::string GetAppfreezeInfoPath(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo); int NotifyANR(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo, const std::string& binderInfo, const std::string& memoryContent); int64_t GetFreezeCurrentTime(); @@ -146,7 +140,7 @@ private: void CollectFreezeSysMemory(std::string& memoryContent); int MergeNotifyInfo(FaultData& faultNotifyData, const AppfreezeManager::AppInfo& appInfo); std::string ParseDecToHex(uint64_t id); - bool GetHitraceId(HitraceInfo& info); + std::string GetHitraceInfo(); void PerfStart(std::string eventName); std::string GetFirstLine(const std::string &path); diff --git a/services/appdfr/include/cpu_data_processor.h b/services/appdfr/include/cpu_data_processor.h index a1e15797c8d..03db866cfc7 100644 --- a/services/appdfr/include/cpu_data_processor.h +++ b/services/appdfr/include/cpu_data_processor.h @@ -18,29 +18,48 @@ #include #include -#include "appfreeze_data.h" - namespace OHOS { namespace AppExecFwk { +struct CpuFreqData { + uint64_t frequency; + uint64_t runningTime; +}; + +struct FrequencyPair { + uint64_t frequency; + float percentage; +}; + +struct TotalTime { + uint64_t totalRunningTime; + uint64_t totalCpuTime; +}; + +struct CpuConsumeTime { + double optimalCpuTime; + uint64_t cpuFaultTime; + uint64_t processCpuTime; + uint64_t deviceRunTime; + uint64_t cpuTime; +}; + class CpuDataProcessor { public: CpuDataProcessor() {}; CpuDataProcessor(const std::vector> &cpuData, - const std::vector &totalTimeList, CpuStartTime cpuStartTime, - const std::string &stackPath, int32_t pid); + const std::vector &totalTimeList, CpuConsumeTime cpuStartTime, + int32_t pid); ~CpuDataProcessor() = default; - std::vector> GetHandlingHalfCpuData() const; + std::vector> GetCpuDetailData() const; std::vector GetTotalTimeList() const; - CpuStartTime GetCpuStartTime() const; - std::string GetStackPath() const; + CpuConsumeTime GetCpuConsumeTime() const; int32_t GetPid() const; private: std::vector> handlingHalfCpuData_; std::vector totalTimeList_; - CpuStartTime cpuStartTime_ {}; - std::string stackPath_; + CpuConsumeTime cpuConsumeTime_ {}; int32_t pid_ = 0; }; } // namespace AppExecFwk diff --git a/services/appdfr/include/appfreeze_data.h b/services/appdfr/include/cpu_sys_config.h similarity index 59% rename from services/appdfr/include/appfreeze_data.h rename to services/appdfr/include/cpu_sys_config.h index 85c8f95edaf..aea8786d3c5 100644 --- a/services/appdfr/include/appfreeze_data.h +++ b/services/appdfr/include/cpu_sys_config.h @@ -12,32 +12,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef OHOS_ABILITY_RUNTIME_APPFREEZE_DATA_H -#define OHOS_ABILITY_RUNTIME_APPFREEZE_DATA_H +#ifndef OHOS_ABILITY_RUNTIME_CPU_SYS_CONFIG_H +#define OHOS_ABILITY_RUNTIME_CPU_SYS_CONFIG_H -#include +#include namespace OHOS { namespace AppExecFwk { -struct CpuFreqData { - uint64_t frequency; - uint64_t runningTime; -}; - -struct FrequencyPair { - uint64_t frequency; - float percentage; -}; - -struct TotalTime { - uint64_t totalRunningTime; - uint64_t totalCpuTime; -}; +class CpuSysConfig { +public: + CpuSysConfig(); + ~CpuSysConfig(); -struct CpuStartTime { - uint64_t halfStartTime; - uint64_t optimalCpuStartTime; + static std::string GetFreqTimePath(int32_t cpu); + static std::string GetMainThreadRunningTimePath(int32_t pid); + static std::string GetProcRunningTimePath(int32_t pid); + static std::string GetMaxCoreDimpsPath(int32_t maxCpuCount); }; } // namespace AppExecFwk } // namespace OHOS -#endif // OHOS_ABILITY_RUNTIME_APPFREEZE_DATA_H +#endif // OHOS_ABILITY_RUNTIME_CPU_SYS_CONFIG_H diff --git a/services/appdfr/src/appfreeze_cpu_freq_manager.cpp b/services/appdfr/src/appfreeze_cpu_freq_manager.cpp index 5963617483e..f6be7e91aa7 100644 --- a/services/appdfr/src/appfreeze_cpu_freq_manager.cpp +++ b/services/appdfr/src/appfreeze_cpu_freq_manager.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -29,9 +30,10 @@ #include "string_ex.h" #include "hilog_tag_wrapper.h" #include "time_util.h" -#include "appfreeze_util.h" #include "dfx_define.h" -#include "fault_data.h" + +#include "appfreeze_util.h" +#include "cpu_sys_config.h" namespace OHOS { namespace AppExecFwk { @@ -47,18 +49,17 @@ namespace { constexpr const char* const LOG_FILE_HEAD = "Generated by HiviewDFX @OpenHarmony"; constexpr const char* const LOG_FILE_SEP = "==============================================================="; constexpr const char* const LIB_THREAD_CPU_LOAD_PATH = "libucollection_utility.z.so"; - constexpr int TIME_LIMIT = 6000; // 6s + constexpr int TIME_LIMIT = 10000; // 10s constexpr size_t MAX_CPU_MAP_SIZE = 10; constexpr uint32_t DEFAULT_CPU_SIZE = 1; constexpr const char* const CPU_INFO_PREFIX = "cpu-info-"; } -std::shared_ptr AppfreezeCpuFreqManager::instance_ = nullptr; ffrt::mutex AppfreezeCpuFreqManager::freezeInfoMutex_; int AppfreezeCpuFreqManager::cpuCount_ = 0; std::map AppfreezeCpuFreqManager::cpuInfoMap_; -typedef double (*GetThreadCpuload)(int); +typedef double (*GetThreadCpuLoad)(int); AppfreezeCpuFreqManager::AppfreezeCpuFreqManager() { @@ -75,110 +76,73 @@ AppfreezeCpuFreqManager &AppfreezeCpuFreqManager::GetInstance() return instance; } -void AppfreezeCpuFreqManager::ClearOldCpuData(uint64_t curTime) +bool AppfreezeCpuFreqManager::RemoveOldInfo() { - std::lock_guard lock(freezeInfoMutex_); if (cpuInfoMap_.size() < MAX_CPU_MAP_SIZE) { - return ; + return true; } + int removeCount = 0; + uint64_t curTime = AppfreezeUtil::GetMilliseconds(); for (auto it = cpuInfoMap_.begin(); it != cpuInfoMap_.end();) { - auto diff = curTime - it->second.GetCpuStartTime().halfStartTime; - if (diff > TIME_LIMIT || diff < 0) { + auto interval = curTime - it->second.GetCpuConsumeTime().cpuFaultTime; + if (interval > TIME_LIMIT || interval < 0) { it = cpuInfoMap_.erase(it); + removeCount++; } else { ++it; } } + TAG_LOGI(AAFwkTag::APPDFR, "reomve old tasks count: %{public}d, " + "current tasks count: %{public}zu", removeCount, cpuInfoMap_.size()); + return removeCount != 0; } -bool AppfreezeCpuFreqManager::IsSkipTask(uint64_t curTime, const std::string &key, int32_t pid) +bool AppfreezeCpuFreqManager::InsertCpuDetailInfo(const std::string &type, int32_t pid) { std::lock_guard lock(freezeInfoMutex_); - auto it = cpuInfoMap_.find(key); - if (it != cpuInfoMap_.end()) { - auto diff = curTime - it->second.GetCpuStartTime().halfStartTime; - if (diff > TIME_LIMIT || diff < 0) { - it = cpuInfoMap_.erase(it); - } else { - TAG_LOGW(AAFwkTag::APPDFR, "Skip this task. " - "The task of the current process is already being executed, pid:%{public}d", pid); - return true; - } - } - if (cpuInfoMap_.size() >= MAX_CPU_MAP_SIZE) { - TAG_LOGW(AAFwkTag::APPDFR, "Skip this task. " - "The current queue can only execute up to %{public}zu tasks", MAX_CPU_MAP_SIZE); - return true; - } - return false; -} - -bool AppfreezeCpuFreqManager::InitCpuDataProcessor(const std::string &eventType, - int32_t pid, int32_t uid, const std::string &stackPath) -{ - uint64_t curTime = AppfreezeUtil::GetMilliseconds(); - ClearOldCpuData(curTime); - std::string key = eventType + std::to_string(uid); - if (IsSkipTask(curTime, key, pid)) { + auto it = cpuInfoMap_.find(type); + if (it == cpuInfoMap_.end() && !RemoveOldInfo()) { return false; } - CpuStartTime cpuStartTime = { - .halfStartTime = curTime, - .optimalCpuStartTime = GetOptimalCpuTime(pid), - }; - std::vector> cpuData; - std::vector totalTimeList; - ParseCpuData(cpuData, totalTimeList); - CpuDataProcessor data(cpuData, totalTimeList, cpuStartTime, stackPath, pid); - { - std::lock_guard lock(freezeInfoMutex_); - cpuInfoMap_[key] = data; - } - TAG_LOGD(AAFwkTag::APPDFR, "init success. eventType: %{public}s path: %{public}s " - "halfStartTime: %{public}" PRIu64", optimalCpuStartTime: %{public}" PRIu64".", - eventType.c_str(), stackPath.c_str(), cpuStartTime.halfStartTime, - cpuStartTime.optimalCpuStartTime); + cpuInfoMap_[type] = std::move(GetCpuDetailInfo(pid)); return true; } -void AppfreezeCpuFreqManager::ParseCpuData(std::vector>& datas, - std::vector& totalTimeLists) +CpuDataProcessor AppfreezeCpuFreqManager::GetCpuDetailInfo(int32_t pid) { - TAG_LOGD(AAFwkTag::APPDFR, "ParseCpuData start time: %{public}s", - AbilityRuntime::TimeUtil::DefaultCurrentTimeStr().c_str()); - std::string tmp = "start time: " + AbilityRuntime::TimeUtil::DefaultCurrentTimeStr(); - TAG_LOGW(AAFwkTag::APPDFR, "ParseCpuData called, %{public}s", tmp.c_str()); + std::vector> cpuDetailInfo{}; + std::vector totalTimeCpuLists{}; for (int32_t i = 0; i < cpuCount_; ++i) { - std::vector parseDatas; - TotalTime totalTime{}; - if (ReadCpuDataByNum(i, parseDatas, totalTime)) { - datas.push_back(parseDatas); - totalTimeLists.push_back(totalTime); + std::vector datas{}; + TotalTime totalCpuTime{}; + if (GetInfoByCpuCount(i, datas, totalCpuTime)) { + cpuDetailInfo.push_back(datas); + totalTimeCpuLists.push_back(totalCpuTime); } } - TAG_LOGD(AAFwkTag::APPDFR, "ParseCpuData end time: %{public}s", - AbilityRuntime::TimeUtil::DefaultCurrentTimeStr().c_str()); + CpuConsumeTime cpuConsumeTime = { + .optimalCpuTime = GetOptimalCpuTime(pid), + .cpuFaultTime = AppfreezeUtil::GetMilliseconds(), + .processCpuTime = GetProcessCpuTime(pid), + .deviceRunTime = GetDeviceRuntime(), + .cpuTime = GetAppCpuTime(pid), + }; + CpuDataProcessor data(cpuDetailInfo, totalTimeCpuLists, cpuConsumeTime, pid); + return data; } -bool AppfreezeCpuFreqManager::ReadCpuDataByNum(int32_t num, std::vector& parseDatas, +bool AppfreezeCpuFreqManager::GetInfoByCpuCount(int32_t cpu, std::vector& parseDatas, TotalTime& totalTime) { - TAG_LOGD(AAFwkTag::APPDFR, "ReadCpuDataByNum start time: %{public}s", - AbilityRuntime::TimeUtil::DefaultCurrentTimeStr().c_str()); - if (num > cpuCount_) { - TAG_LOGE(AAFwkTag::APPDFR, "Read cpu info failed, num:%{public}d, cpuCount:%{public}d", - num, cpuCount_); + std::string cpuFreqFile = CpuSysConfig::GetFreqTimePath(cpu); + std::ifstream fin(cpuFreqFile); + if (!fin.is_open()) { + TAG_LOGE(AAFwkTag::APPDFR, "Read cpu time failed, cpuFreqFile:%{public}s, errno:%{public}d", + cpuFreqFile.c_str(), errno); return false; } - std::string cpuFreqPath = "/sys/devices/system/cpu/cpu" + std::to_string(num) + "/power/time_in_state"; - std::string data; - if (!LoadStringFromFile(cpuFreqPath, data)) { - TAG_LOGE(AAFwkTag::APPDFR, "Read cpu time failed, cpuFreqPath:%{public}s", cpuFreqPath.c_str()); - return false; - } - std::istringstream iss(data); std::string line; - while (std::getline(iss, line)) { + while (getline(fin, line)) { if (line.empty()) { continue; } @@ -222,8 +186,8 @@ std::string AppfreezeCpuFreqManager::GetCpuStr(int code, std::vector totalTimeList, - std::vector blockTotalTimeList, TotalTime& totalTime) +bool AppfreezeCpuFreqManager::GetCpuTotalValue(size_t i, const std::vector& totalTimeList, + const std::vector& blockTotalTimeList, TotalTime& totalTime) { if (totalTimeList.size() <= i || totalTimeList.size() != blockTotalTimeList.size()) { TAG_LOGE(AAFwkTag::APPDFR, "index:%{public}zu, halfTotal size:%{public}zu, " @@ -243,48 +207,46 @@ bool AppfreezeCpuFreqManager::GetCpuTotalValue(size_t i, std::vector return true; } -std::string AppfreezeCpuFreqManager::GetCpuInfoContent( - const std::vector> &handlingHalfCpuData, const std::vector &totalTimeList) +std::string AppfreezeCpuFreqManager::GetCpuInfoContent(const std::vector &warnTotalTimeList, + const std::vector> &warnCpuDetailInfo, + const std::vector &blockTotalTimeList, const std::vector> &blockCpuDetailInfo) { - if (handlingHalfCpuData.size() == 0 || totalTimeList.size() == 0) { + if (warnTotalTimeList.size() == 0 || warnTotalTimeList.size() == 0) { return ""; } - std::stringstream ss; - ss << "start time:" << AbilityRuntime::TimeUtil::DefaultCurrentTimeStr() << std::endl; - std::vector> blockCpuData; - std::vector blockTotalTimeList; - ParseCpuData(blockCpuData, blockTotalTimeList); - if (handlingHalfCpuData.size() != blockCpuData.size()) { - TAG_LOGE(AAFwkTag::APPDFR, "Half and block have different sizes, halfData:%{public}zu, " - "blockData:%{public}zu", handlingHalfCpuData.size(), blockCpuData.size()); + if (warnTotalTimeList.size() != blockTotalTimeList.size()) { + TAG_LOGE(AAFwkTag::APPDFR, "Warning and block have different sizes, warning size:%{public}zu," + " block size:%{public}zu", warnTotalTimeList.size(), blockTotalTimeList.size()); return ""; } - for (size_t i = 0; i < handlingHalfCpuData.size(); ++i) { - auto halfData = handlingHalfCpuData[i]; - auto blockData = blockCpuData[i]; - if (halfData.size() != blockData.size()) { - TAG_LOGE(AAFwkTag::APPDFR, "Half and block have different sizes, halfData:%{public}zu, " - "blockData:%{public}zu", halfData.size(), blockData.size()); + std::stringstream ss; + ss << "start time:" << AbilityRuntime::TimeUtil::DefaultCurrentTimeStr() << std::endl; + for (size_t i = 0; i < warnCpuDetailInfo.size(); ++i) { + auto warnningData = warnCpuDetailInfo[i]; + auto blockData = blockCpuDetailInfo[i]; + if (warnningData.size() != blockData.size()) { + TAG_LOGE(AAFwkTag::APPDFR, "Warning and block have different sizes, warning size:%{public}zu," + " block size:%{public}zu", warnningData.size(), blockData.size()); return ""; } TotalTime totalTime{}; - if (!GetCpuTotalValue(i, totalTimeList, blockTotalTimeList, totalTime)) { + if (!GetCpuTotalValue(i, warnTotalTimeList, blockTotalTimeList, totalTime)) { return ""; } float percentage = (static_cast(totalTime.totalRunningTime) / static_cast(totalTime.totalCpuTime)) * CPU_PERCENTAGE;; std::vector freqPairs; - for (size_t j = 0; j < halfData.size(); ++j) { + for (size_t j = 0; j < warnningData.size(); ++j) { FrequencyPair pair{}; - uint64_t runningTime = halfData[j].runningTime > blockData[j].runningTime ? - (halfData[j].runningTime - blockData[j].runningTime) : - (blockData[j].runningTime - halfData[j].runningTime); + uint64_t runningTime = warnningData[j].runningTime > blockData[j].runningTime ? + (warnningData[j].runningTime - blockData[j].runningTime) : + (blockData[j].runningTime - warnningData[j].runningTime); pair.percentage = (static_cast(runningTime) / static_cast(totalTime.totalCpuTime)) * CPU_PERCENTAGE; - if (pair.percentage < 1 || halfData[j].frequency != blockData[j].frequency) { + if (pair.percentage < 1 || warnningData[j].frequency != blockData[j].frequency) { continue; } - pair.frequency = halfData[j].frequency / HZ_TO_MHZ; + pair.frequency = warnningData[j].frequency / HZ_TO_MHZ; freqPairs.push_back(pair); } ss << GetCpuStr(i, freqPairs, percentage); @@ -295,17 +257,16 @@ std::string AppfreezeCpuFreqManager::GetCpuInfoContent( uint64_t AppfreezeCpuFreqManager::GetAppCpuTime(int32_t pid) { - if (pid < 0) { + std::string cpuFile = CpuSysConfig::GetMainThreadRunningTimePath(pid); + std::ifstream fin(cpuFile); + if (!fin.is_open()) { + TAG_LOGE(AAFwkTag::APPDFR, "Read cpu info failed, cpuFile:%{public}s, errno:%{public}d", + cpuFile.c_str(), errno); return 0; } - uint64_t cpuTime = 0; - std::string filePath = "/proc/" + std::to_string(pid) + "/task/" + std::to_string(pid) + "/stat"; std::string content; - if (!LoadStringFromFile(filePath, content)) { - TAG_LOGE(AAFwkTag::APPDFR, "Read cpu task stat failed, path:%{public}s", filePath.c_str()); - return cpuTime; - } - if (!content.empty()) { + uint64_t cpuTime = 0; + if (getline(fin, content) && !content.empty()) { std::vector tokens; SplitStr(content, " ", tokens); if (tokens.size() <= START_TIME_SECOND_INDEX) { @@ -322,17 +283,15 @@ uint64_t AppfreezeCpuFreqManager::GetAppCpuTime(int32_t pid) uint64_t AppfreezeCpuFreqManager::GetProcessCpuTime(int32_t pid) { - if (pid < 0) { + std::string processFile = CpuSysConfig::GetProcRunningTimePath(pid); + std::ifstream fin(processFile); + if (!fin.is_open()) { + TAG_LOGE(AAFwkTag::APPDFR, "Read cpu info failed, processFile:%{public}s", processFile.c_str()); return 0; } - std::string statPath = "/proc/" + std::to_string(pid) + "/stat"; std::string content; - if (!LoadStringFromFile(statPath, content)) { - TAG_LOGE(AAFwkTag::APPDFR, "Read cpu stat failed, path:%{public}s", statPath.c_str()); - return 0; - } uint64_t processCpuTime = 0; - if (!content.empty()) { + if (getline(fin, content) && !content.empty()) { std::vector tokens; SplitStr(content, " ", tokens); if (tokens.size() <= START_TIME_SECOND_INDEX) { @@ -349,15 +308,15 @@ uint64_t AppfreezeCpuFreqManager::GetProcessCpuTime(int32_t pid) uint64_t AppfreezeCpuFreqManager::GetDeviceRuntime() { - std::string statPath = AppfreezeUtil::PROC_STAT_PATH; - std::string content; - if (!LoadStringFromFile(statPath, content)) { - TAG_LOGE(AAFwkTag::APPDFR, "Read device run time failed, path:%{public}s", statPath.c_str()); + std::ifstream fin(AppfreezeUtil::PROC_STAT_PATH); + if (!fin.is_open()) { + TAG_LOGE(AAFwkTag::APPDFR, "Read device run time failed, path:%{public}s, errno:%{public}d", + AppfreezeUtil::PROC_STAT_PATH, errno); return 0; } uint64_t deviceRuntime = 0; std::string line; - std::istringstream iss(content); + std::istringstream iss(line); if (std::getline(iss, line) && !line.empty()) { std::vector strings; SplitStr(line, " ", strings); @@ -376,48 +335,48 @@ uint64_t AppfreezeCpuFreqManager::GetDeviceRuntime() double AppfreezeCpuFreqManager::GetOptimalCpuTime(int32_t pid) { int maxCpuCount = cpuCount_ - AppfreezeUtil::CPU_COUNT_SUBTRACT; - if (maxCpuCount <= 0) { - TAG_LOGE(AAFwkTag::APPDFR, "GetOptimalCpuTime failed, maxCpuCount:%{public}d", maxCpuCount); - return -1; + std::string cpuFile = CpuSysConfig::GetMaxCoreDimpsPath(maxCpuCount); + std::ifstream fin(cpuFile); + if (!fin.is_open()) { + TAG_LOGE(AAFwkTag::APPDFR, "Read cpu info failed, cpuFile:%{public}s, errno:%{public}d", + cpuFile.c_str(), errno); + return 0; } - std::string statPath = "/sys/devices/system/cpu/cpu" + std::to_string(maxCpuCount) + "/cpu_capacity"; std::string content; - int ret = -1; - if (!LoadStringFromFile(statPath, content)) { - TAG_LOGE(AAFwkTag::APPDFR, "GetOptimalCpuTime failed, path:%{public}s, errno:%{public}d", - statPath.c_str(), errno); + double ret = 0; + if (getline(fin, content) && content.empty()) { + TAG_LOGE(AAFwkTag::APPDFR, "Read info failed, path:%{public}s", cpuFile.c_str()); return ret; } - if (content.empty()) { - TAG_LOGE(AAFwkTag::APPDFR, "Read info failed, path:%{public}s", statPath.c_str()); + double dmips = static_cast(strtoull(content.c_str(), nullptr, CPU_FREQ_DECIMAL_BASE)); + if (dmips <= 0) { + TAG_LOGE(AAFwkTag::APPDFR, "get dmips %{public}lf failed.", dmips); return ret; } - int32_t dmips = static_cast(strtoull(content.c_str(), nullptr, CPU_FREQ_DECIMAL_BASE)); void* threadFuncHandler = dlopen(LIB_THREAD_CPU_LOAD_PATH, RTLD_LAZY); if (threadFuncHandler == nullptr) { TAG_LOGE(AAFwkTag::APPDFR, "dlopen failed, funcHandler is nullptr."); return ret; } - dlerror(); char* err = nullptr; - auto getThreadCpuload = reinterpret_cast(dlsym(threadFuncHandler, "GetThreadCpuload")); + auto getThreadCpuLoad = reinterpret_cast(dlsym(threadFuncHandler, "GetThreadCpuLoad")); err = dlerror(); if (err != nullptr) { - TAG_LOGE(AAFwkTag::APPDFR, "dlsym GetThreadCpuload func failed. %{public}s", err); - return ret; + TAG_LOGE(AAFwkTag::APPDFR, "dlsym GetThreadCpuLoad func failed. %{public}s", err); + } else { + double optimalCpuTime = getThreadCpuLoad(pid); + if (optimalCpuTime >= 0) { + ret = optimalCpuTime / dmips; + } + TAG_LOGW(AAFwkTag::APPDFR, "dmips %{public}lf optimalCpuTime %{public}lf", dmips, optimalCpuTime); } - double optimalCpuTime = getThreadCpuload(pid); - threadFuncHandler = nullptr; - getThreadCpuload = nullptr; dlclose(threadFuncHandler); - if (dmips <= 0 || optimalCpuTime < 0) { - return ret; - } - TAG_LOGW(AAFwkTag::APPDFR, "dmips %{public}d optimalCpuTime %{public}lf", dmips, optimalCpuTime); - return optimalCpuTime / dmips; + threadFuncHandler = nullptr; + getThreadCpuLoad = nullptr; + return ret; } -std::string AppfreezeCpuFreqManager::GetStartTime(uint64_t start) +std::string AppfreezeCpuFreqManager::GetTimeStampStr(uint64_t start) { const uint32_t placeholder = 3; uint64_t startTime = start / AppfreezeUtil::SEC_TO_MILLISEC; @@ -430,54 +389,63 @@ std::string AppfreezeCpuFreqManager::GetStartTime(uint64_t start) std::string AppfreezeCpuFreqManager::GetStaticInfoHead() { - std::ostringstream staticInfoStr; - staticInfoStr << "#Basic Concepts" << std::endl; - staticInfoStr << "T1: StaticsDuration, EndTime - StartTime." << std::endl; - staticInfoStr << "T2: CpuTime --Time that spend on CPU." << std::endl; - staticInfoStr << "T3: SyncWaitTime --SleepingTime + Runnable Time, etc." << std::endl; - staticInfoStr << "T4: OptimalCpuTime --run the thread at the max Core's max cpu capacity." << std::endl; - staticInfoStr << "T5: SupplyAvailableTime --T2 - T3. Time can be optimized by scheduling." << std::endl; - staticInfoStr << "Equation: T1 = T2 + T3. T2 = T4 = T5." << std::endl; - staticInfoStr << + std::ostringstream timeInfo; + timeInfo << "#Basic Concepts" << std::endl; + timeInfo << "T1: StaticsDuration, EndTime - StartTime." << std::endl; + timeInfo << "T2: CpuTime --Time that spend on CPU." << std::endl; + timeInfo << "T3: SyncWaitTime --SleepingTime + Runnable Time, etc." << std::endl; + timeInfo << "T4: OptimalCpuTime --run the thread at the max Core's max cpu capacity." << std::endl; + timeInfo << "T5: SupplyAvailableTime --T2 - T3. Time can be optimized by scheduling." << std::endl; + timeInfo << "Equation: T1 = T2 + T3. T2 = T4 = T5." << std::endl; + timeInfo << "|-----------------------------------StaticsDuration-----------------------------------|." << std::endl; - staticInfoStr << + timeInfo << "|-------------------------CpuTime----------------------|--------SyncWaitTime----------|." << std::endl; - staticInfoStr << + timeInfo << "|----OptimalCpuTime----|------SupplyAvailableTime------|--------SyncWaitTime----------|." << std::endl; - return staticInfoStr.str(); + return timeInfo.str(); +} + +uint64_t AppfreezeCpuFreqManager::GetInterval(uint64_t warnTime, uint64_t blockTime) +{ + return blockTime >= warnTime ? (blockTime - warnTime) : (warnTime - blockTime); } -std::string AppfreezeCpuFreqManager::GetStaticInfo(int32_t pid, CpuStartTime cpuStartTime) +std::string AppfreezeCpuFreqManager::GetConsumeTimeInfo(int32_t pid, CpuConsumeTime warnTimes, + CpuConsumeTime blockTimes) { - std::ostringstream staticInfoStr; - staticInfoStr << GetStaticInfoHead() << std::endl; - staticInfoStr << "#Basic Statistical Infomation " << std::endl; - staticInfoStr << "ProcessCpuTime: " << GetProcessCpuTime(pid) << " ms" << std::endl; - staticInfoStr << "DeviceRuntime: " << GetDeviceRuntime() << " ms" << std::endl; - staticInfoStr << "Tid: " << pid << std::endl; - staticInfoStr << "StartTime: " << GetStartTime(cpuStartTime.halfStartTime) << std::endl; - staticInfoStr << "EndTime: " << AbilityRuntime::TimeUtil::DefaultCurrentTimeStr() << std::endl; - uint64_t duration = AppfreezeUtil::GetMilliseconds() - cpuStartTime.halfStartTime; - staticInfoStr << "StaticsDuration: " << duration << " ms" << std::endl; - uint64_t cpuTime = GetAppCpuTime(pid); - uint64_t syncWaitTime = duration - cpuTime; - uint64_t optimalCpuTime = GetOptimalCpuTime(pid) - cpuStartTime.optimalCpuStartTime; - uint64_t supplyAvailableTime = duration - optimalCpuTime - syncWaitTime; - staticInfoStr << "CpuTime: " << cpuTime << " ms" << std::endl; - staticInfoStr << "SyncWaitTime: " << syncWaitTime << " ms" << std::endl; - staticInfoStr << "OptimalCpuTime: " << optimalCpuTime << " ms" << std::endl; - staticInfoStr << "SupplyAvailableTime: " << supplyAvailableTime << " ms" << std::endl; - return staticInfoStr.str(); + double optimalCpuTime = GetInterval(warnTimes.optimalCpuTime, blockTimes.optimalCpuTime); + uint64_t processCpuTime = GetInterval(warnTimes.processCpuTime, blockTimes.processCpuTime); + uint64_t deviceRunTime = GetInterval(warnTimes.deviceRunTime, blockTimes.deviceRunTime); + uint64_t cpuTime = GetInterval(warnTimes.cpuTime, blockTimes.cpuTime); + uint64_t duration = GetInterval(warnTimes.cpuFaultTime, blockTimes.cpuFaultTime); + uint64_t syncWaitTime = duration > cpuTime ? (duration - cpuTime) : 0; + double supplyAvailableTime = cpuTime - optimalCpuTime; + + std::ostringstream timeInfo; + timeInfo << GetStaticInfoHead() << std::endl; + timeInfo << "#Basic Statistical Infomation " << std::endl; + timeInfo << "ProcessCpuTime: " << processCpuTime << " ms" << std::endl; + timeInfo << "DeviceRuntime: " << deviceRunTime << " ms" << std::endl; + timeInfo << "Tid: " << pid << std::endl; + timeInfo << "StartTime: " << GetTimeStampStr(warnTimes.cpuFaultTime) << std::endl; + timeInfo << "EndTime: " << GetTimeStampStr(blockTimes.cpuFaultTime) << std::endl; + timeInfo << "StaticsDuration: " << duration << " ms" << std::endl; + timeInfo << "CpuTime: " << cpuTime << " ms" << std::endl; + timeInfo << "SyncWaitTime: " << syncWaitTime << " ms" << std::endl; + timeInfo << "OptimalCpuTime: " << optimalCpuTime << " ms" << std::endl; + timeInfo << "SupplyAvailableTime: " << supplyAvailableTime << " ms" << std::endl; + return timeInfo.str(); } -void AppfreezeCpuFreqManager::WriteDfxLogToFile(const std::string &filePath, const std::string &bundleName) +std::string AppfreezeCpuFreqManager::GetFreezeLogHead(const std::string &bundleName) { std::stringstream ss; ss << LOG_FILE_HEAD << std::endl; ss << LOG_FILE_SEP << std::endl; ss << "TimeStamp: " << AbilityRuntime::TimeUtil::DefaultCurrentTimeStr() << std::endl; ss << "Module name: " << bundleName << std::endl; - OHOS::SaveStringToFile(filePath, ss.str()); + return ss.str(); } bool AppfreezeCpuFreqManager::IsContainHalfData(const std::string &key, CpuDataProcessor &cpuData, int32_t pid) @@ -493,46 +461,36 @@ bool AppfreezeCpuFreqManager::IsContainHalfData(const std::string &key, CpuDataP TAG_LOGI(AAFwkTag::APPDFR, "Not find current pid:%{public}d, warning pid:%{public}d", pid, warningPid); return false; } - auto diff = AppfreezeUtil::GetMilliseconds() - it->second.GetCpuStartTime().halfStartTime; - if (diff > TIME_LIMIT) { - it = cpuInfoMap_.erase(it); - TAG_LOGI(AAFwkTag::APPDFR, "The last fault occurred more than 6 seconds ago, " - "diff: %{public}" PRIu64", pid: %{public}d.", diff, pid); - return false; - } cpuData = it->second; return true; } -std::string AppfreezeCpuFreqManager::WriteCpuInfoToFile(const std::string &eventType, - const std::string &bundleName, int32_t uid, int32_t pid, const std::string &eventName) +std::string AppfreezeCpuFreqManager::GetCpuInfoPath(const std::string &type, + const std::string &bundleName, int32_t uid, int32_t pid) { - std::string key = eventType + std::to_string(uid); - CpuDataProcessor cpuData; - if (!IsContainHalfData(key, cpuData, pid)) { + CpuDataProcessor warnCpuInfo; + if (!IsContainHalfData(type, warnCpuInfo, pid)) { return ""; } + CpuDataProcessor blockCpuInfo = std::move(GetCpuDetailInfo(pid)); - std::string cpuInfo = GetCpuInfoContent(cpuData.GetHandlingHalfCpuData(), cpuData.GetTotalTimeList()); - if (cpuInfo.empty()) { - return ""; - } std::string fileName = CPU_INFO_PREFIX + std::to_string(uid) + AbilityRuntime::TimeUtil::FormatTime("%Y%m%d%H%M%S"); - std::string filePath = AppfreezeUtil::CreateFile(AppfreezeUtil::EVENTLOG_PATH, fileName); - WriteDfxLogToFile(filePath, bundleName); + std::string logFile = AppfreezeUtil::CreateFile(AppfreezeUtil::EVENTLOG_PATH, fileName); std::ostringstream str; - str << std::endl << GetStaticInfo(pid, cpuData.GetCpuStartTime()); - str << std::endl << "#CpuFreq Usage (usage >=1%)" << std::endl << cpuInfo << std::endl; - std::string path = filePath + "," + cpuData.GetStackPath(); - OHOS::SaveStringToFile(filePath, str.str(), false); + str << GetFreezeLogHead(bundleName) << std::endl; + str << GetConsumeTimeInfo(pid, warnCpuInfo.GetCpuConsumeTime(), blockCpuInfo.GetCpuConsumeTime()) << std::endl; + str << "#CpuFreq Usage (usage >=1%)" << std::endl << GetCpuInfoContent( + warnCpuInfo.GetTotalTimeList(), warnCpuInfo.GetCpuDetailData(), + blockCpuInfo.GetTotalTimeList(), blockCpuInfo.GetCpuDetailData()) << std::endl; + OHOS::SaveStringToFile(logFile, str.str(), false); { std::lock_guard lock(freezeInfoMutex_); - cpuInfoMap_.erase(key); + cpuInfoMap_.erase(type); } - TAG_LOGW(AAFwkTag::APPDFR, "Write CpuInfo to file: %{public}s", path.c_str()); - return path; + TAG_LOGW(AAFwkTag::APPDFR, "write cpu info success, logFile: %{public}s", logFile.c_str()); + return logFile; } } // namespace AppExecFwk } // namespace OHOS diff --git a/services/appdfr/src/appfreeze_event_report.cpp b/services/appdfr/src/appfreeze_event_report.cpp new file mode 100644 index 00000000000..0d0074e55c8 --- /dev/null +++ b/services/appdfr/src/appfreeze_event_report.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022-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 "appfreeze_event_report.h" +#include "hilog_tag_wrapper.h" +#include "hitrace_meter.h" +#include "fault_data.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +// appfreeze event params +constexpr char EVENT_UID[] = "UID"; +constexpr char EVENT_PID[] = "PID"; +constexpr char EVENT_TID[] = "TID"; +constexpr char EVENT_INPUT_ID[] = "INPUT_ID"; +constexpr char EVENT_MESSAGE[] = "MSG"; +constexpr char EVENT_PACKAGE_NAME[] = "PACKAGE_NAME"; +constexpr char EVENT_PROCESS_NAME[] = "PROCESS_NAME"; +constexpr char EVENT_STACK[] = "STACK"; +constexpr char EVENT_BINDER_INFO[] = "BINDER_INFO"; +constexpr char EVENT_APP_RUNNING_UNIQUE_ID[] = "APP_RUNNING_UNIQUE_ID"; +constexpr char EVENT_FREEZE_MEMORY[] = "FREEZE_MEMORY"; +constexpr char EVENT_FREEZE_INFO_PATH[] = "FREEZE_INFO_PATH"; +constexpr char EVENT_TRACE_ID[] = "HITRACE_ID"; +constexpr char EVENT_FOREGROUND[] = "FOREGROUND"; +} + +int AppfreezeEventReport::SendAppfreezeEvent(const std::string &eventName, HiSysEventType type, + const AppfreezeEventInfo &eventInfo) +{ + HITRACE_METER_FMT(HITRACE_TAG_APP, "SendAppfreezeEvent eventName:%{public}s", eventName.c_str()); + int ret = -1; + if (eventName == AppFreezeType::APP_INPUT_BLOCK) { + return LogAppInputBlockEvent(eventName, type, eventInfo); + } + if (eventName == AppFreezeType::THREAD_BLOCK_6S) { + return LogThreadBlockEvent(eventName, type, eventInfo); + } + return LogGeneralEvent(eventName, type, eventInfo); +} + +int AppfreezeEventReport::LogAppInputBlockEvent(const std::string &name, HiSysEventType type, + const AppfreezeEventInfo &eventInfo) +{ + int ret = -1; + ret = HiSysEventWrite( + OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, + name, + type, + EVENT_UID, eventInfo.uid, + EVENT_PID, eventInfo.pid, + EVENT_PACKAGE_NAME, eventInfo.bundleName, + EVENT_PROCESS_NAME, eventInfo.processName, + EVENT_MESSAGE, eventInfo.errorMessage, + EVENT_STACK, eventInfo.errorStack, + EVENT_BINDER_INFO, eventInfo.binderInfo, + EVENT_APP_RUNNING_UNIQUE_ID, eventInfo.appRunningUniqueId, + EVENT_INPUT_ID, eventInfo.eventId, + EVENT_FREEZE_MEMORY, eventInfo.freezeMemory); + return ret; +} + +int AppfreezeEventReport::LogThreadBlockEvent(const std::string &name, HiSysEventType type, + const AppfreezeEventInfo &eventInfo) +{ + int ret = -1; + ret = HiSysEventWrite( + OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, + name, + type, + EVENT_UID, eventInfo.uid, + EVENT_PID, eventInfo.pid, + EVENT_TID, eventInfo.tid, + EVENT_PACKAGE_NAME, eventInfo.bundleName, + EVENT_PROCESS_NAME, eventInfo.processName, + EVENT_MESSAGE, eventInfo.errorMessage, + EVENT_STACK, eventInfo.errorStack, + EVENT_BINDER_INFO, eventInfo.binderInfo, + EVENT_APP_RUNNING_UNIQUE_ID, eventInfo.appRunningUniqueId, + EVENT_FREEZE_MEMORY, eventInfo.freezeMemory, + EVENT_TRACE_ID, eventInfo.hitraceInfo, + EVENT_FREEZE_INFO_PATH, eventInfo.freezeInfoFile, + EVENT_FOREGROUND, eventInfo.foregroundState); + return ret; +} + +int AppfreezeEventReport::LogGeneralEvent(const std::string &name, HiSysEventType type, + const AppfreezeEventInfo &eventInfo) +{ + int ret = -1; + ret = HiSysEventWrite( + OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, + name, + type, + EVENT_UID, eventInfo.uid, + EVENT_PID, eventInfo.pid, + EVENT_TID, eventInfo.tid, + EVENT_PACKAGE_NAME, eventInfo.bundleName, + EVENT_PROCESS_NAME, eventInfo.processName, + EVENT_MESSAGE, eventInfo.errorMessage, + EVENT_STACK, eventInfo.errorStack, + EVENT_BINDER_INFO, eventInfo.binderInfo, + EVENT_APP_RUNNING_UNIQUE_ID, eventInfo.appRunningUniqueId, + EVENT_FREEZE_MEMORY, eventInfo.freezeMemory, + EVENT_FREEZE_INFO_PATH, eventInfo.freezeInfoFile); + return ret; +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/services/appdfr/src/appfreeze_fault_data.cpp b/services/appdfr/src/appfreeze_fault_data.cpp new file mode 100644 index 00000000000..05237c110a6 --- /dev/null +++ b/services/appdfr/src/appfreeze_fault_data.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023-2024 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 "appfreeze_fault_data.h" + +#include "nlohmann/json.hpp" +#include "string_ex.h" +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AppExecFwk { +bool AppfreezeFaultData::ReadFromParcel(Parcel &parcel) +{ + std::string strValue; + if (!parcel.ReadString(strValue)) { + TAG_LOGE(AAFwkTag::APPDFR, "InForeground [%{public}s] read string failed.", strValue.c_str()); + return false; + } + isInForeground = strValue; + return true; +} + +AppfreezeFaultData *AppfreezeFaultData::Unmarshalling(Parcel &parcel) +{ + AppfreezeFaultData *info = new AppfreezeFaultData(); + if (!info->ReadFromParcel(parcel)) { + delete info; + info = nullptr; + } + return info; +} + +bool AppfreezeFaultData::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteString(isInForeground)) { + TAG_LOGE(AAFwkTag::APPDFR, "InForeground [%{public}s] write string failed.", isInForeground.c_str()); + return false; + } + + return true; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/appdfr/src/appfreeze_manager.cpp b/services/appdfr/src/appfreeze_manager.cpp index a01dcd8a638..7edb48d23d7 100644 --- a/services/appdfr/src/appfreeze_manager.cpp +++ b/services/appdfr/src/appfreeze_manager.cpp @@ -41,29 +41,13 @@ #include "hitrace/hitracechain.h" #endif #include "appfreeze_cpu_freq_manager.h" +#include "appfreeze_event_report.h" namespace OHOS { namespace AppExecFwk { namespace { constexpr char EVENT_UID[] = "UID"; -constexpr char EVENT_PID[] = "PID"; -constexpr char EVENT_TID[] = "TID"; -constexpr char EVENT_INPUT_ID[] = "INPUT_ID"; -constexpr char EVENT_MESSAGE[] = "MSG"; -constexpr char EVENT_PACKAGE_NAME[] = "PACKAGE_NAME"; -constexpr char EVENT_PROCESS_NAME[] = "PROCESS_NAME"; -constexpr char EVENT_STACK[] = "STACK"; -constexpr char BINDER_INFO[] = "BINDER_INFO"; -constexpr char APP_RUNNING_UNIQUE_ID[] = "APP_RUNNING_UNIQUE_ID"; -constexpr char FREEZE_MEMORY[] = "FREEZE_MEMORY"; -constexpr char FREEZE_INFO_PATH[] = "FREEZE_INFO_PATH"; #ifdef ABILITY_RUNTIME_HITRACE_ENABLE -constexpr char EVENT_TRACE_ID[] = "HITRACE_ID"; -constexpr char EVENT_SPAN_ID[] = "SPAN_ID"; -constexpr char EVENT_PARENT_SPAN_ID[] = "PARENT_SPAN_ID"; -constexpr char EVENT_TRACE_FLAG[] = "TRACE_FLAG"; -constexpr char EVENT_APPFREEZE_TYPE[] = "appfreeze"; -constexpr char EVENT_SYSFREEZE_TYPE[] = "sysfreeze"; constexpr int32_t CHARACTER_WIDTH = 2; #endif @@ -83,6 +67,11 @@ static bool g_betaVersion = OHOS::system::GetParameter("const.logsystem.versiont static bool g_overseaVersion = OHOS::system::GetParameter("const.global.region", "CN") != "CN"; static bool g_developMode = (OHOS::system::GetParameter("persist.hiview.leak_detector", "unknown") == "enable") || (OHOS::system::GetParameter("persist.hiview.leak_detector", "unknown") == "true"); + +static constexpr const char *const HITRACE_ID = "hitrace_id: "; +static constexpr const char *const SPAN_ID = "span_id: "; +static constexpr const char *const PARENT_SPAN_ID = "parent_span_id: "; +static constexpr const char *const TRACE_FLAG = "trace_flag: "; } static constexpr const char *const TWELVE_BIG_CPU_CUR_FREQ = "/sys/devices/system/cpu/cpufreq/policy2/scaling_cur_freq"; static constexpr const char *const TWELVE_BIG_CPU_MAX_FREQ = "/sys/devices/system/cpu/cpufreq/policy2/scaling_max_freq"; @@ -225,7 +214,9 @@ int AppfreezeManager::AppfreezeHandleWithStack(const FaultData& faultData, const faultNotifyData.appfreezeInfo = faultData.appfreezeInfo; faultNotifyData.appRunningUniqueId = faultData.appRunningUniqueId; faultNotifyData.procStatm = faultData.procStatm; - +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + faultNotifyData.freezeData = faultData.freezeData; +#endif HITRACE_METER_FMT(HITRACE_TAG_APP, "AppfreezeHandleWithStack pid:%{public}d-name:%{public}s", appInfo.pid, faultData.errorObject.name.c_str()); return MergeNotifyInfo(faultNotifyData, appInfo); @@ -385,91 +376,95 @@ std::string AppfreezeManager::ParseDecToHex(uint64_t id) return ss.str(); } -bool AppfreezeManager::GetHitraceId(HitraceInfo& info) +std::string AppfreezeManager::GetHitraceInfo() { #ifdef ABILITY_RUNTIME_HITRACE_ENABLE OHOS::HiviewDFX::HiTraceId hitraceId = OHOS::HiviewDFX::HiTraceChain::GetId(); if (hitraceId.IsValid() == 0) { TAG_LOGW(AAFwkTag::APPDFR, "get hitrace id is invalid."); - return false; + return ""; } - info.hiTraceChainId = ParseDecToHex(hitraceId.GetChainId()); - info.spanId = ParseDecToHex(hitraceId.GetSpanId()); - info.pspanId = ParseDecToHex(hitraceId.GetParentSpanId()); - info.traceFlag = ParseDecToHex(hitraceId.GetFlags()); - TAG_LOGW(AAFwkTag::APPDFR, - "hiTraceChainId:%{public}s, spanId:%{public}s, pspanId:%{public}s, traceFlag:%{public}s", - info.hiTraceChainId.c_str(), info.spanId.c_str(), info.pspanId.c_str(), info.traceFlag.c_str()); - return true; + std::ostringstream hitraceIdStr; + hitraceIdStr << HITRACE_ID << ParseDecToHex(hitraceId.GetChainId()) << + SPAN_ID << ParseDecToHex(hitraceId.GetSpanId()) << + PARENT_SPAN_ID << ParseDecToHex(hitraceId.GetSpanId()) << + TRACE_FLAG << ParseDecToHex(hitraceId.GetParentSpanId()); + TAG_LOGW(AAFwkTag::APPDFR, "hitraceIdStr:%{public}s", hitraceIdStr.str().c_str()); + return hitraceIdStr.str(); #endif - return false; + return ""; } -std::string AppfreezeManager::ReportAppfreezeCpuInfo(const FaultData& faultData, +void AppfreezeManager::InitWarningCpuInfo(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo) { - std::string filePath; - if (faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_3S) { - AppExecFwk::AppfreezeCpuFreqManager::GetInstance().InitCpuDataProcessor( - EVENT_APPFREEZE_TYPE, appInfo.pid, appInfo.uid, faultData.appfreezeInfo); - } else if (faultData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT) { - AppExecFwk::AppfreezeCpuFreqManager::GetInstance().InitCpuDataProcessor( - EVENT_SYSFREEZE_TYPE, appInfo.pid, appInfo.uid, faultData.appfreezeInfo); - } else if (faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_6S) { - filePath = AppExecFwk::AppfreezeCpuFreqManager::GetInstance().WriteCpuInfoToFile( - EVENT_APPFREEZE_TYPE, appInfo.bundleName, appInfo.uid, appInfo.pid, faultData.errorObject.name); + std::string eventName = faultData.errorObject.name; + if (eventName != AppFreezeType::THREAD_BLOCK_3S && + eventName != AppFreezeType::LIFECYCLE_HALF_TIMEOUT) { + return; + } + std::string type = std::to_string(appInfo.pid) + "-" + std::to_string(appInfo.uid) + "-" + eventName; + bool ret = AppExecFwk::AppfreezeCpuFreqManager::GetInstance().InsertCpuDetailInfo(type, appInfo.pid); + TAG_LOGI(AAFwkTag::APPDFR, "Insert cpuInfo ret:%{public}d, pid:%{public}d, name:%{public}s, " + "appfreezeInfo:%{public}s, type:%{public}s", ret, appInfo.pid, + eventName.c_str(), faultData.appfreezeInfo.c_str(), type.c_str()); +} + +std::string AppfreezeManager::GetAppfreezeInfoPath(const FaultData& faultData, + const AppfreezeManager::AppInfo& appInfo) +{ + std::string eventName = faultData.errorObject.name; + std::string type = std::to_string(appInfo.pid) + "-" + std::to_string(appInfo.uid) + "-"; + if (faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_6S) { + type += AppFreezeType::THREAD_BLOCK_3S; } else if (faultData.errorObject.name == AppFreezeType::LIFECYCLE_TIMEOUT) { - filePath = AppExecFwk::AppfreezeCpuFreqManager::GetInstance().WriteCpuInfoToFile( - EVENT_SYSFREEZE_TYPE, appInfo.bundleName, appInfo.uid, appInfo.pid, faultData.errorObject.name); + type += AppFreezeType::LIFECYCLE_HALF_TIMEOUT; + } else { + return faultData.appfreezeInfo; } - TAG_LOGI(AAFwkTag::APPDFR, "report appfreeze name:%{public}s, appfreezeInfo:%{public}s, path:%{public}s", - faultData.errorObject.name.c_str(), faultData.appfreezeInfo.c_str(), filePath.c_str()); - return filePath; + std::string cpuInfoFile = AppExecFwk::AppfreezeCpuFreqManager::GetInstance().GetCpuInfoPath( + type, appInfo.bundleName, appInfo.uid, appInfo.pid); + TAG_LOGI(AAFwkTag::APPDFR, "name:%{public}s, cpuInfoFile:%{public}s, type:%{public}s", + faultData.errorObject.name.c_str(), cpuInfoFile.c_str(), type.c_str()); + return cpuInfoFile; } int AppfreezeManager::NotifyANR(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo, const std::string& binderInfo, const std::string& memoryContent) { - std::string appRunningUniqueId = faultData.appRunningUniqueId; - int ret = 0; - this->PerfStart(faultData.errorObject.name); + std::string eventName = faultData.errorObject.name; + this->PerfStart(eventName); int64_t startTime = AbilityRuntime::TimeUtil::CurrentTimeMillis(); - if (faultData.errorObject.name == AppFreezeType::APP_INPUT_BLOCK) { - ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, faultData.errorObject.name, - OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_UID, appInfo.uid, EVENT_PID, appInfo.pid, - EVENT_PACKAGE_NAME, appInfo.bundleName, EVENT_PROCESS_NAME, appInfo.processName, EVENT_MESSAGE, - faultData.errorObject.message, EVENT_STACK, faultData.errorObject.stack, BINDER_INFO, binderInfo, - APP_RUNNING_UNIQUE_ID, appRunningUniqueId, EVENT_INPUT_ID, faultData.eventId, - FREEZE_MEMORY, memoryContent + "\n" + faultData.procStatm); - } else if (faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_6S) { - HitraceInfo info; - bool hitraceIsValid = GetHitraceId(info); - ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, faultData.errorObject.name, - OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_UID, appInfo.uid, EVENT_PID, appInfo.pid, - EVENT_TID, faultData.tid, - EVENT_PACKAGE_NAME, appInfo.bundleName, EVENT_PROCESS_NAME, appInfo.processName, EVENT_MESSAGE, - faultData.errorObject.message, EVENT_STACK, faultData.errorObject.stack, BINDER_INFO, binderInfo, - APP_RUNNING_UNIQUE_ID, appRunningUniqueId, FREEZE_MEMORY, memoryContent + "\n" + faultData.procStatm, - EVENT_TRACE_ID, hitraceIsValid ? info.hiTraceChainId : "", - EVENT_SPAN_ID, hitraceIsValid ? info.spanId : "", - EVENT_PARENT_SPAN_ID, hitraceIsValid ? info.pspanId : "", - EVENT_TRACE_FLAG, hitraceIsValid ? info.traceFlag : "", - FREEZE_INFO_PATH, ReportAppfreezeCpuInfo(faultData, appInfo)); - } else { - ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, faultData.errorObject.name, - OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_UID, appInfo.uid, EVENT_PID, appInfo.pid, - EVENT_TID, faultData.tid > 0 ? faultData.tid : appInfo.pid, - EVENT_PACKAGE_NAME, appInfo.bundleName, EVENT_PROCESS_NAME, appInfo.processName, EVENT_MESSAGE, - faultData.errorObject.message, EVENT_STACK, faultData.errorObject.stack, BINDER_INFO, binderInfo, - APP_RUNNING_UNIQUE_ID, appRunningUniqueId, FREEZE_MEMORY, memoryContent + "\n" + faultData.procStatm, - FREEZE_INFO_PATH, ReportAppfreezeCpuInfo(faultData, appInfo)); - } - TAG_LOGW(AAFwkTag::APPDFR, - "reportEvent:%{public}s, pid:%{public}d, tid:%{public}d, bundleName:%{public}s, appRunningUniqueId:%{public}s" - ", endTime:%{public}s, interval:%{public}" PRId64 " ms, eventId:%{public}d hisysevent write ret: %{public}d", + int tid = faultData.tid; + std::string appRunningUniqueId = faultData.appRunningUniqueId; + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid > 0 ? tid : 0; + eventInfo.pid = appInfo.pid; + eventInfo.uid = appInfo.uid; + eventInfo.eventId = faultData.eventId; + eventInfo.bundleName = appInfo.bundleName; + eventInfo.processName = appInfo.processName; + eventInfo.binderInfo = binderInfo; + eventInfo.freezeMemory = memoryContent + "\n" + faultData.procStatm; + eventInfo.appRunningUniqueId = appRunningUniqueId; + eventInfo.errorStack = faultData.errorObject.stack; + eventInfo.errorName = eventName; + eventInfo.errorMessage = faultData.errorObject.message; + eventInfo.freezeInfoFile = GetAppfreezeInfoPath(faultData, appInfo); + eventInfo.hitraceInfo = GetHitraceInfo(); +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + eventInfo.foregroundState = faultData.freezeData.isInForeground; +#endif + + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + TAG_LOGW(AAFwkTag::APPDFR, "reportEvent:%{public}s, pid:%{public}d, tid:%{public}d, bundleName:%{public}s, " + "appRunningUniqueId:%{public}s, endTime:%{public}s, interval:%{public}" PRId64 " ms, " + "eventId:%{public}d freezeInfoFile:%{public}s, hisysevent write ret: %{public}d", faultData.errorObject.name.c_str(), appInfo.pid, faultData.tid, appInfo.bundleName.c_str(), appRunningUniqueId.c_str(), AbilityRuntime::TimeUtil::DefaultCurrentTimeStr().c_str(), - AbilityRuntime::TimeUtil::CurrentTimeMillis() - startTime, faultData.eventId, ret); + AbilityRuntime::TimeUtil::CurrentTimeMillis() - startTime, faultData.eventId, + eventInfo.freezeInfoFile.c_str(), ret); #ifdef ABILITY_RUNTIME_HITRACE_ENABLE OHOS::HiviewDFX::HiTraceChain::ClearId(); #endif diff --git a/services/appdfr/src/cpu_data_processor.cpp b/services/appdfr/src/cpu_data_processor.cpp index 278957242ee..969ac50572a 100644 --- a/services/appdfr/src/cpu_data_processor.cpp +++ b/services/appdfr/src/cpu_data_processor.cpp @@ -17,14 +17,12 @@ namespace OHOS { namespace AppExecFwk { CpuDataProcessor::CpuDataProcessor(const std::vector> &cpuData, - const std::vector &totalTimeList, CpuStartTime cpuStartTime, - const std::string &stackPath, int32_t pid) - : handlingHalfCpuData_(cpuData), totalTimeList_(totalTimeList), cpuStartTime_(cpuStartTime), stackPath_(stackPath), - pid_(pid) + const std::vector &totalTimeList, CpuConsumeTime cpuConsumeTime, int32_t pid) + : handlingHalfCpuData_(cpuData), totalTimeList_(totalTimeList), cpuConsumeTime_(cpuConsumeTime), pid_(pid) { } -std::vector> CpuDataProcessor::GetHandlingHalfCpuData() const +std::vector> CpuDataProcessor::GetCpuDetailData() const { return handlingHalfCpuData_; } @@ -34,14 +32,9 @@ std::vector CpuDataProcessor::GetTotalTimeList() const return totalTimeList_; } -CpuStartTime CpuDataProcessor::GetCpuStartTime() const +CpuConsumeTime CpuDataProcessor::GetCpuConsumeTime() const { - return cpuStartTime_; -} - -std::string CpuDataProcessor::GetStackPath() const -{ - return stackPath_; + return cpuConsumeTime_; } int32_t CpuDataProcessor::GetPid() const diff --git a/services/appdfr/src/cpu_sys_config.cpp b/services/appdfr/src/cpu_sys_config.cpp new file mode 100644 index 00000000000..a59ea03c53a --- /dev/null +++ b/services/appdfr/src/cpu_sys_config.cpp @@ -0,0 +1,65 @@ +/* + * 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 "cpu_sys_config.h" +#include + +namespace OHOS { +namespace AppExecFwk { +namespace { + constexpr const char* const CPU_SYS_DEVICES = "/sys/devices/system/cpu/cpu"; + constexpr const char* const CPU_TIME_IN_STATE = "/power/time_in_state"; + constexpr const char* const CPU_PROC_PREFIX = "/proc/"; + constexpr const char* const CPU_PROC_TASK = "/task/"; + constexpr const char* const CPU_PROC_STAT = "/stat"; + constexpr const char* const CPU_CAPACITY = "/cpu_capacity"; +} +CpuSysConfig::CpuSysConfig() +{ +} + +CpuSysConfig::~CpuSysConfig() +{ +} + +std::string CpuSysConfig::GetFreqTimePath(int32_t cpu) +{ + std::stringstream ss; + ss << CPU_SYS_DEVICES << cpu << CPU_TIME_IN_STATE; + return ss.str(); +} + +std::string CpuSysConfig::GetMainThreadRunningTimePath(int32_t pid) +{ + std::stringstream ss; + ss << CPU_PROC_PREFIX << pid << CPU_PROC_TASK << pid << CPU_PROC_STAT; + return ss.str(); +} + +std::string CpuSysConfig::GetProcRunningTimePath(int32_t pid) +{ + std::stringstream ss; + ss << CPU_PROC_PREFIX << pid << CPU_PROC_STAT; + return ss.str(); +} + +std::string CpuSysConfig::GetMaxCoreDimpsPath(int32_t maxCpuCount) +{ + std::stringstream ss; + ss << CPU_SYS_DEVICES << maxCpuCount << CPU_CAPACITY; + return ss.str(); +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/services/appmgr/BUILD.gn b/services/appmgr/BUILD.gn index b9d6640df6b..b022d14b3c0 100644 --- a/services/appmgr/BUILD.gn +++ b/services/appmgr/BUILD.gn @@ -205,6 +205,11 @@ ohos_shared_library("libappms") { if (app_mgr_service_hicollie_enable) { defines += [ "APP_MGR_SERVICE_HICOLLIE_ENABLE" ] } + + if (ability_runtime_appfreeze_fault_data_enable) { + defines += [ "ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE" ] + } + cflags += [ "-DAPP_NO_RESPONSE_BUNDLENAME=\"${ability_runtime_app_no_response_bundlename}\"" ] version_script = "libappms.map" diff --git a/services/appmgr/src/app_mgr_service_inner.cpp b/services/appmgr/src/app_mgr_service_inner.cpp index 7058992c0f9..24aa5c91a13 100644 --- a/services/appmgr/src/app_mgr_service_inner.cpp +++ b/services/appmgr/src/app_mgr_service_inner.cpp @@ -7235,6 +7235,15 @@ int32_t AppMgrServiceInner::SubmitDfxFaultTask(const FaultData &faultData, const return ERR_INVALID_VALUE; } int64_t startTime = AbilityRuntime::TimeUtil::CurrentTimeMillis(); + TAG_LOGI(AAFwkTag::APPDFR, "init cpuInfo, eventName:%{public}s, bundleName:%{public}s, " + "pid:%{public}d", faultData.errorObject.name.c_str(), bundleName.c_str(), pid); + AppfreezeManager::AppInfo info = { + .pid = pid, + .uid = callerUid, + .bundleName = bundleName, + .processName = processName, + }; + AppExecFwk::AppfreezeManager::GetInstance()->InitWarningCpuInfo(faultData, info); dfxTaskHandler_->SubmitTask(notifyAppTask, "NotifyAppFaultTask"); TAG_LOGW(AAFwkTag::APPDFR, "submit NotifyAppFaultTask, eventName:%{public}s, bundleName:%{public}s, " "endTime:%{public}s, interval:%{public}" PRId64 " ms", faultData.errorObject.name.c_str(), @@ -7499,6 +7508,9 @@ FaultData AppMgrServiceInner::ConvertDataTypes(const AppFaultDataBySA &faultData newfaultData.needKillProcess = faultData.needKillProcess; newfaultData.appfreezeInfo = faultData.appfreezeInfo; newfaultData.procStatm = faultData.procStatm; +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + newfaultData.freezeData = faultData.freezeData; +#endif if (appRunningManager_) { std::string appRunningUniqueId; int32_t ret = appRunningManager_->GetAppRunningUniqueIdByPid(faultData.pid, appRunningUniqueId); diff --git a/test/unittest/dfr_test/BUILD.gn b/test/unittest/dfr_test/BUILD.gn index fc3693ed844..851d8a6cd42 100644 --- a/test/unittest/dfr_test/BUILD.gn +++ b/test/unittest/dfr_test/BUILD.gn @@ -23,5 +23,7 @@ group("unittest") { "cpu_data_processor_test:unittest", "dump_proc_helper_test:unittest", "watchdog_test:unittest", + "cpu_sys_config_test:unittest", + "appfreeze_event_report_test:unittest", ] } diff --git a/test/unittest/dfr_test/appfreeze_cpu_freq_manager_test/appfreeze_cpu_freq_manager_test.cpp b/test/unittest/dfr_test/appfreeze_cpu_freq_manager_test/appfreeze_cpu_freq_manager_test.cpp index 4416cde3d42..36ddb1ecfed 100644 --- a/test/unittest/dfr_test/appfreeze_cpu_freq_manager_test/appfreeze_cpu_freq_manager_test.cpp +++ b/test/unittest/dfr_test/appfreeze_cpu_freq_manager_test/appfreeze_cpu_freq_manager_test.cpp @@ -19,7 +19,6 @@ #include "appfreeze_cpu_freq_manager.h" #undef private -#include "appfreeze_data.h" #include "appfreeze_util.h" using namespace testing; @@ -54,50 +53,58 @@ void AppfreezeCpuFreqManagerTest::TearDown(void) {} /** - * @tc.number: InitCpuDataProcessorTest_001 + * @tc.number: InsertCpuDetailInfo_001 * @tc.desc: add testcase * @tc.type: FUNC */ -HWTEST_F(AppfreezeCpuFreqManagerTest, InitCpuDataProcessorTest_001, TestSize.Level1) +HWTEST_F(AppfreezeCpuFreqManagerTest, InsertCpuDetailInfo_001, TestSize.Level1) { uint32_t checkMapSize = 10; - std::string eventType = "test0"; + std::string type = "test0"; int32_t pid = getpid(); int32_t uid = static_cast(getuid()); - std::string stackpath = "InitCpuDataProcessorTest_001"; - bool ret = AppfreezeCpuFreqManager::GetInstance().InitCpuDataProcessor(eventType, pid, uid, stackpath); + bool ret = AppfreezeCpuFreqManager::GetInstance().InsertCpuDetailInfo(type, pid); EXPECT_TRUE(ret); - ret = AppfreezeCpuFreqManager::GetInstance().InitCpuDataProcessor(eventType, pid, uid, stackpath); - EXPECT_TRUE(!ret); for (auto i = 1; i < checkMapSize; i++) { - eventType = "test" + std::to_string(i); - AppfreezeCpuFreqManager::GetInstance().InitCpuDataProcessor(eventType, pid, uid, stackpath); + type = "test" + std::to_string(i); + AppfreezeCpuFreqManager::GetInstance().InsertCpuDetailInfo(type, pid); } - EXPECT_TRUE(AppfreezeCpuFreqManager::GetInstance().cpuInfoMap_.size() == checkMapSize); - int left = 8; // over 8s + int left = 10; // over 10s while (left > 0) { left = sleep(left); } - eventType = "test112"; - ret = AppfreezeCpuFreqManager::GetInstance().InitCpuDataProcessor(eventType, pid, uid, stackpath); + type = "test0"; + ret = AppfreezeCpuFreqManager::GetInstance().InsertCpuDetailInfo(type, pid); EXPECT_TRUE(ret); } /** - * @tc.number: ReadCpuDataByNumTest_001 + * @tc.number: GetCpuDetailInfo_001 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeCpuFreqManagerTest, GetCpuDetailInfo_001, TestSize.Level1) +{ + int32_t pid = getpid(); + CpuDataProcessor data = AppfreezeCpuFreqManager::GetInstance().GetCpuDetailInfo(pid); + EXPECT_TRUE(pid >= 0); +} + +/** + * @tc.number: GetInfoByCpuCountTest_001 * @tc.desc: add testcase * @tc.type: FUNC */ -HWTEST_F(AppfreezeCpuFreqManagerTest, ReadCpuDataByNumTest_001, TestSize.Level1) +HWTEST_F(AppfreezeCpuFreqManagerTest, GetInfoByCpuCountTest_001, TestSize.Level1) { std::vector parseDatas; TotalTime totalTime; int32_t num = 100; - AppfreezeCpuFreqManager::GetInstance().ReadCpuDataByNum(num, parseDatas, totalTime); + AppfreezeCpuFreqManager::GetInstance().GetInfoByCpuCount(num, parseDatas, totalTime); EXPECT_TRUE(parseDatas.size() == 0); num = 0; - AppfreezeCpuFreqManager::GetInstance().ReadCpuDataByNum(num, parseDatas, totalTime); - EXPECT_TRUE(parseDatas.size() == 0); + AppfreezeCpuFreqManager::GetInstance().GetInfoByCpuCount(num, parseDatas, totalTime); + EXPECT_TRUE(parseDatas.size() >= 0); } /** @@ -204,7 +211,7 @@ HWTEST_F(AppfreezeCpuFreqManagerTest, GetProcessCpuTimeTest_001, TestSize.Level0 */ HWTEST_F(AppfreezeCpuFreqManagerTest, GetOptimalCpuTimeTest_001, TestSize.Level0) { - uint64_t ret = AppfreezeCpuFreqManager::GetInstance().GetOptimalCpuTime(getpid()); + double ret = AppfreezeCpuFreqManager::GetInstance().GetOptimalCpuTime(getpid()); EXPECT_TRUE(ret >= 0); int count = AppfreezeCpuFreqManager::GetInstance().cpuCount_; AppfreezeCpuFreqManager::GetInstance().cpuCount_ = 0; @@ -221,10 +228,12 @@ HWTEST_F(AppfreezeCpuFreqManagerTest, GetOptimalCpuTimeTest_001, TestSize.Level0 HWTEST_F(AppfreezeCpuFreqManagerTest, GetCpuInfoTest_001, TestSize.Level0) { uint64_t start = AppfreezeUtil::GetMilliseconds(); - std::string ret = AppfreezeCpuFreqManager::GetInstance().GetStartTime(start); + std::string ret = AppfreezeCpuFreqManager::GetInstance().GetTimeStampStr(start); EXPECT_TRUE(!ret.empty()); - CpuStartTime cpuStartTime; - ret = AppfreezeCpuFreqManager::GetInstance().GetStaticInfo(getpid(), cpuStartTime); + CpuConsumeTime cpuConsumeTime1; + CpuConsumeTime cpuConsumeTime2; + ret = AppfreezeCpuFreqManager::GetInstance().GetConsumeTimeInfo(getpid(), cpuConsumeTime1, + cpuConsumeTime2); EXPECT_TRUE(!ret.empty()); ret = AppfreezeCpuFreqManager::GetInstance().GetStaticInfoHead(); EXPECT_TRUE(!ret.empty()); @@ -237,9 +246,12 @@ HWTEST_F(AppfreezeCpuFreqManagerTest, GetCpuInfoTest_001, TestSize.Level0) */ HWTEST_F(AppfreezeCpuFreqManagerTest, GetCpuInfoContentTest_001, TestSize.Level0) { - std::vector> datas; - std::vector totalTimeList; - std::string ret = AppfreezeCpuFreqManager::GetInstance().GetCpuInfoContent(datas, totalTimeList); + std::vector> datas1; + std::vector totalTimeList1; + std::vector> datas2; + std::vector totalTimeList2; + std::string ret = AppfreezeCpuFreqManager::GetInstance().GetCpuInfoContent(totalTimeList1, datas1, + totalTimeList2, datas2); EXPECT_TRUE(ret.empty()); std::vector parseDatas; CpuFreqData cpuFreqData1 = { @@ -247,63 +259,106 @@ HWTEST_F(AppfreezeCpuFreqManagerTest, GetCpuInfoContentTest_001, TestSize.Level0 .runningTime = 100, }; parseDatas.push_back(cpuFreqData1); - datas.push_back(parseDatas); + datas1.push_back(parseDatas); TotalTime time1 = { .totalRunningTime = 50, .totalCpuTime = 1000, }; - totalTimeList.push_back(time1); - ret = AppfreezeCpuFreqManager::GetInstance().GetCpuInfoContent(datas, totalTimeList); + totalTimeList1.push_back(time1); + ret = AppfreezeCpuFreqManager::GetInstance().GetCpuInfoContent(totalTimeList1, datas1, + totalTimeList2, datas2); EXPECT_TRUE(ret.empty()); } /** - * @tc.number: WriteCpuInfoToFileTest_001 + * @tc.number: GetFreezeLogHeadTest_001 * @tc.desc: add testcase * @tc.type: FUNC */ -HWTEST_F(AppfreezeCpuFreqManagerTest, WriteCpuInfoToFileTest_001, TestSize.Level0) +HWTEST_F(AppfreezeCpuFreqManagerTest, GetFreezeLogHeadTest_001, TestSize.Level0) +{ + std::string ret = AppfreezeCpuFreqManager::GetInstance().GetFreezeLogHead("bundleName"); + EXPECT_TRUE(!ret.empty()); +} + +/** + * @tc.number: GetIntervalTest_001 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeCpuFreqManagerTest, GetIntervalTest_001, TestSize.Level0) +{ + uint64_t warnTime = 1234; // test value + uint64_t blockTime = 2345; // test value + uint64_t ret = AppfreezeCpuFreqManager::GetInstance().GetInterval(warnTime, blockTime); + EXPECT_EQ(ret, 1111); +} + +/** + * @tc.number: GetIntervalTest_002 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeCpuFreqManagerTest, GetIntervalTest_002, TestSize.Level0) +{ + uint64_t warnTime = 1200; // test value + uint64_t blockTime = 1000; // test value + uint64_t ret = AppfreezeCpuFreqManager::GetInstance().GetInterval(warnTime, blockTime); + EXPECT_EQ(ret, 200); +} + +/** + * @tc.number: GetConsumeTimeInfoTest_001 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeCpuFreqManagerTest, GetConsumeTimeInfoTest_001, TestSize.Level0) { - AppfreezeCpuFreqManager::GetInstance().WriteDfxLogToFile("filePath", "bundleName"); - std::string eventType = "WriteCpuInfoToFileTest_001"; - std::string testValue = "AppfreezeCpuFreqManagerTest"; - std::string ret = AppfreezeCpuFreqManager::GetInstance().WriteCpuInfoToFile(eventType, - testValue, getuid(), getpid(), testValue); - EXPECT_TRUE(ret.empty()); int32_t pid = getpid(); - int32_t uid = static_cast(getuid()); - bool result = AppfreezeCpuFreqManager::GetInstance().InitCpuDataProcessor(eventType, pid, uid, testValue); - EXPECT_TRUE(result); - testValue = "LIFECYCLE_TIMEOUT"; - ret = AppfreezeCpuFreqManager::GetInstance().WriteCpuInfoToFile(eventType, - testValue, getuid(), getpid(), testValue); - EXPECT_TRUE(ret.empty()); + CpuConsumeTime warnTimes = { + .optimalCpuTime = AppfreezeCpuFreqManager::GetInstance().GetOptimalCpuTime(pid), + .cpuFaultTime = AppfreezeUtil::GetMilliseconds(), + .processCpuTime = AppfreezeCpuFreqManager::GetInstance().GetProcessCpuTime(pid), + .deviceRunTime = AppfreezeCpuFreqManager::GetInstance().GetDeviceRuntime(), + .cpuTime = AppfreezeCpuFreqManager::GetInstance().GetAppCpuTime(pid), + }; + uint64_t testValue = 1234; // testValue + CpuConsumeTime blockTimes = { + .optimalCpuTime = AppfreezeCpuFreqManager::GetInstance().GetOptimalCpuTime(pid) + testValue, + .cpuFaultTime = AppfreezeUtil::GetMilliseconds() + testValue, + .processCpuTime = AppfreezeCpuFreqManager::GetInstance().GetProcessCpuTime(pid) + testValue, + .deviceRunTime = AppfreezeCpuFreqManager::GetInstance().GetDeviceRuntime() + testValue, + .cpuTime = AppfreezeCpuFreqManager::GetInstance().GetAppCpuTime(pid) + testValue, + }; + std::string ret = AppfreezeCpuFreqManager::GetInstance().GetConsumeTimeInfo(pid, + warnTimes, blockTimes); + EXPECT_TRUE(!ret.empty()); } /** - * @tc.number: WriteCpuInfoToFileTest_002 + * @tc.number: GetCpuInfoPathTest_001 * @tc.desc: add testcase * @tc.type: FUNC */ -HWTEST_F(AppfreezeCpuFreqManagerTest, WriteCpuInfoToFileTest_002, TestSize.Level0) +HWTEST_F(AppfreezeCpuFreqManagerTest, GetCpuInfoPathTest_001, TestSize.Level0) { int32_t pid = getpid(); int32_t uid = static_cast(getuid()); - std::string eventType = "WriteCpuInfoToFileTest_001"; + std::string type = "GetCpuInfoPathTest_001"; std::string testValue = "AppfreezeCpuFreqManagerTest"; - bool result = AppfreezeCpuFreqManager::GetInstance().InitCpuDataProcessor(eventType, pid, uid, testValue); - EXPECT_TRUE(!result); + bool result = AppfreezeCpuFreqManager::GetInstance().InsertCpuDetailInfo(type, pid); + EXPECT_TRUE(result); int32_t newPid = pid + 10; - std::string ret = AppfreezeCpuFreqManager::GetInstance().WriteCpuInfoToFile(eventType, - testValue, getuid(), newPid, testValue); + std::string ret = AppfreezeCpuFreqManager::GetInstance().GetCpuInfoPath(type, + testValue, uid, newPid); EXPECT_TRUE(ret.empty()); - int left = 7; + int left = 10; // test value while (left > 0) { left = sleep(left); } - ret = AppfreezeCpuFreqManager::GetInstance().WriteCpuInfoToFile(eventType, - testValue, getuid(), pid, testValue); - EXPECT_TRUE(ret.empty()); + ret = AppfreezeCpuFreqManager::GetInstance().GetCpuInfoPath(type, + testValue, uid, pid); + EXPECT_TRUE(!ret.empty()); } } // namespace AppExecFwk } // namespace OHOS diff --git a/test/unittest/dfr_test/appfreeze_event_report_test/BUILD.gn b/test/unittest/dfr_test/appfreeze_event_report_test/BUILD.gn new file mode 100644 index 00000000000..cee37c58d56 --- /dev/null +++ b/test/unittest/dfr_test/appfreeze_event_report_test/BUILD.gn @@ -0,0 +1,46 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/test.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +module_output_path = "ability_runtime/freeze_checker" + +############################################################################### + +ohos_unittest("appfreeze_event_report_test") { + module_out_path = module_output_path + + include_dirs = [ + "${ability_runtime_services_path}/appdfr/include", + ] + + sources = [ "appfreeze_event_report_test.cpp" ] + + deps = [] + + external_deps = [ + "ability_runtime:app_manager", + "hisysevent:libhisysevent", + "googletest:gmock_main", + "googletest:gtest_main", + ] +} + +############################################################################### + +group("unittest") { + testonly = true + deps = [ ":appfreeze_event_report_test" ] +} diff --git a/test/unittest/dfr_test/appfreeze_event_report_test/appfreeze_event_report_test.cpp b/test/unittest/dfr_test/appfreeze_event_report_test/appfreeze_event_report_test.cpp new file mode 100644 index 00000000000..7954600ab90 --- /dev/null +++ b/test/unittest/dfr_test/appfreeze_event_report_test/appfreeze_event_report_test.cpp @@ -0,0 +1,381 @@ +/* + * 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 + +#include "appfreeze_event_report.h" + +using namespace testing; +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::AppExecFwk; + +namespace OHOS { +namespace AppExecFwk { +class AppfreezeEventReportTest : public testing::Test { +public: + AppfreezeEventReportTest() + {} + ~AppfreezeEventReportTest() + {} + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void AppfreezeEventReportTest::SetUpTestCase(void) +{} + +void AppfreezeEventReportTest::TearDownTestCase(void) +{} + +void AppfreezeEventReportTest::SetUp(void) +{} + +void AppfreezeEventReportTest::TearDown(void) +{} + +/** + * @tc.number: SendAppfreezeEvent_Test_001 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeEventReportTest, SendAppfreezeEvent_Test_001, TestSize.Level1) +{ + std::string eventName = "THREAD_BLOCK_3S"; + std::string testName = "SendAppfreezeEvent_Test_001"; + int tid = static_cast(gettid()); + int pid = static_cast(getpid()); + int uid = static_cast(getuid()); + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid; + eventInfo.pid = pid; + eventInfo.uid = uid; + eventInfo.eventId = -1; // test value + eventInfo.bundleName = testName; + eventInfo.processName = testName; + eventInfo.binderInfo = "PeerBinder: test binder info \\n"; + eventInfo.freezeMemory = "memory info test"; + eventInfo.appRunningUniqueId = "id: 1234"; + eventInfo.errorStack = "SendAppfreezeEvent_Test_001: error stack"; + eventInfo.errorName = eventName; + eventInfo.errorMessage = "SendAppfreezeEvent_Test_001: error message"; + eventInfo.freezeInfoFile = "SendAppfreezeEvent_Test_001: freezeInfoFile"; + eventInfo.hitraceInfo = "hitraceInfo: 1234"; + eventInfo.foregroundState = "Yes"; + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.number: SendAppfreezeEvent_Test_002 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeEventReportTest, SendAppfreezeEvent_Test_002, TestSize.Level1) +{ + std::string eventName = "THREAD_BLOCK_6S"; + std::string testName = "SendAppfreezeEvent_Test_002"; + int tid = static_cast(gettid()); + int pid = static_cast(getpid()); + int uid = static_cast(getuid()); + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid; + eventInfo.pid = pid; + eventInfo.uid = uid; + eventInfo.eventId = -1; // test value + eventInfo.bundleName = testName; + eventInfo.processName = testName; + eventInfo.binderInfo = "PeerBinder: test binder info \\n"; + eventInfo.freezeMemory = "memory info test"; + eventInfo.appRunningUniqueId = "id: 1234"; + eventInfo.errorStack = "SendAppfreezeEvent_Test_002: error stack"; + eventInfo.errorName = eventName; + eventInfo.errorMessage = "SendAppfreezeEvent_Test_002: error message"; + eventInfo.freezeInfoFile = "SendAppfreezeEvent_Test_002: freezeInfoFile"; + eventInfo.hitraceInfo = "hitraceInfo: 1234"; + eventInfo.foregroundState = "Yes"; + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.number: SendAppfreezeEvent_Test_003 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeEventReportTest, SendAppfreezeEvent_Test_003, TestSize.Level1) +{ + std::string eventName = "LIFECYCLE_HALF_TIMEOUT"; + std::string testName = "SendAppfreezeEvent_Test_003"; + int tid = static_cast(gettid()); + int pid = static_cast(getpid()); + int uid = static_cast(getuid()); + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid; + eventInfo.pid = pid; + eventInfo.uid = uid; + eventInfo.eventId = -1; // test value + eventInfo.bundleName = testName; + eventInfo.processName = testName; + eventInfo.binderInfo = "PeerBinder: test binder info \\n"; + eventInfo.freezeMemory = "memory info test"; + eventInfo.appRunningUniqueId = "id: 1234"; + eventInfo.errorStack = "SendAppfreezeEvent_Test_003: error stack"; + eventInfo.errorName = eventName; + eventInfo.errorMessage = "SendAppfreezeEvent_Test_003: error message"; + eventInfo.freezeInfoFile = "SendAppfreezeEvent_Test_003: freezeInfoFile"; + eventInfo.hitraceInfo = "hitraceInfo: 1234"; + eventInfo.foregroundState = "Yes"; + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.number: SendAppfreezeEvent_Test_004 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeEventReportTest, SendAppfreezeEvent_Test_004, TestSize.Level1) +{ + std::string eventName = "LIFECYCLE_HALF_TIMEOUT_WARNING"; + std::string testName = "SendAppfreezeEvent_Test_004"; + int tid = static_cast(gettid()); + int pid = static_cast(getpid()); + int uid = static_cast(getuid()); + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid; + eventInfo.pid = pid; + eventInfo.uid = uid; + eventInfo.eventId = -1; // test value + eventInfo.bundleName = testName; + eventInfo.processName = testName; + eventInfo.binderInfo = "PeerBinder: test binder info \\n"; + eventInfo.freezeMemory = "memory info test"; + eventInfo.appRunningUniqueId = "id: 1234"; + eventInfo.errorStack = "SendAppfreezeEvent_Test_004: error stack"; + eventInfo.errorName = eventName; + eventInfo.errorMessage = "SendAppfreezeEvent_Test_004: error message"; + eventInfo.freezeInfoFile = "SendAppfreezeEvent_Test_004: freezeInfoFile"; + eventInfo.hitraceInfo = "hitraceInfo: 1234"; + eventInfo.foregroundState = "Yes"; + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.number: SendAppfreezeEvent_Test_005 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeEventReportTest, SendAppfreezeEvent_Test_005, TestSize.Level1) +{ + std::string eventName = "LIFECYCLE_TIMEOUT"; + std::string testName = "SendAppfreezeEvent_Test_005"; + int tid = static_cast(gettid()); + int pid = static_cast(getpid()); + int uid = static_cast(getuid()); + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid; + eventInfo.pid = pid; + eventInfo.uid = uid; + eventInfo.eventId = -1; // test value + eventInfo.bundleName = testName; + eventInfo.processName = testName; + eventInfo.binderInfo = "PeerBinder: test binder info \\n"; + eventInfo.freezeMemory = "memory info test"; + eventInfo.appRunningUniqueId = "id: 1234"; + eventInfo.errorStack = "SendAppfreezeEvent_Test_005: error stack"; + eventInfo.errorName = eventName; + eventInfo.errorMessage = "SendAppfreezeEvent_Test_005: error message"; + eventInfo.freezeInfoFile = "SendAppfreezeEvent_Test_005: freezeInfoFile"; + eventInfo.hitraceInfo = "hitraceInfo: 1234"; + eventInfo.foregroundState = "Yes"; + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.number: SendAppfreezeEvent_Test_006 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeEventReportTest, SendAppfreezeEvent_Test_006, TestSize.Level1) +{ + std::string eventName = "LIFECYCLE_TIMEOUT_WARNING"; + std::string testName = "SendAppfreezeEvent_Test_006"; + int tid = static_cast(gettid()); + int pid = static_cast(getpid()); + int uid = static_cast(getuid()); + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid; + eventInfo.pid = pid; + eventInfo.uid = uid; + eventInfo.eventId = -1; // test value + eventInfo.bundleName = testName; + eventInfo.processName = testName; + eventInfo.binderInfo = "PeerBinder: test binder info \\n"; + eventInfo.freezeMemory = "memory info test"; + eventInfo.appRunningUniqueId = "id: 1234"; + eventInfo.errorStack = "SendAppfreezeEvent_Test_006: error stack"; + eventInfo.errorName = eventName; + eventInfo.errorMessage = "SendAppfreezeEvent_Test_006: error message"; + eventInfo.freezeInfoFile = "SendAppfreezeEvent_Test_006: freezeInfoFile"; + eventInfo.hitraceInfo = "hitraceInfo: 1234"; + eventInfo.foregroundState = "Yes"; + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.number: SendAppfreezeEvent_Test_007 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeEventReportTest, SendAppfreezeEvent_Test_007, TestSize.Level1) +{ + std::string eventName = "APP_LIFECYCLE_TIMEOUT"; + std::string testName = "SendAppfreezeEvent_Test_007"; + int tid = static_cast(gettid()); + int pid = static_cast(getpid()); + int uid = static_cast(getuid()); + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid; + eventInfo.pid = pid; + eventInfo.uid = uid; + eventInfo.eventId = -1; // test value + eventInfo.bundleName = testName; + eventInfo.processName = testName; + eventInfo.binderInfo = "PeerBinder: test binder info \\n"; + eventInfo.freezeMemory = "memory info test"; + eventInfo.appRunningUniqueId = "id: 1234"; + eventInfo.errorStack = "SendAppfreezeEvent_Test_007: error stack"; + eventInfo.errorName = eventName; + eventInfo.errorMessage = "SendAppfreezeEvent_Test_007: error message"; + eventInfo.freezeInfoFile = "SendAppfreezeEvent_Test_007: freezeInfoFile"; + eventInfo.hitraceInfo = "hitraceInfo: 1234"; + eventInfo.foregroundState = "Yes"; + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.number: SendAppfreezeEvent_Test_008 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeEventReportTest, SendAppfreezeEvent_Test_008, TestSize.Level1) +{ + std::string eventName = "APP_INPUT_BLOCK"; + std::string testName = "SendAppfreezeEvent_Test_008"; + int tid = static_cast(gettid()); + int pid = static_cast(getpid()); + int uid = static_cast(getuid()); + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid; + eventInfo.pid = pid; + eventInfo.uid = uid; + eventInfo.eventId = -1; // test value + eventInfo.bundleName = testName; + eventInfo.processName = testName; + eventInfo.binderInfo = "PeerBinder: test binder info \\n"; + eventInfo.freezeMemory = "memory info test"; + eventInfo.appRunningUniqueId = "id: 1234"; + eventInfo.errorStack = "SendAppfreezeEvent_Test_008: error stack"; + eventInfo.errorName = eventName; + eventInfo.errorMessage = "SendAppfreezeEvent_Test_008: error message"; + eventInfo.freezeInfoFile = "SendAppfreezeEvent_Test_008: freezeInfoFile"; + eventInfo.hitraceInfo = "hitraceInfo: 1234"; + eventInfo.foregroundState = "Yes"; + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.number: SendAppfreezeEvent_Test_009 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeEventReportTest, SendAppfreezeEvent_Test_009, TestSize.Level1) +{ + std::string eventName = "BUSSINESS_THREAD_BLOCK_3S"; + std::string testName = "SendAppfreezeEvent_Test_009"; + int tid = static_cast(gettid()); + int pid = static_cast(getpid()); + int uid = static_cast(getuid()); + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid; + eventInfo.pid = pid; + eventInfo.uid = uid; + eventInfo.eventId = -1; // test value + eventInfo.bundleName = testName; + eventInfo.processName = testName; + eventInfo.binderInfo = "PeerBinder: test binder info \\n"; + eventInfo.freezeMemory = "memory info test"; + eventInfo.appRunningUniqueId = "id: 1234"; + eventInfo.errorStack = "SendAppfreezeEvent_Test_009: error stack"; + eventInfo.errorName = eventName; + eventInfo.errorMessage = "SendAppfreezeEvent_Test_009: error message"; + eventInfo.freezeInfoFile = "SendAppfreezeEvent_Test_009: freezeInfoFile"; + eventInfo.hitraceInfo = "hitraceInfo: 1234"; + eventInfo.foregroundState = "Yes"; + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.number: SendAppfreezeEvent_Test_010 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeEventReportTest, SendAppfreezeEvent_Test_010, TestSize.Level1) +{ + std::string eventName = "BUSSINESS_THREAD_BLOCK_6S"; + std::string testName = "SendAppfreezeEvent_Test_010"; + int tid = static_cast(gettid()); + int pid = static_cast(getpid()); + int uid = static_cast(getuid()); + AppfreezeEventInfo eventInfo; + eventInfo.tid = tid; + eventInfo.pid = pid; + eventInfo.uid = uid; + eventInfo.eventId = -1; // test value + eventInfo.bundleName = testName; + eventInfo.processName = testName; + eventInfo.binderInfo = "PeerBinder: test binder info \\n"; + eventInfo.freezeMemory = "memory info test"; + eventInfo.appRunningUniqueId = "id: 1234"; + eventInfo.errorStack = "SendAppfreezeEvent_Test_010: error stack"; + eventInfo.errorName = eventName; + eventInfo.errorMessage = "SendAppfreezeEvent_Test_010: error message"; + eventInfo.freezeInfoFile = "SendAppfreezeEvent_Test_010: freezeInfoFile"; + eventInfo.hitraceInfo = "hitraceInfo: 1234"; + eventInfo.foregroundState = "Yes"; + int ret = AppfreezeEventReport::SendAppfreezeEvent(eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, eventInfo); + EXPECT_EQ(ret, 0); +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/test/unittest/dfr_test/appfreeze_inner_test/BUILD.gn b/test/unittest/dfr_test/appfreeze_inner_test/BUILD.gn index 087d5d57b38..eead79c54d8 100644 --- a/test/unittest/dfr_test/appfreeze_inner_test/BUILD.gn +++ b/test/unittest/dfr_test/appfreeze_inner_test/BUILD.gn @@ -75,6 +75,7 @@ ohos_unittest("appfreeze_inner_test") { "${ability_runtime_native_path}/appkit:appkit_native", "${ability_runtime_path}/js_environment/frameworks/js_environment:js_environment", "${ability_runtime_path}/utils/global/freeze:freeze_util", + "${ability_runtime_services_path}/common:task_handler_wrap", ] external_deps = [ @@ -113,6 +114,11 @@ ohos_unittest("appfreeze_inner_test") { "${ability_runtime_innerkits_path}/uri_permission:uri_permission_mgr", ] } + + defines = [] + if (ability_runtime_appfreeze_fault_data_enable) { + defines += [ "ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE" ] + } } ############################################################################### diff --git a/test/unittest/dfr_test/appfreeze_inner_test/appfreeze_inner_test.cpp b/test/unittest/dfr_test/appfreeze_inner_test/appfreeze_inner_test.cpp index 4f95f653758..264e2b434a6 100644 --- a/test/unittest/dfr_test/appfreeze_inner_test/appfreeze_inner_test.cpp +++ b/test/unittest/dfr_test/appfreeze_inner_test/appfreeze_inner_test.cpp @@ -271,5 +271,29 @@ HWTEST_F(AppfreezeInnerTest, AppfreezeInner_GetProcStatm_001, TestSize.Level1) procStatm = appfreezeInner->GetProcStatm(pid); EXPECT_TRUE(procStatm.empty()); } + +/** + * @tc.number: AppfreezeInner_EnableFreezeSample_001 + * @tc.name: EnableFreezeSample + */ +HWTEST_F(AppfreezeInnerTest, AppfreezeInner_EnableFreezeSample_001, TestSize.Level1) +{ + std::string ret = appfreezeInner->EnableFreezeSample(AppFreezeType::LIFECYCLE_HALF_TIMEOUT); + EXPECT_TRUE(!ret.empty()); + ret = appfreezeInner->EnableFreezeSample(AppFreezeType::THREAD_BLOCK_6S); + EXPECT_TRUE(ret.empty()); +} + +/** + * @tc.number: AppfreezeInner_AppInForeground_001 + * @tc.name: SetAppInForeground and GetAppInForeground + */ +HWTEST_F(AppfreezeInnerTest, AppfreezeInner_AppInForeground_001, TestSize.Level1) +{ + appfreezeInner->SetAppInForeground(true); + EXPECT_TRUE(appfreezeInner->GetAppInForeground()); + appfreezeInner->SetAppInForeground(false); + EXPECT_TRUE(!appfreezeInner->GetAppInForeground()); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/test/unittest/dfr_test/appfreeze_manager_test/BUILD.gn b/test/unittest/dfr_test/appfreeze_manager_test/BUILD.gn index 9bdb269886e..98faa993018 100644 --- a/test/unittest/dfr_test/appfreeze_manager_test/BUILD.gn +++ b/test/unittest/dfr_test/appfreeze_manager_test/BUILD.gn @@ -93,6 +93,10 @@ ohos_unittest("appfreeze_manager_test") { external_deps += [ "hitrace:libhitracechain" ] defines += [ "ABILITY_RUNTIME_HITRACE_ENABLE" ] } + + if (ability_runtime_appfreeze_fault_data_enable) { + defines += [ "ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE" ] + } } ############################################################################### diff --git a/test/unittest/dfr_test/appfreeze_manager_test/appfreeze_manager_test.cpp b/test/unittest/dfr_test/appfreeze_manager_test/appfreeze_manager_test.cpp index ab700c31e9f..2276e41ee9b 100644 --- a/test/unittest/dfr_test/appfreeze_manager_test/appfreeze_manager_test.cpp +++ b/test/unittest/dfr_test/appfreeze_manager_test/appfreeze_manager_test.cpp @@ -275,7 +275,7 @@ HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_AppFreezeFilter_002, TestSiz int32_t pid = static_cast(getprocpid()); std::string bundleName = "AppfreezeManagerTest_AppFreezeFilter_002"; EXPECT_TRUE(appfreezeManager->CancelAppFreezeDetect(pid, bundleName)); - EXPECT_TRUE(!appfreezeManager->IsProcessDebug(pid, bundleName)); + appfreezeManager->IsProcessDebug(pid, bundleName); appfreezeManager->RemoveDeathProcess(bundleName); } @@ -311,24 +311,23 @@ HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_ParseDecToHex_001, TestSize. #ifdef ABILITY_RUNTIME_HITRACE_ENABLE /** - * @tc.number: AppfreezeManagerTest_GetHitraceId_001 + * @tc.number: AppfreezeManagerTest_GetHitraceInfo_001 * @tc.desc: add testcase codecoverage * @tc.type: FUNC */ -HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_GetHitraceId_001, TestSize.Level1) +HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_GetHitraceInfo_001, TestSize.Level1) { - AppfreezeManager::HitraceInfo info; - bool ret = appfreezeManager->GetHitraceId(info); - EXPECT_TRUE(!ret); - OHOS::HiviewDFX::HiTraceChain::Begin("AppfreezeManagerTest_GetHitraceId_001", 0); - appfreezeManager->GetHitraceId(info); + std::string ret = appfreezeManager->GetHitraceInfo(); + EXPECT_TRUE(ret.empty()); + OHOS::HiviewDFX::HiTraceChain::Begin("AppfreezeManagerTest_GetHitraceInfo_001", 0); + appfreezeManager->GetHitraceInfo(); FaultData faultData; faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_6S; AppfreezeManager::AppInfo appInfo = { .pid = getpid(), .uid = getuid(), - .bundleName = "AppfreezeManagerTest_GetHitraceId_001", - .processName = "AppfreezeManagerTest_GetHitraceId_001", + .bundleName = "AppfreezeManagerTest_GetHitraceInfo_001", + .processName = "AppfreezeManagerTest_GetHitraceInfo_001", }; int result = appfreezeManager->NotifyANR(faultData, appInfo, "test", "test"); EXPECT_EQ(result, 0); @@ -336,32 +335,77 @@ HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_GetHitraceId_001, TestSize.L #endif /** - * @tc.number: AppfreezeManagerTest_ReportAppfreezeCpuInfo_001 + * @tc.number: AppfreezeManagerTest_InitWarningCpuDetailInfo_001 * @tc.desc: add testcase * @tc.type: FUNC */ -HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_ReportAppfreezeCpuInfo_001, TestSize.Level1) +HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_InitWarningCpuDetailInfo_001, TestSize.Level1) { FaultData faultData; std::string bundleName = "AppfreezeManagerTest"; faultData.appfreezeInfo = "test.txt"; + faultData.errorObject.name = AppFreezeType::APP_INPUT_BLOCK; + int pid = getpid(); + int uid = getuid(); + AppfreezeManager::AppInfo appInfo = { + .pid = pid, + .uid = uid, + .bundleName = bundleName, + .processName = bundleName, + }; + appfreezeManager->InitWarningCpuInfo(faultData, appInfo); + faultData.errorObject.name = AppFreezeType::LIFECYCLE_TIMEOUT; + appfreezeManager->InitWarningCpuInfo(faultData, appInfo); + faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_6S; + appfreezeManager->InitWarningCpuInfo(faultData, appInfo); + faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_3S; + appfreezeManager->InitWarningCpuInfo(faultData, appInfo); + faultData.errorObject.name = AppFreezeType::LIFECYCLE_HALF_TIMEOUT; + appfreezeManager->InitWarningCpuInfo(faultData, appInfo); + int count = 10; // test value + for (int i = 1; i <= count; i++) { + appInfo.pid += i; + appfreezeManager->InitWarningCpuInfo(faultData, appInfo); + } + while (count > 0) { + count = sleep(count); + } + appInfo.pid = pid; + appfreezeManager->InitWarningCpuInfo(faultData, appInfo); + EXPECT_TRUE(appfreezeManager != nullptr); +} + +/** + * @tc.number: AppfreezeManagerTest_GetAppfreezeInfoPath_001 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(AppfreezeManagerTest, AppfreezeManagerTest_GetAppfreezeInfoPath_001, TestSize.Level1) +{ + FaultData faultData; + std::string bundleName = "AppfreezeManagerTest"; + faultData.errorObject.name = AppFreezeType::APP_INPUT_BLOCK; AppfreezeManager::AppInfo appInfo = { .pid = getpid(), .uid = getuid(), .bundleName = bundleName, .processName = bundleName, }; - std::string freezeInfoFile = appfreezeManager->ReportAppfreezeCpuInfo(faultData, appInfo); - EXPECT_EQ(freezeInfoFile, ""); + std::string ret = appfreezeManager->GetAppfreezeInfoPath(faultData, appInfo); + EXPECT_EQ(ret, ""); + faultData.appfreezeInfo = "test001"; + faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_3S; + ret = appfreezeManager->GetAppfreezeInfoPath(faultData, appInfo); + EXPECT_EQ(ret, faultData.appfreezeInfo); faultData.errorObject.name = AppFreezeType::THREAD_BLOCK_6S; - freezeInfoFile = appfreezeManager->ReportAppfreezeCpuInfo(faultData, appInfo); - EXPECT_TRUE(freezeInfoFile.empty()); + ret = appfreezeManager->GetAppfreezeInfoPath(faultData, appInfo); + EXPECT_TRUE(!ret.empty()); + faultData.errorObject.name = AppFreezeType::LIFECYCLE_HALF_TIMEOUT; - freezeInfoFile = appfreezeManager->ReportAppfreezeCpuInfo(faultData, appInfo); - EXPECT_EQ(freezeInfoFile, ""); + appfreezeManager->InitWarningCpuInfo(faultData, appInfo); faultData.errorObject.name = AppFreezeType::LIFECYCLE_TIMEOUT; - freezeInfoFile = appfreezeManager->ReportAppfreezeCpuInfo(faultData, appInfo); + appfreezeManager->GetAppfreezeInfoPath(faultData, appInfo); } /** diff --git a/test/unittest/dfr_test/appfreeze_state_test/BUILD.gn b/test/unittest/dfr_test/appfreeze_state_test/BUILD.gn index 642724b8179..d42fc89a563 100644 --- a/test/unittest/dfr_test/appfreeze_state_test/BUILD.gn +++ b/test/unittest/dfr_test/appfreeze_state_test/BUILD.gn @@ -75,6 +75,7 @@ ohos_unittest("appfreeze_state_test") { "${ability_runtime_native_path}/appkit:app_context_utils", "${ability_runtime_native_path}/appkit:appkit_native", "${ability_runtime_path}/utils/global/freeze:freeze_util", + "${ability_runtime_services_path}/common:task_handler_wrap", ] external_deps = [ diff --git a/test/unittest/dfr_test/cpu_data_processor_test/cpu_data_processor_test.cpp b/test/unittest/dfr_test/cpu_data_processor_test/cpu_data_processor_test.cpp index df358b92315..15d5fe4d0cd 100644 --- a/test/unittest/dfr_test/cpu_data_processor_test/cpu_data_processor_test.cpp +++ b/test/unittest/dfr_test/cpu_data_processor_test/cpu_data_processor_test.cpp @@ -19,7 +19,6 @@ #include "cpu_data_processor.h" #undef private -#include "appfreeze_data.h" #include "appfreeze_util.h" using namespace testing; @@ -54,19 +53,18 @@ void CpuDataProcessorTest::TearDown(void) {} /** - * @tc.number: GetHandlingHalfCpuData_Test_001 + * @tc.number: GetCpuDetailData_Test_001 * @tc.desc: add testcase * @tc.type: FUNC */ -HWTEST_F(CpuDataProcessorTest, GetHandlingHalfCpuData_Test_001, TestSize.Level1) +HWTEST_F(CpuDataProcessorTest, GetCpuDetailData_Test_001, TestSize.Level1) { std::vector> cpuData; std::vector totalTimeList; - CpuStartTime cpuStartTime; - std::string stackPath = "GetHandlingHalfCpuData_Test_001"; + CpuConsumeTime cpuStartTime; int pid = getpid(); - CpuDataProcessor data(cpuData, totalTimeList, cpuStartTime, stackPath, pid); - EXPECT_TRUE(data.GetHandlingHalfCpuData().size() == 0); + CpuDataProcessor data(cpuData, totalTimeList, cpuStartTime, pid); + EXPECT_TRUE(data.GetCpuDetailData().size() == 0); } /** @@ -78,50 +76,29 @@ HWTEST_F(CpuDataProcessorTest, GetTotalTimeList_Test_001, TestSize.Level1) { std::vector> cpuData; std::vector totalTimeList; - CpuStartTime cpuStartTime; - std::string stackPath = "GetTotalTimeList_Test_001"; + CpuConsumeTime cpuStartTime; int pid = getpid(); - CpuDataProcessor data(cpuData, totalTimeList, cpuStartTime, stackPath, pid); + CpuDataProcessor data(cpuData, totalTimeList, cpuStartTime, pid); EXPECT_TRUE(data.GetTotalTimeList().size() == 0); } /** - * @tc.number: GetCpuStartTime_Test_001 + * @tc.number: GetCpuConsumeTime_Test_001 * @tc.desc: add testcase * @tc.type: FUNC */ -HWTEST_F(CpuDataProcessorTest, GetCpuStartTime_Test_001, TestSize.Level1) +HWTEST_F(CpuDataProcessorTest, GetCpuConsumeTime_Test_001, TestSize.Level1) { std::vector> cpuData; std::vector totalTimeList; - CpuStartTime cpuStartTime = { - .halfStartTime = 1234, - .optimalCpuStartTime = 1234, + CpuConsumeTime cpuStartTime = { + .cpuFaultTime = 1234, + .optimalCpuTime = 1234, }; - std::string stackPath = "GetCpuStartTime_Test_001"; int pid = getpid(); - CpuDataProcessor data(cpuData, totalTimeList, cpuStartTime, stackPath, pid); - EXPECT_EQ(data.GetCpuStartTime().halfStartTime, 1234); - EXPECT_EQ(data.GetCpuStartTime().optimalCpuStartTime, 1234); -} - -/** - * @tc.number: GetStackPath_Test_001 - * @tc.desc: add testcase - * @tc.type: FUNC - */ -HWTEST_F(CpuDataProcessorTest, GetStackPath_Test_001, TestSize.Level1) -{ - std::vector> cpuData; - std::vector totalTimeList; - CpuStartTime cpuStartTime = { - .halfStartTime = 1234, - .optimalCpuStartTime = 1234, - }; - std::string stackPath = "GetStackPath_Test_001"; - int pid = getpid(); - CpuDataProcessor data(cpuData, totalTimeList, cpuStartTime, stackPath, pid); - EXPECT_EQ(data.GetStackPath(), stackPath); + CpuDataProcessor data(cpuData, totalTimeList, cpuStartTime, pid); + EXPECT_EQ(data.GetCpuConsumeTime().cpuFaultTime, 1234); + EXPECT_EQ(data.GetCpuConsumeTime().optimalCpuTime, 1234); } } // namespace AppExecFwk } // namespace OHOS diff --git a/test/unittest/dfr_test/cpu_sys_config_test/BUILD.gn b/test/unittest/dfr_test/cpu_sys_config_test/BUILD.gn new file mode 100644 index 00000000000..d8a1d5f0e8c --- /dev/null +++ b/test/unittest/dfr_test/cpu_sys_config_test/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/test.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +module_output_path = "ability_runtime/freeze_checker" + +############################################################################### + +ohos_unittest("cpu_sys_config_test") { + module_out_path = module_output_path + + include_dirs = [ + "${ability_runtime_services_path}/appdfr/include", + ] + + sources = [ "cpu_sys_config_test.cpp" ] + + deps = [] + + external_deps = [ + "ability_runtime:app_manager", + "googletest:gmock_main", + "googletest:gtest_main", + ] +} + +############################################################################### + +group("unittest") { + testonly = true + deps = [ ":cpu_sys_config_test" ] +} diff --git a/test/unittest/dfr_test/cpu_sys_config_test/cpu_sys_config_test.cpp b/test/unittest/dfr_test/cpu_sys_config_test/cpu_sys_config_test.cpp new file mode 100644 index 00000000000..49fcc74370f --- /dev/null +++ b/test/unittest/dfr_test/cpu_sys_config_test/cpu_sys_config_test.cpp @@ -0,0 +1,209 @@ +/* + * 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 "cpu_sys_config.h" + +#include +#include +#include + +using namespace testing; +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::AppExecFwk; + +namespace OHOS { +namespace AppExecFwk { +class CpuSysConfigTest : public testing::Test { +public: + CpuSysConfigTest() + {} + ~CpuSysConfigTest() + {} + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void CpuSysConfigTest::SetUpTestCase(void) +{} + +void CpuSysConfigTest::TearDownTestCase(void) +{} + +void CpuSysConfigTest::SetUp(void) +{} + +void CpuSysConfigTest::TearDown(void) +{} + +/** + * @tc.number: GetFreqTimePath_Test_001 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetFreqTimePath_Test_001, TestSize.Level1) +{ + int cpu = 0; + EXPECT_TRUE(!CpuSysConfig::GetFreqTimePath(cpu).empty()); +} + +/** + * @tc.number: GetFreqTimePath_Test_002 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetFreqTimePath_Test_002, TestSize.Level1) +{ + int cpu = -1; + std::string path = CpuSysConfig::GetFreqTimePath(cpu); + EXPECT_TRUE(!path.empty()); + std::ifstream fin(path); + EXPECT_TRUE(!fin.is_open()); +} + +/** + * @tc.number: GetFreqTimePath_Test_003 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetFreqTimePath_Test_003, TestSize.Level1) +{ + int cpu = 0; + std::string path = CpuSysConfig::GetFreqTimePath(cpu); + EXPECT_TRUE(!path.empty()); + std::ifstream fin(path); + EXPECT_TRUE(fin.is_open()); +} + +/** + * @tc.number: GetMainThreadRunningTimePath_Test_001 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetMainThreadRunningTimePath_Test_001, TestSize.Level1) +{ + int pid = 0; + EXPECT_TRUE(!CpuSysConfig::GetMainThreadRunningTimePath(pid).empty()); +} + +/** + * @tc.number: GetMainThreadRunningTimePath_Test_002 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetMainThreadRunningTimePath_Test_002, TestSize.Level1) +{ + int pid = -1; + std::string path = CpuSysConfig::GetMainThreadRunningTimePath(pid); + EXPECT_TRUE(!path.empty()); + std::ifstream fin(path); + EXPECT_TRUE(!fin.is_open()); +} + +/** + * @tc.number: GetMainThreadRunningTimePath_Test_003 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetMainThreadRunningTimePath_Test_003, TestSize.Level1) +{ + int pid = 0; + std::string path = CpuSysConfig::GetMainThreadRunningTimePath(pid); + EXPECT_TRUE(!path.empty()); + std::ifstream fin(path); + EXPECT_TRUE(!fin.is_open()); +} + +/** + * @tc.number: GetProcRunningTimePath_Test_001 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetProcRunningTimePath_Test_001, TestSize.Level1) +{ + int pid = 0; + EXPECT_TRUE(!CpuSysConfig::GetProcRunningTimePath(pid).empty()); +} + +/** + * @tc.number: GetProcRunningTimePath_Test_002 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetProcRunningTimePath_Test_002, TestSize.Level1) +{ + int pid = -1; + std::string path = CpuSysConfig::GetProcRunningTimePath(pid); + EXPECT_TRUE(!path.empty()); + std::ifstream fin(path); + EXPECT_TRUE(!fin.is_open()); +} + +/** + * @tc.number: GetProcRunningTimePath_Test_003 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetProcRunningTimePath_Test_003, TestSize.Level1) +{ + int pid = 0; + std::string path = CpuSysConfig::GetProcRunningTimePath(pid); + EXPECT_TRUE(!path.empty()); + std::ifstream fin(path); + EXPECT_TRUE(!fin.is_open()); +} + +/** + * @tc.number: GetMaxCoreDimpsPath_Test_001 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetMaxCoreDimpsPath_Test_001, TestSize.Level1) +{ + int maxCpuCount = 0; + EXPECT_TRUE(!CpuSysConfig::GetMaxCoreDimpsPath(maxCpuCount).empty()); +} + +/** + * @tc.number: GetMaxCoreDimpsPath_Test_002 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetMaxCoreDimpsPath_Test_002, TestSize.Level1) +{ + int maxCpuCount = -1; + std::string path = CpuSysConfig::GetMaxCoreDimpsPath(maxCpuCount); + EXPECT_TRUE(!path.empty()); + std::ifstream fin(path); + EXPECT_TRUE(!fin.is_open()); +} + +/** + * @tc.number: GetMaxCoreDimpsPath_Test_003 + * @tc.desc: add testcase + * @tc.type: FUNC + */ +HWTEST_F(CpuSysConfigTest, GetMaxCoreDimpsPath_Test_003, TestSize.Level1) +{ + int maxCpuCount = 0; + std::string path = CpuSysConfig::GetMaxCoreDimpsPath(maxCpuCount); + EXPECT_TRUE(!path.empty()); + std::ifstream fin(path); + EXPECT_TRUE(fin.is_open()); +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/test/unittest/fault_data/BUILD.gn b/test/unittest/fault_data/BUILD.gn index 74a123db908..b2b20737039 100644 --- a/test/unittest/fault_data/BUILD.gn +++ b/test/unittest/fault_data/BUILD.gn @@ -63,6 +63,11 @@ ohos_unittest("fault_data_test") { if (background_task_mgr_continuous_task_enable) { external_deps += [ "background_task_mgr:bgtaskmgr_innerkits" ] } + + defines = [] + if (ability_runtime_appfreeze_fault_data_enable) { + defines += [ "ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE" ] + } } group("unittest") { diff --git a/test/unittest/fault_data/fault_data_test.cpp b/test/unittest/fault_data/fault_data_test.cpp index 310bae8bf5d..407e4e0c9e6 100644 --- a/test/unittest/fault_data/fault_data_test.cpp +++ b/test/unittest/fault_data/fault_data_test.cpp @@ -20,6 +20,10 @@ #include "message_parcel.h" #undef private +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE +#include "appfreeze_fault_data.h" +#endif + using namespace testing; using namespace testing::ext; @@ -83,7 +87,17 @@ HWTEST_F(FaultDataTest, ReadFromParcel_001, TestSize.Level1) messageFifth.WriteInt32(12); bool retFifth = faultData->ReadFromParcel(messageFifth); EXPECT_EQ(false, retFifth); +} +/** + * @tc.name: FaultDataTest_ReadFromParcel_002 + * @tc.desc: Verify that the ReadFromParcel interface calls normally + * @tc.type: FUNC + */ +HWTEST_F(FaultDataTest, FaultDataTest_ReadFromParcel_002, TestSize.Level1) +{ + auto faultData = std::make_shared(); + std::string helloWord = "HelloWord"; MessageParcel messageSixth; messageSixth.WriteString(helloWord); messageSixth.WriteString(helloWord); @@ -102,6 +116,10 @@ HWTEST_F(FaultDataTest, ReadFromParcel_001, TestSize.Level1) messageSixth.WriteString(helloWord); messageSixth.WriteString(helloWord); messageSixth.WriteString(helloWord); +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + messageSixth.WriteString(helloWord); +#endif + bool retSixth = faultData->ReadFromParcel(messageSixth); EXPECT_EQ(true, retSixth); } @@ -136,6 +154,9 @@ HWTEST_F(FaultDataTest, Unmarshalling_001, TestSize.Level1) message.WriteString(helloWord); message.WriteString(helloWord); message.WriteString(helloWord); +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + message.WriteString(helloWord); +#endif auto retSecond = faultData->Unmarshalling(message); EXPECT_NE(nullptr, retSecond); } @@ -195,7 +216,17 @@ HWTEST_F(FaultDataTest, ReadFromParcel_002, TestSize.Level1) messageFifth.WriteInt32(12); bool retFifth = appFaultDataBySA->ReadFromParcel(messageFifth); EXPECT_EQ(false, retFifth); +} +/** + * @tc.name: ReadFromParcel_003 + * @tc.desc: Verify that the ReadFromParcel interface calls normally + * @tc.type: FUNC + */ +HWTEST_F(FaultDataTest, ReadFromParcel_003, TestSize.Level1) +{ + auto appFaultDataBySA = std::make_shared(); + std::string helloWord = "HelloWord"; MessageParcel messageSixth; messageSixth.WriteString(helloWord); messageSixth.WriteString(helloWord); @@ -213,6 +244,9 @@ HWTEST_F(FaultDataTest, ReadFromParcel_002, TestSize.Level1) messageSixth.WriteString(helloWord); messageSixth.WriteString(helloWord); messageSixth.WriteString(helloWord); +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + messageSixth.WriteString(helloWord); +#endif bool retSixth = appFaultDataBySA->ReadFromParcel(messageSixth); EXPECT_EQ(true, retSixth); } @@ -246,6 +280,9 @@ HWTEST_F(FaultDataTest, Unmarshalling_002, TestSize.Level1) message.WriteString(helloWord); message.WriteString(helloWord); message.WriteString(helloWord); +#ifdef ABILITY_RUNTIME_APPFREEZE_FAULT_DATA_ENABLE + message.WriteString(helloWord); +#endif auto retSecond = appFaultDataBySA->Unmarshalling(message); EXPECT_NE(nullptr, retSecond); } -- Gitee