1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at 6c29fa5a6Sopenharmony_ci * 7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c29fa5a6Sopenharmony_ci * 9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and 13c29fa5a6Sopenharmony_ci * limitations under the License. 14c29fa5a6Sopenharmony_ci */ 15c29fa5a6Sopenharmony_ci 16c29fa5a6Sopenharmony_ci#include "anr_manager.h" 17c29fa5a6Sopenharmony_ci 18c29fa5a6Sopenharmony_ci#include "ability_manager_client.h" 19c29fa5a6Sopenharmony_ci 20c29fa5a6Sopenharmony_ci#include "dfx_hisysevent.h" 21c29fa5a6Sopenharmony_ci#include "input_event_handler.h" 22c29fa5a6Sopenharmony_ci#include "i_input_windows_manager.h" 23c29fa5a6Sopenharmony_ci#include "mmi_log.h" 24c29fa5a6Sopenharmony_ci#include "napi_constants.h" 25c29fa5a6Sopenharmony_ci#include "proto.h" 26c29fa5a6Sopenharmony_ci#include "timer_manager.h" 27c29fa5a6Sopenharmony_ci 28c29fa5a6Sopenharmony_ci#undef MMI_LOG_DOMAIN 29c29fa5a6Sopenharmony_ci#define MMI_LOG_DOMAIN MMI_LOG_ANRDETECT 30c29fa5a6Sopenharmony_ci#undef MMI_LOG_TAG 31c29fa5a6Sopenharmony_ci#define MMI_LOG_TAG "ANRManager" 32c29fa5a6Sopenharmony_ci 33c29fa5a6Sopenharmony_cinamespace OHOS { 34c29fa5a6Sopenharmony_cinamespace MMI { 35c29fa5a6Sopenharmony_cinamespace { 36c29fa5a6Sopenharmony_ciconst std::string FOUNDATION { "foundation" }; 37c29fa5a6Sopenharmony_ciconstexpr int32_t MAX_TIMER_COUNT { 50 }; 38c29fa5a6Sopenharmony_ciconstexpr int32_t TIME_CONVERT_RATIO { 1000 }; 39c29fa5a6Sopenharmony_ci} // namespace 40c29fa5a6Sopenharmony_ci 41c29fa5a6Sopenharmony_ciANRManager::ANRManager() {} 42c29fa5a6Sopenharmony_ciANRManager::~ANRManager() {} 43c29fa5a6Sopenharmony_ci 44c29fa5a6Sopenharmony_civoid ANRManager::Init(UDSServer &udsServer) 45c29fa5a6Sopenharmony_ci{ 46c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 47c29fa5a6Sopenharmony_ci udsServer_ = &udsServer; 48c29fa5a6Sopenharmony_ci CHKPV(udsServer_); 49c29fa5a6Sopenharmony_ci udsServer_->AddSessionDeletedCallback([this] (SessionPtr session) { 50c29fa5a6Sopenharmony_ci return this->OnSessionLost(session); 51c29fa5a6Sopenharmony_ci } 52c29fa5a6Sopenharmony_ci ); 53c29fa5a6Sopenharmony_ci} 54c29fa5a6Sopenharmony_ci 55c29fa5a6Sopenharmony_ciint32_t ANRManager::MarkProcessed(int32_t pid, int32_t eventType, int32_t eventId) 56c29fa5a6Sopenharmony_ci{ 57c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 58c29fa5a6Sopenharmony_ci MMI_HILOGD("pid:%{public}d, eventType:%{public}d, eventId:%{public}d", pid, eventType, eventId); 59c29fa5a6Sopenharmony_ci SessionPtr sess = udsServer_->GetSessionByPid(pid); 60c29fa5a6Sopenharmony_ci if (sess == nullptr) { 61c29fa5a6Sopenharmony_ci if (pid_ != pid) { 62c29fa5a6Sopenharmony_ci pid_ = pid; 63c29fa5a6Sopenharmony_ci MMI_HILOGE("The sess is null, return value is %{public}d", RET_ERR); 64c29fa5a6Sopenharmony_ci } 65c29fa5a6Sopenharmony_ci return RET_ERR; 66c29fa5a6Sopenharmony_ci } 67c29fa5a6Sopenharmony_ci std::list<int32_t> timerIds = sess->DelEvents(eventType, eventId); 68c29fa5a6Sopenharmony_ci for (int32_t item : timerIds) { 69c29fa5a6Sopenharmony_ci if (item != -1) { 70c29fa5a6Sopenharmony_ci TimerMgr->RemoveTimer(item); 71c29fa5a6Sopenharmony_ci anrTimerCount_--; 72c29fa5a6Sopenharmony_ci MMI_HILOGD("Remove anr timer, anr type:%{public}d, eventId:%{public}d, timer id:%{public}d," 73c29fa5a6Sopenharmony_ci "count:%{public}d", eventType, eventId, item, anrTimerCount_); 74c29fa5a6Sopenharmony_ci } 75c29fa5a6Sopenharmony_ci } 76c29fa5a6Sopenharmony_ci return RET_OK; 77c29fa5a6Sopenharmony_ci} 78c29fa5a6Sopenharmony_ci 79c29fa5a6Sopenharmony_civoid ANRManager::RemoveTimers(SessionPtr sess) 80c29fa5a6Sopenharmony_ci{ 81c29fa5a6Sopenharmony_ci CHKPV(sess); 82c29fa5a6Sopenharmony_ci std::vector<int32_t> DispatchTimerIds = sess->GetTimerIds(ANR_DISPATCH); 83c29fa5a6Sopenharmony_ci for (int32_t item : DispatchTimerIds) { 84c29fa5a6Sopenharmony_ci if (item != -1) { 85c29fa5a6Sopenharmony_ci TimerMgr->RemoveTimer(item); 86c29fa5a6Sopenharmony_ci anrTimerCount_--; 87c29fa5a6Sopenharmony_ci } 88c29fa5a6Sopenharmony_ci } 89c29fa5a6Sopenharmony_ci std::vector<int32_t> MonitorTimerIds = sess->GetTimerIds(ANR_MONITOR); 90c29fa5a6Sopenharmony_ci for (int32_t item : MonitorTimerIds) { 91c29fa5a6Sopenharmony_ci if (item != -1) { 92c29fa5a6Sopenharmony_ci TimerMgr->RemoveTimer(item); 93c29fa5a6Sopenharmony_ci anrTimerCount_--; 94c29fa5a6Sopenharmony_ci } 95c29fa5a6Sopenharmony_ci } 96c29fa5a6Sopenharmony_ci} 97c29fa5a6Sopenharmony_ci 98c29fa5a6Sopenharmony_civoid ANRManager::RemoveTimersByType(SessionPtr sess, int32_t type) 99c29fa5a6Sopenharmony_ci{ 100c29fa5a6Sopenharmony_ci CHKPV(sess); 101c29fa5a6Sopenharmony_ci if (type != ANR_DISPATCH && type != ANR_MONITOR) { 102c29fa5a6Sopenharmony_ci MMI_HILOGE("Remove times failed, your input parm is %{public}d, which is not legal", type); 103c29fa5a6Sopenharmony_ci return; 104c29fa5a6Sopenharmony_ci } 105c29fa5a6Sopenharmony_ci std::vector<int32_t> timerIds = sess->GetTimerIds(ANR_MONITOR); 106c29fa5a6Sopenharmony_ci for (int32_t item : timerIds) { 107c29fa5a6Sopenharmony_ci if (item != -1) { 108c29fa5a6Sopenharmony_ci TimerMgr->RemoveTimer(item); 109c29fa5a6Sopenharmony_ci anrTimerCount_--; 110c29fa5a6Sopenharmony_ci } 111c29fa5a6Sopenharmony_ci } 112c29fa5a6Sopenharmony_ci} 113c29fa5a6Sopenharmony_ci 114c29fa5a6Sopenharmony_civoid ANRManager::AddTimer(int32_t type, int32_t id, int64_t currentTime, SessionPtr sess) 115c29fa5a6Sopenharmony_ci{ 116c29fa5a6Sopenharmony_ci CHKPV(sess); 117c29fa5a6Sopenharmony_ci if (sess->GetTokenType() != TokenType::TOKEN_HAP || sess->GetProgramName() == FOUNDATION) { 118c29fa5a6Sopenharmony_ci MMI_HILOGD("Not application event, skip. pid:%{public}d, anr type:%{public}d", sess->GetPid(), type); 119c29fa5a6Sopenharmony_ci return; 120c29fa5a6Sopenharmony_ci } 121c29fa5a6Sopenharmony_ci if (anrTimerCount_ >= MAX_TIMER_COUNT) { 122c29fa5a6Sopenharmony_ci MMI_HILOGD("Add timer failed, timer count reached the maximum number:%{public}d", MAX_TIMER_COUNT); 123c29fa5a6Sopenharmony_ci return; 124c29fa5a6Sopenharmony_ci } 125c29fa5a6Sopenharmony_ci int32_t timerId = TimerMgr->AddTimer(INPUT_UI_TIMEOUT_TIME / TIME_CONVERT_RATIO, 1, [this, id, type, sess]() { 126c29fa5a6Sopenharmony_ci CHKPV(sess); 127c29fa5a6Sopenharmony_ci if (type == ANR_MONITOR || WIN_MGR->IsWindowVisible(sess->GetPid())) { 128c29fa5a6Sopenharmony_ci sess->SetAnrStatus(type, true); 129c29fa5a6Sopenharmony_ci DfxHisysevent::ApplicationBlockInput(sess); 130c29fa5a6Sopenharmony_ci MMI_HILOG_FREEZEE("Application not responding. pid:%{public}d, anr type:%{public}d, eventId:%{public}d", 131c29fa5a6Sopenharmony_ci sess->GetPid(), type, id); 132c29fa5a6Sopenharmony_ci CHK_INVALID_RV(anrNoticedPid_, "Add anr timer failed, timer count reached the maximum number"); 133c29fa5a6Sopenharmony_ci NetPacket pkt(MmiMessageId::NOTICE_ANR); 134c29fa5a6Sopenharmony_ci pkt << sess->GetPid(); 135c29fa5a6Sopenharmony_ci pkt << id; 136c29fa5a6Sopenharmony_ci if (pkt.ChkRWError()) { 137c29fa5a6Sopenharmony_ci MMI_HILOGE("Packet write failed"); 138c29fa5a6Sopenharmony_ci return; 139c29fa5a6Sopenharmony_ci } 140c29fa5a6Sopenharmony_ci auto fd = udsServer_->GetClientFd(anrNoticedPid_); 141c29fa5a6Sopenharmony_ci if (!udsServer_->SendMsg(fd, pkt)) { 142c29fa5a6Sopenharmony_ci MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL); 143c29fa5a6Sopenharmony_ci return; 144c29fa5a6Sopenharmony_ci } 145c29fa5a6Sopenharmony_ci } 146c29fa5a6Sopenharmony_ci std::vector<int32_t> timerIds = sess->GetTimerIds(type); 147c29fa5a6Sopenharmony_ci for (int32_t item : timerIds) { 148c29fa5a6Sopenharmony_ci if (item != -1) { 149c29fa5a6Sopenharmony_ci TimerMgr->RemoveTimer(item); 150c29fa5a6Sopenharmony_ci anrTimerCount_--; 151c29fa5a6Sopenharmony_ci MMI_HILOGD("Clear anr timer, type:%{public}d, timer id:%{public}d, count:%{public}d", 152c29fa5a6Sopenharmony_ci type, item, anrTimerCount_); 153c29fa5a6Sopenharmony_ci } 154c29fa5a6Sopenharmony_ci } 155c29fa5a6Sopenharmony_ci }); 156c29fa5a6Sopenharmony_ci CHK_INVALID_RV(timerId, "Add anr timer failed, timer count reached the maximum number"); 157c29fa5a6Sopenharmony_ci anrTimerCount_++; 158c29fa5a6Sopenharmony_ci MMI_HILOGD("Add anr timer success, anr type:%{public}d, eventId:%{public}d, timer id:%{public}d, count:%{public}d", 159c29fa5a6Sopenharmony_ci type, id, timerId, anrTimerCount_); 160c29fa5a6Sopenharmony_ci sess->SaveANREvent(type, id, currentTime, timerId); 161c29fa5a6Sopenharmony_ci} 162c29fa5a6Sopenharmony_ci 163c29fa5a6Sopenharmony_cibool ANRManager::TriggerANR(int32_t type, int64_t time, SessionPtr sess) 164c29fa5a6Sopenharmony_ci{ 165c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 166c29fa5a6Sopenharmony_ci CHKPF(udsServer_); 167c29fa5a6Sopenharmony_ci CHKPF(sess); 168c29fa5a6Sopenharmony_ci if (sess->GetTokenType() != TokenType::TOKEN_HAP || sess->GetProgramName() == FOUNDATION) { 169c29fa5a6Sopenharmony_ci MMI_HILOGD("Not application event, skip. pid:%{public}d, anr type:%{public}d", sess->GetPid(), type); 170c29fa5a6Sopenharmony_ci return false; 171c29fa5a6Sopenharmony_ci } 172c29fa5a6Sopenharmony_ci if (sess->CheckAnrStatus(type)) { 173c29fa5a6Sopenharmony_ci MMI_HILOGD("Application not responding. pid:%{public}d, anr type:%{public}d", sess->GetPid(), type); 174c29fa5a6Sopenharmony_ci return true; 175c29fa5a6Sopenharmony_ci } 176c29fa5a6Sopenharmony_ci MMI_HILOGD("Event dispatch normal"); 177c29fa5a6Sopenharmony_ci return false; 178c29fa5a6Sopenharmony_ci} 179c29fa5a6Sopenharmony_ci 180c29fa5a6Sopenharmony_civoid ANRManager::OnSessionLost(SessionPtr session) 181c29fa5a6Sopenharmony_ci{ 182c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 183c29fa5a6Sopenharmony_ci CHKPV(session); 184c29fa5a6Sopenharmony_ci if (anrNoticedPid_ == session->GetPid()) { 185c29fa5a6Sopenharmony_ci MMI_HILOGI("The anrNoticedPid_ changes to invalid"); 186c29fa5a6Sopenharmony_ci anrNoticedPid_ = -1; 187c29fa5a6Sopenharmony_ci } 188c29fa5a6Sopenharmony_ci MMI_HILOGI("SessionLost remove all Timers"); 189c29fa5a6Sopenharmony_ci RemoveTimers(session); 190c29fa5a6Sopenharmony_ci} 191c29fa5a6Sopenharmony_ci 192c29fa5a6Sopenharmony_ciint32_t ANRManager::SetANRNoticedPid(int32_t pid) 193c29fa5a6Sopenharmony_ci{ 194c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 195c29fa5a6Sopenharmony_ci anrNoticedPid_ = pid; 196c29fa5a6Sopenharmony_ci return RET_OK; 197c29fa5a6Sopenharmony_ci} 198c29fa5a6Sopenharmony_ci} // namespace MMI 199c29fa5a6Sopenharmony_ci} // namespace OHOS 200