1 /*
2 * Copyright (c) 2022 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
20 #include "define_multimodal.h"
21
22 #include "input_manager_impl.h"
23 #include "multimodal_input_connect_manager.h"
24
25 namespace OHOS {
26 namespace MMI {
27 namespace {
28 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "ANRHandler" };
29 constexpr int64_t MAX_MARK_PROCESS_DELAY_TIME = 3500000;
30 constexpr int64_t MIN_MARK_PROCESS_DELAY_TIME = 50000;
31 constexpr int32_t INVALID_OR_PROCESSED_ID = -1;
32 constexpr int32_t TIME_TRANSITION = 1000;
33 } // namespace
34
ANRHandler()35 ANRHandler::ANRHandler() {}
36
~ANRHandler()37 ANRHandler::~ANRHandler() {}
38
SetLastProcessedEventStatus(int32_t eventType,bool status)39 void ANRHandler::SetLastProcessedEventStatus(int32_t eventType, bool status)
40 {
41 std::lock_guard<std::mutex> guard(anrMtx_);
42 event_[eventType].sendStatus = status;
43 }
44
UpdateLastProcessedEventId(int32_t eventType,int32_t eventId)45 void ANRHandler::UpdateLastProcessedEventId(int32_t eventType, int32_t eventId)
46 {
47 std::lock_guard<std::mutex> guard(anrMtx_);
48 event_[eventType].lastEventId = eventId;
49 }
50
SetLastProcessedEventId(int32_t eventType,int32_t eventId,int64_t actionTime)51 void ANRHandler::SetLastProcessedEventId(int32_t eventType, int32_t eventId, int64_t actionTime)
52 {
53 CALL_DEBUG_ENTER;
54 if (event_[eventType].lastEventId > eventId) {
55 MMI_HILOGE("Event type:%{public}d, id %{public}d less then last processed lastEventId %{public}d",
56 eventType, eventId, event_[eventType].lastEventId);
57 return;
58 }
59 UpdateLastProcessedEventId(eventType, eventId);
60
61 int64_t currentTime = GetSysClockTime();
62 int64_t timeoutTime = INPUT_UI_TIMEOUT_TIME - (currentTime - actionTime);
63 MMI_HILOGD("Processed event type:%{public}d, id:%{public}d, actionTime:%{public}" PRId64 ", "
64 "currentTime:%{public}" PRId64 ", timeoutTime:%{public}" PRId64,
65 eventType, eventId, actionTime, currentTime, timeoutTime);
66
67 if (!event_[eventType].sendStatus) {
68 if (timeoutTime < MIN_MARK_PROCESS_DELAY_TIME) {
69 SendEvent(eventType, 0);
70 } else {
71 int64_t delayTime;
72 if (timeoutTime >= MAX_MARK_PROCESS_DELAY_TIME) {
73 delayTime = MAX_MARK_PROCESS_DELAY_TIME / TIME_TRANSITION;
74 } else {
75 delayTime = timeoutTime / TIME_TRANSITION;
76 }
77 SendEvent(eventType, delayTime);
78 }
79 }
80 }
81
GetLastProcessedEventId(int32_t eventType)82 int32_t ANRHandler::GetLastProcessedEventId(int32_t eventType)
83 {
84 CALL_DEBUG_ENTER;
85 std::lock_guard<std::mutex> guard(anrMtx_);
86 if (event_[eventType].lastEventId == INVALID_OR_PROCESSED_ID
87 || event_[eventType].lastEventId <= event_[eventType].lastReportId) {
88 MMI_HILOGD("Invalid or processed event type:%{public}d, lastEventId:%{public}d, lastReportId:%{public}d",
89 eventType, event_[eventType].lastEventId, event_[eventType].lastReportId);
90 return INVALID_OR_PROCESSED_ID;
91 }
92
93 event_[eventType].lastReportId = event_[eventType].lastEventId;
94 MMI_HILOGD("Processed event type:%{public}d, lastEventId:%{public}d, lastReportId:%{public}d",
95 eventType, event_[eventType].lastEventId, event_[eventType].lastReportId);
96 return event_[eventType].lastEventId;
97 }
98
MarkProcessed(int32_t eventType)99 void ANRHandler::MarkProcessed(int32_t eventType)
100 {
101 CALL_DEBUG_ENTER;
102 int32_t eventId = GetLastProcessedEventId(eventType);
103 if (eventId == INVALID_OR_PROCESSED_ID) {
104 return;
105 }
106 MMI_HILOGD("Processed event type:%{public}d, id:%{public}d", eventType, eventId);
107 int32_t ret = MultimodalInputConnMgr->MarkProcessed(eventType, eventId);
108 if (ret != 0) {
109 MMI_HILOGE("Send to server failed, ret:%{public}d", ret);
110 }
111 SetLastProcessedEventStatus(eventType, false);
112 }
113
114
SendEvent(int32_t eventType,int64_t delayTime)115 void ANRHandler::SendEvent(int32_t eventType, int64_t delayTime)
116 {
117 CALL_DEBUG_ENTER;
118 MMI_HILOGD("Event type:%{public}d, delayTime:%{public}" PRId64, eventType, delayTime);
119 SetLastProcessedEventStatus(eventType, true);
120 MarkProcessed(eventType);
121 }
122
ResetAnrArray()123 void ANRHandler::ResetAnrArray()
124 {
125 for (int i = 0; i < ANR_EVENT_TYPE_NUM; i++) {
126 event_[i].sendStatus = false;
127 event_[i].lastEventId = -1;
128 event_[i].lastReportId = -1;
129 }
130 }
131 } // namespace MMI
132 } // namespace OHOS