1 /*
2  * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "appfreeze_manager.h"
16 
17 #include <fcntl.h>
18 #include <sys/time.h>
19 #include <sys/wait.h>
20 #include <sys/types.h>
21 #include <sys/syscall.h>
22 #include <sys/stat.h>
23 #include <fstream>
24 
25 #include "faultloggerd_client.h"
26 #include "file_ex.h"
27 #include "ffrt.h"
28 #include "dfx_dump_catcher.h"
29 #include "directory_ex.h"
30 #include "hisysevent.h"
31 #include "hitrace_meter.h"
32 #include "parameter.h"
33 #include "singleton.h"
34 
35 #include "app_mgr_client.h"
36 #include "hilog_tag_wrapper.h"
37 #include "time_util.h"
38 
39 namespace OHOS {
40 namespace AppExecFwk {
41 namespace {
42 constexpr char EVENT_UID[] = "UID";
43 constexpr char EVENT_PID[] = "PID";
44 constexpr char EVENT_INPUT_ID[] = "INPUT_ID";
45 constexpr char EVENT_MESSAGE[] = "MSG";
46 constexpr char EVENT_PACKAGE_NAME[] = "PACKAGE_NAME";
47 constexpr char EVENT_PROCESS_NAME[] = "PROCESS_NAME";
48 constexpr char EVENT_STACK[] = "STACK";
49 constexpr char BINDER_INFO[] = "BINDER_INFO";
50 constexpr char APP_RUNNING_UNIQUE_ID[] = "APP_RUNNING_UNIQUE_ID";
51 constexpr char FREEZE_MEMORY[] = "FREEZE_MEMORY";
52 constexpr int MAX_LAYER = 8;
53 constexpr int FREEZEMAP_SIZE_MAX = 20;
54 constexpr int FREEZE_TIME_LIMIT = 60000;
55 static constexpr int64_t NANOSECONDS = 1000000000;  // NANOSECONDS mean 10^9 nano second
56 static constexpr int64_t MICROSECONDS = 1000000;    // MICROSECONDS mean 10^6 millias second
57 constexpr uint64_t SEC_TO_MILLISEC = 1000;
58 const std::string LOG_FILE_PATH = "data/log/eventlog";
59 }
60 std::shared_ptr<AppfreezeManager> AppfreezeManager::instance_ = nullptr;
61 ffrt::mutex AppfreezeManager::singletonMutex_;
62 ffrt::mutex AppfreezeManager::freezeMutex_;
63 ffrt::mutex AppfreezeManager::catchStackMutex_;
64 std::map<int, std::string> AppfreezeManager::catchStackMap_;
65 ffrt::mutex AppfreezeManager::freezeFilterMutex_;
66 
AppfreezeManager()67 AppfreezeManager::AppfreezeManager()
68 {
69     name_ = "AppfreezeManager" + std::to_string(GetMilliseconds());
70 }
71 
~AppfreezeManager()72 AppfreezeManager::~AppfreezeManager()
73 {
74 }
75 
GetInstance()76 std::shared_ptr<AppfreezeManager> AppfreezeManager::GetInstance()
77 {
78     if (instance_ == nullptr) {
79         std::lock_guard<ffrt::mutex> lock(singletonMutex_);
80         if (instance_ == nullptr) {
81             instance_ = std::make_shared<AppfreezeManager>();
82         }
83     }
84     return instance_;
85 }
86 
DestroyInstance()87 void AppfreezeManager::DestroyInstance()
88 {
89     std::lock_guard<ffrt::mutex> lock(singletonMutex_);
90     if (instance_ != nullptr) {
91         instance_.reset();
92         instance_ = nullptr;
93     }
94 }
95 
GetMilliseconds()96 uint64_t AppfreezeManager::GetMilliseconds()
97 {
98     auto now = std::chrono::system_clock::now();
99     auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
100     return millisecs.count();
101 }
102 
IsHandleAppfreeze(const std::string& bundleName)103 bool AppfreezeManager::IsHandleAppfreeze(const std::string& bundleName)
104 {
105     if (bundleName.empty()) {
106         return true;
107     }
108     return !DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->IsAttachDebug(bundleName);
109 }
110 
AppfreezeHandle(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo)111 int AppfreezeManager::AppfreezeHandle(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo)
112 {
113     TAG_LOGD(AAFwkTag::APPDFR, "called %{public}s, bundleName %{public}s, name_ %{public}s",
114         faultData.errorObject.name.c_str(), appInfo.bundleName.c_str(), name_.c_str());
115     if (!IsHandleAppfreeze(appInfo.bundleName)) {
116         return -1;
117     }
118     HITRACE_METER_FMT(HITRACE_TAG_APP, "AppfreezeHandler:%{public}s bundleName:%{public}s",
119         faultData.errorObject.name.c_str(), appInfo.bundleName.c_str());
120     std::string memoryContent = "";
121     CollectFreezeSysMemory(memoryContent);
122     if (faultData.errorObject.name == AppFreezeType::APP_INPUT_BLOCK) {
123         AcquireStack(faultData, appInfo, memoryContent);
124     } else {
125         NotifyANR(faultData, appInfo, "", memoryContent);
126     }
127     return 0;
128 }
129 
CollectFreezeSysMemory(std::string& memoryContent)130 void AppfreezeManager::CollectFreezeSysMemory(std::string& memoryContent)
131 {
132     std::string tmp = "";
133     std::string pressMemInfo = "/proc/pressure/memory";
134     OHOS::LoadStringFromFile(pressMemInfo, tmp);
135     memoryContent = tmp + "\n";
136     std::string memInfoPath = "/proc/memview";
137     if (!OHOS::FileExists(memInfoPath)) {
138         memInfoPath = "/proc/meminfo";
139     }
140     OHOS::LoadStringFromFile(memInfoPath, tmp);
141     memoryContent += tmp;
142 }
143 
AppfreezeHandleWithStack(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo)144 int AppfreezeManager::AppfreezeHandleWithStack(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo)
145 {
146     TAG_LOGD(AAFwkTag::APPDFR, "called %{public}s, bundleName %{public}s, name_ %{public}s",
147         faultData.errorObject.name.c_str(), appInfo.bundleName.c_str(), name_.c_str());
148     if (!IsHandleAppfreeze(appInfo.bundleName)) {
149         return -1;
150     }
151     FaultData faultNotifyData;
152     faultNotifyData.errorObject.name = faultData.errorObject.name;
153     faultNotifyData.errorObject.message = faultData.errorObject.message;
154     faultNotifyData.errorObject.stack = faultData.errorObject.stack;
155     faultNotifyData.faultType = FaultDataType::APP_FREEZE;
156     faultNotifyData.eventId = faultData.eventId;
157 
158     HITRACE_METER_FMT(HITRACE_TAG_APP, "AppfreezeHandleWithStack pid:%d-name:%s",
159         appInfo.pid, faultData.errorObject.name.c_str());
160     if (faultData.errorObject.name == AppFreezeType::LIFECYCLE_TIMEOUT
161         || faultData.errorObject.name == AppFreezeType::APP_INPUT_BLOCK
162         || faultData.errorObject.name == AppFreezeType::THREAD_BLOCK_6S) {
163         if (AppExecFwk::AppfreezeManager::GetInstance()->IsNeedIgnoreFreezeEvent(appInfo.pid)) {
164             TAG_LOGE(AAFwkTag::APPDFR, "appFreeze happend");
165             return 0;
166         }
167     }
168 
169     std::string memoryContent = "";
170     CollectFreezeSysMemory(memoryContent);
171     std::string fileName = faultData.errorObject.name + "_" +
172         AbilityRuntime::TimeUtil::FormatTime("%Y%m%d%H%M%S") + "_" + std::to_string(appInfo.pid) + "_stack";
173     std::string catcherStack = "";
174     std::string catchJsonStack = "";
175     std::string fullStackPath = "";
176     if (faultData.errorObject.name == AppFreezeType::LIFECYCLE_HALF_TIMEOUT
177         || faultData.errorObject.name == AppFreezeType::LIFECYCLE_TIMEOUT) {
178         catcherStack += CatcherStacktrace(appInfo.pid);
179         fullStackPath = WriteToFile(fileName, catcherStack);
180         faultNotifyData.errorObject.stack = fullStackPath;
181     } else {
182         auto start = GetMilliseconds();
183         std::string timeStamp = "\nTimestamp:" + AbilityRuntime::TimeUtil::FormatTime("%Y-%m-%d %H:%M:%S") +
184             ":" + std::to_string(start % SEC_TO_MILLISEC);
185         faultNotifyData.errorObject.message += timeStamp;
186         catchJsonStack += CatchJsonStacktrace(appInfo.pid, faultData.errorObject.name);
187         fullStackPath = WriteToFile(fileName, catchJsonStack);
188         faultNotifyData.errorObject.stack = fullStackPath;
189     }
190     if (faultNotifyData.errorObject.name == AppFreezeType::APP_INPUT_BLOCK) {
191         AcquireStack(faultNotifyData, appInfo, memoryContent);
192     } else {
193         NotifyANR(faultNotifyData, appInfo, "", memoryContent);
194     }
195     return 0;
196 }
197 
WriteToFile(const std::string& fileName, std::string& content)198 std::string AppfreezeManager::WriteToFile(const std::string& fileName, std::string& content)
199 {
200     std::string dir_path = LOG_FILE_PATH + "/freeze";
201     constexpr mode_t defaultLogDirMode = 0770;
202     if (!OHOS::FileExists(dir_path)) {
203         OHOS::ForceCreateDirectory(dir_path);
204         OHOS::ChangeModeDirectory(dir_path, defaultLogDirMode);
205     }
206     std::string realPath;
207     if (!OHOS::PathToRealPath(dir_path, realPath)) {
208         TAG_LOGE(AAFwkTag::APPDFR, "pathToRealPath failed:%{public}s", dir_path.c_str());
209         return "";
210     }
211     std::string stackPath = realPath + "/" + fileName;
212     constexpr mode_t defaultLogFileMode = 0644;
213     auto fd = open(stackPath.c_str(), O_CREAT | O_WRONLY | O_TRUNC, defaultLogFileMode);
214     if (fd < 0) {
215         TAG_LOGI(AAFwkTag::APPDFR, "stackPath create failed");
216         return "";
217     } else {
218         TAG_LOGI(AAFwkTag::APPDFR, "stackPath: %{public}s", stackPath.c_str());
219     }
220     OHOS::SaveStringToFd(fd, content);
221     close(fd);
222     return stackPath;
223 }
224 
LifecycleTimeoutHandle(const ParamInfo& info, FreezeUtil::LifecycleFlow flow)225 int AppfreezeManager::LifecycleTimeoutHandle(const ParamInfo& info, FreezeUtil::LifecycleFlow flow)
226 {
227     if (info.typeId != AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT) {
228         return -1;
229     }
230     if (!IsHandleAppfreeze(info.bundleName)) {
231         return -1;
232     }
233     if (info.eventName != AppFreezeType::LIFECYCLE_TIMEOUT &&
234         info.eventName != AppFreezeType::LIFECYCLE_HALF_TIMEOUT) {
235         return -1;
236     }
237     TAG_LOGD(AAFwkTag::APPDFR, "called %{public}s, name_ %{public}s", info.bundleName.c_str(),
238         name_.c_str());
239     HITRACE_METER_FMT(HITRACE_TAG_APP, "LifecycleTimeoutHandle:%{public}s bundleName:%{public}s",
240         info.eventName.c_str(), info.bundleName.c_str());
241     AppFaultDataBySA faultDataSA;
242     faultDataSA.errorObject.name = info.eventName;
243     faultDataSA.errorObject.message = info.msg;
244     faultDataSA.faultType = FaultDataType::APP_FREEZE;
245     faultDataSA.timeoutMarkers = "notifyFault" +
246                                  std::to_string(info.pid) +
247                                  "-" + std::to_string(GetMilliseconds());
248     faultDataSA.pid = info.pid;
249     if (flow.state != AbilityRuntime::FreezeUtil::TimeoutState::UNKNOWN) {
250         faultDataSA.token = flow.token;
251         faultDataSA.state = static_cast<uint32_t>(flow.state);
252     }
253     DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->NotifyAppFaultBySA(faultDataSA);
254     return 0;
255 }
256 
AcquireStack(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo, const std::string& memoryContent)257 int AppfreezeManager::AcquireStack(const FaultData& faultData,
258     const AppfreezeManager::AppInfo& appInfo, const std::string& memoryContent)
259 {
260     int ret = 0;
261     int pid = appInfo.pid;
262     FaultData faultNotifyData;
263     faultNotifyData.errorObject.name = faultData.errorObject.name;
264     faultNotifyData.errorObject.message = faultData.errorObject.message;
265     faultNotifyData.errorObject.stack = faultData.errorObject.stack;
266     faultNotifyData.faultType = FaultDataType::APP_FREEZE;
267     faultNotifyData.eventId = faultData.eventId;
268     std::string binderInfo;
269     std::string binderPidsStr;
270     std::set<int> pids = GetBinderPeerPids(binderInfo, pid);
271     for (auto& pidTemp : pids) {
272         TAG_LOGI(AAFwkTag::APPDFR, "pidTemp pids:%{public}d", pidTemp);
273         if (pidTemp != pid) {
274             std::string content = "PeerBinder catcher stacktrace for pid : " + std::to_string(pidTemp) + "\n";
275             content += CatcherStacktrace(pidTemp);
276             binderInfo += content;
277             binderPidsStr += " " + std::to_string(pidTemp);
278         }
279     }
280 
281     if (pids.empty()) {
282         binderInfo +="PeerBinder pids is empty\n";
283     }
284 
285     std::string fileName = faultData.errorObject.name + "_" +
286         AbilityRuntime::TimeUtil::FormatTime("%Y%m%d%H%M%S") + "_" + std::to_string(appInfo.pid) + "_binder";
287     std::string fullStackPath = WriteToFile(fileName, binderInfo);
288     binderInfo = fullStackPath + "," + binderPidsStr;
289 
290     ret = NotifyANR(faultNotifyData, appInfo, binderInfo, memoryContent);
291     return ret;
292 }
293 
NotifyANR(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo, const std::string& binderInfo, const std::string& memoryContent)294 int AppfreezeManager::NotifyANR(const FaultData& faultData, const AppfreezeManager::AppInfo& appInfo,
295     const std::string& binderInfo, const std::string& memoryContent)
296 {
297     std::string appRunningUniqueId = "";
298     DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetAppRunningUniqueIdByPid(appInfo.pid,
299         appRunningUniqueId);
300     int ret = 0;
301     if (faultData.errorObject.name == AppFreezeType::APP_INPUT_BLOCK) {
302         ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, faultData.errorObject.name,
303             OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_UID, appInfo.uid, EVENT_PID, appInfo.pid,
304             EVENT_PACKAGE_NAME, appInfo.bundleName, EVENT_PROCESS_NAME, appInfo.processName, EVENT_MESSAGE,
305             faultData.errorObject.message, EVENT_STACK, faultData.errorObject.stack, BINDER_INFO, binderInfo,
306             APP_RUNNING_UNIQUE_ID, appRunningUniqueId, EVENT_INPUT_ID, faultData.eventId,
307             FREEZE_MEMORY, memoryContent);
308     } else {
309         ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, faultData.errorObject.name,
310             OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_UID, appInfo.uid, EVENT_PID, appInfo.pid,
311             EVENT_PACKAGE_NAME, appInfo.bundleName, EVENT_PROCESS_NAME, appInfo.processName, EVENT_MESSAGE,
312             faultData.errorObject.message, EVENT_STACK, faultData.errorObject.stack, BINDER_INFO, binderInfo,
313             APP_RUNNING_UNIQUE_ID, appRunningUniqueId, FREEZE_MEMORY, memoryContent);
314     }
315     TAG_LOGI(AAFwkTag::APPDFR,
316         "reportEvent:%{public}s, pid:%{public}d, bundleName:%{public}s, appRunningUniqueId:%{public}s"
317         ", eventId:%{public}d hisysevent write ret: %{public}d",
318         faultData.errorObject.name.c_str(), appInfo.pid, appInfo.bundleName.c_str(), appRunningUniqueId.c_str(),
319         faultData.eventId, ret);
320     return 0;
321 }
322 
BinderParser(std::ifstream& fin, std::string& stack) const323 std::map<int, std::set<int>> AppfreezeManager::BinderParser(std::ifstream& fin, std::string& stack) const
324 {
325     std::map<int, std::set<int>> binderInfo;
326     const int decimal = 10;
327     std::string line;
328     bool isBinderMatchup = false;
329     TAG_LOGI(AAFwkTag::APPDFR, "start");
330     stack += "BinderCatcher --\n\n";
331     while (getline(fin, line)) {
332         stack += line + "\n";
333         if (isBinderMatchup) {
334             continue;
335         }
336 
337         if (line.find("async\t") != std::string::npos) {
338             continue;
339         }
340 
341         std::istringstream lineStream(line);
342         std::vector<std::string> strList;
343         std::string tmpstr;
344         while (lineStream >> tmpstr) {
345             strList.push_back(tmpstr);
346         }
347 
348         auto SplitPhase = [](const std::string& str, uint16_t index) -> std::string {
349             std::vector<std::string> strings;
350             SplitStr(str, ":", strings);
351             if (index < strings.size()) {
352                 return strings[index];
353             }
354             return "";
355         };
356 
357         if (strList.size() >= 7) { // 7: valid array size
358             // 2: peer id,
359             std::string server = SplitPhase(strList[2], 0);
360             // 0: local id,
361             std::string client = SplitPhase(strList[0], 0);
362             // 5: wait time, s
363             std::string wait = SplitPhase(strList[5], 1);
364             if (server == "" || client == "" || wait == "") {
365                 continue;
366             }
367             int serverNum = std::strtol(server.c_str(), nullptr, decimal);
368             int clientNum = std::strtol(client.c_str(), nullptr, decimal);
369             int waitNum = std::strtol(wait.c_str(), nullptr, decimal);
370             TAG_LOGI(AAFwkTag::APPDFR, "server:%{public}d, client:%{public}d, wait:%{public}d", serverNum, clientNum,
371                 waitNum);
372             binderInfo[clientNum].insert(serverNum);
373         }
374         if (line.find("context") != line.npos) {
375             isBinderMatchup = true;
376         }
377     }
378     TAG_LOGI(AAFwkTag::APPDFR, "binderInfo size: %{public}zu", binderInfo.size());
379     return binderInfo;
380 }
381 
GetBinderPeerPids(std::string& stack, int pid) const382 std::set<int> AppfreezeManager::GetBinderPeerPids(std::string& stack, int pid) const
383 {
384     std::set<int> pids;
385     std::ifstream fin;
386     std::string path = LOGGER_DEBUG_PROC_PATH;
387     char resolvePath[PATH_MAX] = {0};
388     if (realpath(path.c_str(), resolvePath) == nullptr) {
389         TAG_LOGE(AAFwkTag::APPDFR, "invalid realpath");
390         return pids;
391     }
392     fin.open(resolvePath);
393     if (!fin.is_open()) {
394         TAG_LOGE(AAFwkTag::APPDFR, "open failed, %{public}s", resolvePath);
395         stack += "open file failed :" + path + "\r\n";
396         return pids;
397     }
398 
399     stack += "\n\nPeerBinderCatcher -- pid==" + std::to_string(pid) + "\n\n";
400     std::map<int, std::set<int>> binderInfo = BinderParser(fin, stack);
401     fin.close();
402 
403     if (binderInfo.size() == 0 || binderInfo.find(pid) == binderInfo.end()) {
404         return pids;
405     }
406 
407     ParseBinderPids(binderInfo, pids, pid, 0);
408     for (auto& each : pids) {
409         TAG_LOGD(AAFwkTag::APPDFR, "each pids:%{public}d", each);
410     }
411     return pids;
412 }
413 
ParseBinderPids(const std::map<int, std::set<int>>& binderInfo, std::set<int>& pids, int pid, int layer) const414 void AppfreezeManager::ParseBinderPids(const std::map<int, std::set<int>>& binderInfo,
415     std::set<int>& pids, int pid, int layer) const
416 {
417     auto it = binderInfo.find(pid);
418     layer++;
419     if (layer >= MAX_LAYER) {
420         return;
421     }
422     if (it != binderInfo.end()) {
423         for (auto& each : it->second) {
424             pids.insert(each);
425             ParseBinderPids(binderInfo, pids, each, layer);
426         }
427     }
428 }
429 
DeleteStack(int pid)430 void AppfreezeManager::DeleteStack(int pid)
431 {
432     std::lock_guard<ffrt::mutex> lock(catchStackMutex_);
433     auto it = catchStackMap_.find(pid);
434     if (it != catchStackMap_.end()) {
435         catchStackMap_.erase(it);
436     }
437 }
438 
FindStackByPid(std::string& ret, int pid) const439 void AppfreezeManager::FindStackByPid(std::string& ret, int pid) const
440 {
441     std::lock_guard<ffrt::mutex> lock(catchStackMutex_);
442     auto it = catchStackMap_.find(pid);
443     if (it != catchStackMap_.end()) {
444         ret = it->second;
445     }
446 }
447 
CatchJsonStacktrace(int pid, const std::string& faultType) const448 std::string AppfreezeManager::CatchJsonStacktrace(int pid, const std::string& faultType) const
449 {
450     HITRACE_METER_FMT(HITRACE_TAG_APP, "CatchJsonStacktrace pid:%d", pid);
451     HiviewDFX::DfxDumpCatcher dumplog;
452     std::string ret;
453     std::string msg;
454     size_t defaultMaxFaultNum = 256;
455     if (dumplog.DumpCatchProcess(pid, msg, defaultMaxFaultNum, true) == -1) {
456         TAG_LOGI(AAFwkTag::APPDFR, "appfreeze catch stack failed");
457         ret = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + msg;
458         if (faultType == AppFreezeType::APP_INPUT_BLOCK) {
459             FindStackByPid(ret, pid);
460         }
461     } else {
462         ret = msg;
463         if (faultType == AppFreezeType::THREAD_BLOCK_3S) {
464             std::lock_guard<ffrt::mutex> lock(catchStackMutex_);
465             catchStackMap_[pid] = msg;
466         }
467     }
468     return ret;
469 }
470 
CatcherStacktrace(int pid) const471 std::string AppfreezeManager::CatcherStacktrace(int pid) const
472 {
473     HITRACE_METER_FMT(HITRACE_TAG_APP, "CatcherStacktrace pid:%d", pid);
474     HiviewDFX::DfxDumpCatcher dumplog;
475     std::string ret;
476     std::string msg;
477     if (dumplog.DumpCatchProcess(pid, msg) == -1) {
478         ret = "Failed to dump stacktrace for " + std::to_string(pid) + "\n" + msg;
479     } else {
480         ret = msg;
481     }
482     return ret;
483 }
484 
IsProcessDebug(int32_t pid, std::string bundleName)485 bool AppfreezeManager::IsProcessDebug(int32_t pid, std::string bundleName)
486 {
487     std::lock_guard<ffrt::mutex> lock(freezeFilterMutex_);
488     auto it = appfreezeFilterMap_.find(bundleName);
489     if (it != appfreezeFilterMap_.end() && it->second.pid == pid) {
490         if (it->second.state == AppFreezeState::APPFREEZE_STATE_CANCELED) {
491             TAG_LOGI(AAFwkTag::APPDFR, "filtration only once");
492             return false;
493         } else {
494             TAG_LOGI(AAFwkTag::APPDFR, "filtration %{public}s", bundleName.c_str());
495             return true;
496         }
497     }
498 
499     const int buffSize = 128;
500     char paramBundle[buffSize] = {0};
501     GetParameter("hiviewdfx.appfreeze.filter_bundle_name", "", paramBundle, buffSize - 1);
502     std::string debugBundle(paramBundle);
503 
504     if (bundleName.compare(debugBundle) == 0) {
505         TAG_LOGI(AAFwkTag::APPDFR, "filtration %{public}s_%{public}s not exit",
506             debugBundle.c_str(), bundleName.c_str());
507         return true;
508     }
509     return false;
510 }
511 
GetFreezeCurrentTime()512 int64_t AppfreezeManager::GetFreezeCurrentTime()
513 {
514     struct timespec t;
515     t.tv_sec = 0;
516     t.tv_nsec = 0;
517     clock_gettime(CLOCK_MONOTONIC, &t);
518     return static_cast<int64_t>(((t.tv_sec) * NANOSECONDS + t.tv_nsec) / MICROSECONDS);
519 }
520 
SetFreezeState(int32_t pid, int state)521 void AppfreezeManager::SetFreezeState(int32_t pid, int state)
522 {
523     std::lock_guard<ffrt::mutex> lock(freezeMutex_);
524     if (appfreezeInfo_.find(pid) != appfreezeInfo_.end()) {
525         appfreezeInfo_[pid].state = state;
526         appfreezeInfo_[pid].occurTime = GetFreezeCurrentTime();
527     } else {
528         AppFreezeInfo info;
529         info.pid = pid;
530         info.state = state;
531         info.occurTime = GetFreezeCurrentTime();
532         appfreezeInfo_.emplace(pid, info);
533     }
534 }
535 
GetFreezeState(int32_t pid)536 int AppfreezeManager::GetFreezeState(int32_t pid)
537 {
538     std::lock_guard<ffrt::mutex> lock(freezeMutex_);
539     auto it = appfreezeInfo_.find(pid);
540     if (it != appfreezeInfo_.end()) {
541         return it->second.state;
542     }
543     return AppFreezeState::APPFREEZE_STATE_IDLE;
544 }
545 
GetFreezeTime(int32_t pid)546 int64_t AppfreezeManager::GetFreezeTime(int32_t pid)
547 {
548     std::lock_guard<ffrt::mutex> lock(freezeMutex_);
549     auto it = appfreezeInfo_.find(pid);
550     if (it != appfreezeInfo_.end()) {
551         return it->second.occurTime;
552     }
553     return 0;
554 }
555 
ClearOldInfo()556 void AppfreezeManager::ClearOldInfo()
557 {
558     std::lock_guard<ffrt::mutex> lock(freezeMutex_);
559     int64_t currentTime = GetFreezeCurrentTime();
560     for (auto it = appfreezeInfo_.begin(); it != appfreezeInfo_.end();) {
561         auto diff = currentTime - it->second.occurTime;
562         if (diff > FREEZE_TIME_LIMIT) {
563             it = appfreezeInfo_.erase(it);
564         } else {
565             ++it;
566         }
567     }
568 }
569 
IsNeedIgnoreFreezeEvent(int32_t pid)570 bool AppfreezeManager::IsNeedIgnoreFreezeEvent(int32_t pid)
571 {
572     if (appfreezeInfo_.size() >= FREEZEMAP_SIZE_MAX) {
573         ClearOldInfo();
574     }
575     int state = GetFreezeState(pid);
576     int64_t currentTime = GetFreezeCurrentTime();
577     int64_t lastTime = GetFreezeTime(pid);
578     auto diff = currentTime - lastTime;
579     if (state == AppFreezeState::APPFREEZE_STATE_FREEZE) {
580         if (diff >= FREEZE_TIME_LIMIT) {
581             TAG_LOGI(AAFwkTag::APPDFR, "durationTime: "
582                 "%{public}" PRId64 "state: %{public}d", diff, state);
583             return false;
584         }
585         return true;
586     } else {
587         if (currentTime > FREEZE_TIME_LIMIT && diff < FREEZE_TIME_LIMIT) {
588             return true;
589         }
590         SetFreezeState(pid, AppFreezeState::APPFREEZE_STATE_FREEZE);
591         TAG_LOGI(AAFwkTag::APPDFR, "durationTime: "
592             "%{public}" PRId64 " SetFreezeState: %{public}d", diff, state);
593         return false;
594     }
595 }
596 
CancelAppFreezeDetect(int32_t pid, const std::string& bundleName)597 bool AppfreezeManager::CancelAppFreezeDetect(int32_t pid, const std::string& bundleName)
598 {
599     if (bundleName.empty()) {
600         TAG_LOGE(AAFwkTag::APPDFR, "SetAppFreezeFilter bundleName is empty.");
601         return false;
602     }
603     std::lock_guard<ffrt::mutex> lock(freezeFilterMutex_);
604     AppFreezeInfo info;
605     info.pid = pid;
606     info.state = AppFreezeState::APPFREEZE_STATE_CANCELING;
607     appfreezeFilterMap_.emplace(bundleName, info);
608     return true;
609 }
610 
RemoveDeathProcess(std::string bundleName)611 void AppfreezeManager::RemoveDeathProcess(std::string bundleName)
612 {
613     std::lock_guard<ffrt::mutex> lock(freezeFilterMutex_);
614     auto it = appfreezeFilterMap_.find(bundleName);
615     if (it != appfreezeFilterMap_.end()) {
616         TAG_LOGI(AAFwkTag::APPDFR, "Remove bundleName: %{public}s", bundleName.c_str());
617         appfreezeFilterMap_.erase(it);
618     }
619 }
620 
ResetAppfreezeState(int32_t pid, const std::string& bundleName)621 void AppfreezeManager::ResetAppfreezeState(int32_t pid, const std::string& bundleName)
622 {
623     std::lock_guard<ffrt::mutex> lock(freezeFilterMutex_);
624     if (appfreezeFilterMap_.find(bundleName) != appfreezeFilterMap_.end()) {
625         TAG_LOGD(AAFwkTag::APPDFR, "bundleName: %{public}s",
626             bundleName.c_str());
627         appfreezeFilterMap_[bundleName].state = AppFreezeState::APPFREEZE_STATE_CANCELED;
628     }
629 }
630 
IsValidFreezeFilter(int32_t pid, const std::string& bundleName)631 bool AppfreezeManager::IsValidFreezeFilter(int32_t pid, const std::string& bundleName)
632 {
633     std::lock_guard<ffrt::mutex> lock(freezeFilterMutex_);
634     if (appfreezeFilterMap_.find(bundleName) != appfreezeFilterMap_.end()) {
635         return false;
636     }
637     return true;
638 }
639 }  // namespace AAFwk
640 }  // namespace OHOS