1 /*
2  * Copyright (c) 2023 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 "anr_manager.h"
16 
17 #include <algorithm>
18 #include <vector>
19 
20 #include "dfx_hisysevent.h"
21 #include "entrance_log.h"
22 #include "proto.h"
23 #include "timer_manager.h"
24 #include "window_manager_hilog.h"
25 
26 namespace OHOS {
27 namespace Rosen {
28 namespace {
29 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ANRManager" };
30 constexpr int32_t MAX_ANR_TIMER_COUNT { 64 };
31 constexpr int32_t NONEXISTENT_TIMER_ID { -1 };
32 } // namespace
33 
ANRManager()34 ANRManager::ANRManager() {}
~ANRManager()35 ANRManager::~ANRManager() {}
36 
Init()37 void ANRManager::Init()
38 {
39     CALL_DEBUG_ENTER;
40     SwitchAnr(false);
41     DelayedSingleton<TimerManager>::GetInstance()->Init();
42 }
43 
AddTimer(int32_t eventId,int32_t persistentId)44 void ANRManager::AddTimer(int32_t eventId, int32_t persistentId)
45 {
46     std::lock_guard<std::mutex> guard(mtx_);
47     if (!switcher_) {
48         WLOGFD("Anr is off, dispatch event without timer");
49         return;
50     }
51     if (anrTimerCount_ >= MAX_ANR_TIMER_COUNT) {
52         WLOGFD("AddAnrTimer failed, anrTimerCount exceeded %{public}d", MAX_ANR_TIMER_COUNT);
53         return;
54     }
55     int32_t timerId = DelayedSingleton<TimerManager>::GetInstance()->AddTimer(ANRTimeOutTime::INPUT_UI_TIMEOUT_TIME,
56         [this, eventId, persistentId]() {
57         WLOGFE("Anr callback enter. persistentId:%{public}d, eventId:%{public}d", persistentId, eventId);
58         DelayedSingleton<EventStage>::GetInstance()->SetAnrStatus(persistentId, true);
59         AppInfo appInfo = GetAppInfoByPersistentId(persistentId);
60         DfxHisysevent::ApplicationBlockInput(eventId, appInfo.pid, appInfo.bundleName, persistentId);
61         WLOGFE("Application not responding. persistentId:%{public}d, eventId:%{public}d, pid:%{public}d, "
62             "bundleName:%{public}s", persistentId, eventId, appInfo.pid, appInfo.bundleName.c_str());
63         ExecuteAnrObserver(appInfo.pid);
64         std::vector<int32_t> timerIds = DelayedSingleton<EventStage>::GetInstance()->GetTimerIds(persistentId);
65         for (int32_t item : timerIds) {
66             DelayedSingleton<TimerManager>::GetInstance()->RemoveTimer(item);
67             anrTimerCount_--;
68         }
69         WLOGFE("Anr callback leave. persistentId:%{public}d, eventId:%{public}d", persistentId, eventId);
70     });
71     if (timerId == NONEXISTENT_TIMER_ID) {
72         WLOGFD("AddTimer for eventId:%{public}d, persistentId:%{public}d failed, result from timerManager",
73             eventId, persistentId);
74         return;
75     }
76     anrTimerCount_++;
77     DelayedSingleton<EventStage>::GetInstance()->SaveANREvent(persistentId, eventId, timerId);
78     WLOGFD("AddTimer for persistentId:%{public}d, timerId:%{public}d, eventId:%{public}d",
79         persistentId, timerId, eventId);
80 }
81 
MarkProcessed(int32_t eventId,int32_t persistentId)82 void ANRManager::MarkProcessed(int32_t eventId, int32_t persistentId)
83 {
84     CALL_DEBUG_ENTER;
85     std::lock_guard<std::mutex> guard(mtx_);
86     WLOGFI("MarkProcessed eventId:%{public}d, persistentId:%{public}d", eventId, persistentId);
87     std::vector<int32_t> timerIds = DelayedSingleton<EventStage>::GetInstance()->DelEvents(persistentId, eventId);
88     for (int32_t item : timerIds) {
89         DelayedSingleton<TimerManager>::GetInstance()->RemoveTimer(item);
90         anrTimerCount_--;
91     }
92 }
93 
IsANRTriggered(int32_t persistentId)94 bool ANRManager::IsANRTriggered(int32_t persistentId)
95 {
96     std::lock_guard<std::mutex> guard(mtx_);
97     if (DelayedSingleton<EventStage>::GetInstance()->CheckAnrStatus(persistentId)) {
98         WLOGFE("Application not respond, persistentId:%{public}d -> pid:%{public}d, bundleName:%{public}s",
99             persistentId, applicationMap_[persistentId].pid, applicationMap_[persistentId].bundleName.c_str());
100         return true;
101     }
102     return false;
103 }
104 
OnSessionLost(int32_t persistentId)105 void ANRManager::OnSessionLost(int32_t persistentId)
106 {
107     CALL_DEBUG_ENTER;
108     std::lock_guard<std::mutex> guard(mtx_);
109     WLOGFD("Disconnect session, persistentId:%{public}d -> pid:%{public}d, bundleName:%{public}s",
110         persistentId, applicationMap_[persistentId].pid, applicationMap_[persistentId].bundleName.c_str());
111     RemoveTimers(persistentId);
112     RemovePersistentId(persistentId);
113 }
114 
OnBackground(int32_t persistentId)115 void ANRManager::OnBackground(int32_t persistentId)
116 {
117     CALL_DEBUG_ENTER;
118     std::lock_guard<std::mutex> guard(mtx_);
119     WLOGFD("Background session, persistentId:%{public}d -> pid:%{public}d, bundleName:%{public}s",
120         persistentId, applicationMap_[persistentId].pid, applicationMap_[persistentId].bundleName.c_str());
121     RemoveTimers(persistentId);
122     RemovePersistentId(persistentId);
123 }
124 
SetApplicationInfo(int32_t persistentId,int32_t pid,const std::string & bundleName)125 void ANRManager::SetApplicationInfo(int32_t persistentId, int32_t pid, const std::string& bundleName)
126 {
127     std::lock_guard<std::mutex> guard(mtx_);
128     WLOGFD("PersistentId:%{public}d -> pid:%{public}d, bundleName:%{public}s",
129         persistentId, pid, bundleName.c_str());
130     applicationMap_[persistentId] = { pid, bundleName };
131 }
132 
SetAnrObserver(std::function<void (int32_t)> anrObserver)133 void ANRManager::SetAnrObserver(std::function<void(int32_t)> anrObserver)
134 {
135     CALL_DEBUG_ENTER;
136     std::lock_guard<std::mutex> guard(mtx_);
137     WLOGFD("SetAnrObserver, anrObserver is null:%{public}d", (anrObserver==nullptr));
138     anrObserver_ = anrObserver;
139 }
140 
GetAppInfoByPersistentId(int32_t persistentId)141 ANRManager::AppInfo ANRManager::GetAppInfoByPersistentId(int32_t persistentId)
142 {
143     if (applicationMap_.find(persistentId) != applicationMap_.end()) {
144         WLOGFD("PersistentId:%{public}d -> pid:%{public}d, bundleName:%{public}s",
145             persistentId, applicationMap_[persistentId].pid, applicationMap_[persistentId].bundleName.c_str());
146         return applicationMap_[persistentId];
147     }
148     WLOGFD("No application matches persistentId:%{public}d", persistentId);
149     return ANRManager::AppInfo();
150 }
151 
RemoveTimers(int32_t persistentId)152 void ANRManager::RemoveTimers(int32_t persistentId)
153 {
154     WLOGFD("Remove timers for persistentId:%{public}d", persistentId);
155     std::vector<int32_t> timerIds = DelayedSingleton<EventStage>::GetInstance()->GetTimerIds(persistentId);
156     for (int32_t item : timerIds) {
157         DelayedSingleton<TimerManager>::GetInstance()->RemoveTimer(item);
158         anrTimerCount_--;
159     }
160 }
161 
RemovePersistentId(int32_t persistentId)162 void ANRManager::RemovePersistentId(int32_t persistentId)
163 {
164     WLOGFD("RemovePersistentId:%{public}d", persistentId);
165     applicationMap_.erase(persistentId);
166     DelayedSingleton<EventStage>::GetInstance()->OnSessionLost(persistentId);
167 }
168 
SwitchAnr(bool status)169 void ANRManager::SwitchAnr(bool status)
170 {
171     switcher_ = status;
172     if (switcher_) {
173         WLOGFI("Anr is on");
174     } else {
175         WLOGFI("Anr is off");
176     }
177 }
178 
SetAppInfoGetter(std::function<void (int32_t,std::string &,int32_t)> callback)179 void ANRManager::SetAppInfoGetter(std::function<void(int32_t, std::string&, int32_t)> callback)
180 {
181     CALL_DEBUG_ENTER;
182     std::lock_guard<std::mutex> guard(mtx_);
183     WLOGFD("SetAppInfoGetter, callback is null:%{public}d", (callback==nullptr));
184     appInfoGetter_ = callback;
185 }
186 
GetBundleName(int32_t pid,int32_t uid)187 std::string ANRManager::GetBundleName(int32_t pid, int32_t uid)
188 {
189     CALL_DEBUG_ENTER;
190     std::lock_guard<std::mutex> guard(mtx_);
191     std::string bundleName { "unknown" };
192     if (appInfoGetter_ == nullptr) {
193         WLOGFW("AppInfoGetter is nullptr");
194         return bundleName;
195     }
196     appInfoGetter_(pid, bundleName, uid);
197     return bundleName;
198 }
199 
ExecuteAnrObserver(int32_t pid)200 void ANRManager::ExecuteAnrObserver(int32_t pid)
201 {
202     CALL_DEBUG_ENTER;
203     if (anrObserver_ != nullptr) {
204         anrObserver_(pid);
205     } else {
206         WLOGFE("AnrObserver is nullptr, do nothing, pid:%{public}d", pid);
207     }
208 }
209 } // namespace Rosen
210 } // namespace OHOS
211