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