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
16 #include "anr_handler.h"
17
18 #include <cinttypes>
19 #include <functional>
20 #include <string>
21
22 #include "entrance_log.h"
23 #include "proto.h"
24 #include "util.h"
25 #include "window_manager_hilog.h"
26
27 namespace OHOS {
28 namespace Rosen {
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ANRHandler" };
31 constexpr int64_t MAX_MARK_PROCESS_DELAY_TIME { 3500000 };
32 constexpr int64_t MIN_MARK_PROCESS_DELAY_TIME { 50000 };
33 constexpr int32_t INVALID_EVENT_ID { -1 };
34 constexpr int32_t INVALID_PERSISTENT_ID { -1 };
35 constexpr int32_t TIME_TRANSITION { 1000 };
36 const std::string ANR_HANDLER_RUNNER { "ANR_HANDLER" };
37 } // namespace
38
ANRHandler()39 ANRHandler::ANRHandler()
40 {
41 auto runner = AppExecFwk::EventRunner::Create(ANR_HANDLER_RUNNER);
42 if (runner == nullptr) {
43 WLOGFE("Create eventRunner failed");
44 return;
45 }
46 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
47 }
48
~ANRHandler()49 ANRHandler::~ANRHandler() {}
50
SetSessionStage(int32_t eventId,const wptr<ISessionStage> & sessionStage)51 void ANRHandler::SetSessionStage(int32_t eventId, const wptr<ISessionStage> &sessionStage)
52 {
53 std::lock_guard<std::recursive_mutex> lock(mutex_);
54 sessionStageMap_[eventId] = sessionStage;
55 }
56
HandleEventConsumed(int32_t eventId,int64_t actionTime)57 void ANRHandler::HandleEventConsumed(int32_t eventId, int64_t actionTime)
58 {
59 std::lock_guard<std::recursive_mutex> lock(mutex_);
60 int32_t currentPersistentId = GetPersistentIdOfEvent(eventId);
61 WLOGFD("Processed eventId:%{public}d, persistentId:%{public}d", eventId, currentPersistentId);
62 if (IsOnEventHandler(currentPersistentId)) {
63 UpdateLatestEventId(eventId);
64 return;
65 }
66 int64_t currentTime = GetSysClockTime();
67 int64_t timeoutTime = ANRTimeOutTime::INPUT_UI_TIMEOUT_TIME * TIME_TRANSITION - (currentTime - actionTime);
68 WLOGFD("Processed eventId:%{public}d, persistentId:%{public}d, actionTime:%{public}" PRId64 ", "
69 "currentTime:%{public}" PRId64 ", timeoutTime:%{public}" PRId64,
70 eventId, currentPersistentId, actionTime, currentTime, timeoutTime);
71 if (timeoutTime < MIN_MARK_PROCESS_DELAY_TIME) {
72 SendEvent(eventId, 0);
73 } else {
74 int64_t delayTime = 0;
75 if (timeoutTime >= MAX_MARK_PROCESS_DELAY_TIME) {
76 delayTime = MAX_MARK_PROCESS_DELAY_TIME / TIME_TRANSITION;
77 } else {
78 delayTime = timeoutTime / TIME_TRANSITION;
79 }
80 SendEvent(eventId, delayTime);
81 }
82 }
83
ClearDestroyedPersistentId(int32_t persistentId)84 void ANRHandler::ClearDestroyedPersistentId(int32_t persistentId)
85 {
86 CALL_DEBUG_ENTER;
87 std::lock_guard<std::recursive_mutex> lock(mutex_);
88 if (anrHandlerState_.sendStatus.find(persistentId) == anrHandlerState_.sendStatus.end()) {
89 WLOGFE("PersistentId:%{public}d not in ANRHandler", persistentId);
90 return;
91 }
92 anrHandlerState_.sendStatus.erase(persistentId);
93 WLOGFD("PersistentId:%{public}d erased in ANRHandler", persistentId);
94 }
95
SetAnrHandleState(int32_t eventId,bool status)96 void ANRHandler::SetAnrHandleState(int32_t eventId, bool status)
97 {
98 CALL_DEBUG_ENTER;
99 std::lock_guard<std::recursive_mutex> lock(mutex_);
100 int32_t persistentId = GetPersistentIdOfEvent(eventId);
101 anrHandlerState_.sendStatus[persistentId] = status;
102 if (status) {
103 anrHandlerState_.eventsToReceipt.push_back(eventId);
104 } else {
105 anrHandlerState_.eventsToReceipt.pop_front();
106 ClearExpiredEvents(eventId);
107 }
108 }
109
MarkProcessed()110 void ANRHandler::MarkProcessed()
111 {
112 CALL_DEBUG_ENTER;
113 std::lock_guard<std::recursive_mutex> lock(mutex_);
114 if (anrHandlerState_.eventsToReceipt.empty()) {
115 WLOGFE("Events to receipt is empty");
116 SetAnrHandleState(INVALID_EVENT_ID, false);
117 return;
118 }
119 int32_t eventId = anrHandlerState_.eventsToReceipt.front();
120 WLOGFD("EventId:%{public}d ", eventId);
121 if (sessionStageMap_.find(eventId) == sessionStageMap_.end()) {
122 WLOGFE("SessionStage for eventId:%{public}d is not in sessionStageMap", eventId);
123 } else if (sessionStageMap_[eventId] == nullptr) {
124 WLOGFE("SessionStage for eventId:%{public}d is nullptr", eventId);
125 } else if (WSError ret = sessionStageMap_[eventId]->MarkProcessed(eventId); ret != WSError::WS_OK) {
126 WLOGFE("Send to sceneBoard failed, ret:%{public}d", ret);
127 }
128 SetAnrHandleState(eventId, false);
129 }
130
SendEvent(int32_t eventId,int64_t delayTime)131 void ANRHandler::SendEvent(int32_t eventId, int64_t delayTime)
132 {
133 CALL_DEBUG_ENTER;
134 std::lock_guard<std::recursive_mutex> lock(mutex_);
135 SetAnrHandleState(eventId, true);
136 if (eventHandler_ == nullptr) {
137 WLOGFE("EventHandler is nullptr");
138 SetAnrHandleState(eventId, false);
139 return;
140 }
141 if (!eventHandler_->PostHighPriorityTask(std::bind(&ANRHandler::MarkProcessed, this), delayTime)) {
142 WLOGFE("Send dispatch event failed");
143 }
144 }
145
ClearExpiredEvents(int32_t eventId)146 void ANRHandler::ClearExpiredEvents(int32_t eventId)
147 {
148 CALL_DEBUG_ENTER;
149 std::lock_guard<std::recursive_mutex> lock(mutex_);
150 int32_t persistentId = GetPersistentIdOfEvent(eventId);
151 for (auto iter = sessionStageMap_.begin(); iter != sessionStageMap_.end();) {
152 auto currentPersistentId = GetPersistentIdOfEvent(iter->first);
153 if (iter->first < eventId &&
154 (currentPersistentId == persistentId || currentPersistentId == INVALID_PERSISTENT_ID)) {
155 sessionStageMap_.erase(iter++);
156 } else {
157 iter++;
158 }
159 }
160 }
161
GetPersistentIdOfEvent(int32_t eventId)162 int32_t ANRHandler::GetPersistentIdOfEvent(int32_t eventId)
163 {
164 std::lock_guard<std::recursive_mutex> lock(mutex_);
165 if (sessionStageMap_.find(eventId) == sessionStageMap_.end()) {
166 WLOGFE("No sessionStage for eventId:%{public}d", eventId);
167 return INVALID_PERSISTENT_ID;
168 }
169 auto sessionStage = sessionStageMap_[eventId];
170 if (sessionStage == nullptr) {
171 WLOGFE("SessionStage for eventId:%{public}d is nullptr", eventId);
172 return INVALID_PERSISTENT_ID;
173 }
174 return sessionStage->GetPersistentId();
175 }
176
IsOnEventHandler(int32_t persistentId)177 bool ANRHandler::IsOnEventHandler(int32_t persistentId)
178 {
179 std::lock_guard<std::recursive_mutex> lock(mutex_);
180 if (anrHandlerState_.sendStatus.find(persistentId) != anrHandlerState_.sendStatus.end() &&
181 anrHandlerState_.sendStatus[persistentId]) {
182 return true;
183 }
184 return false;
185 }
186
UpdateLatestEventId(int32_t eventId)187 void ANRHandler::UpdateLatestEventId(int32_t eventId)
188 {
189 std::lock_guard<std::recursive_mutex> lock(mutex_);
190 auto currentPersistentId = GetPersistentIdOfEvent(eventId);
191 for (auto& event : anrHandlerState_.eventsToReceipt) {
192 if (GetPersistentIdOfEvent(event) == currentPersistentId && eventId > event) {
193 WLOGFD("Replace eventId:%{public}d by newer eventId:%{public}d", event, eventId);
194 event = eventId;
195 break;
196 }
197 }
198 }
199 } // namespace Rosen
200 } // namespace OHOS
201