diff --git a/services/timer/include/timer_manager.h b/services/timer/include/timer_manager.h index 05e8401916f12257c2d70b0dae8e549f4ec5ecaf..d47dc084414a85ad8d26a603cece70970dfa1862 100644 --- a/services/timer/include/timer_manager.h +++ b/services/timer/include/timer_manager.h @@ -135,8 +135,13 @@ private: void UpdateTimersState(std::shared_ptr &alarm); bool AdjustSingleTimer(std::shared_ptr timer); + void RecordTimerCount(int uid); + void DecreaseTimerCount(int uid); + void WarningAlarmRecord(); + void ShowTimerCountByUid(); std::map> timerEntryMap_; + std::vector> timerCount_; std::default_random_engine random_; std::atomic_bool runFlag_; std::shared_ptr handler_; diff --git a/services/timer/src/timer_manager.cpp b/services/timer/src/timer_manager.cpp index 4800be8518c71f5b1ba9167d4c895598997d5a79..d279044d9f40ffbfe79e3bf5066c53564927b846 100644 --- a/services/timer/src/timer_manager.cpp +++ b/services/timer/src/timer_manager.cpp @@ -152,7 +152,7 @@ int32_t TimerManager::CreateTimer(TimerPara ¶s, uint64_t &timerId, DatabaseType type) { - TIME_HILOGD(TIME_MODULE_SERVICE, + TIME_HILOGI(TIME_MODULE_SERVICE, "Create timer: %{public}d windowLength:%{public}" PRId64 "interval:%{public}" PRId64 "flag:%{public}d" "uid:%{public}d pid:%{public}d timerId:%{public}" PRId64 "", paras.timerType, paras.windowLength, paras.interval, paras.flag, IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid(), timerId); @@ -180,6 +180,7 @@ int32_t TimerManager::CreateTimer(TimerPara ¶s, bundleName }); timerEntryMap_.insert(std::make_pair(timerId, timerInfo)); + RecordTimerCount(timerInfo->uid); } if (type == NOT_STORE) { @@ -198,6 +199,84 @@ void TimerManager::ReCreateTimer(uint64_t timerId, std::shared_ptr t { std::lock_guard lock(entryMapMutex_); timerEntryMap_.insert(std::make_pair(timerId, timerInfo)); + RecordTimerCount(timerInfo->uid); +} + +void TimerManager::RecordTimerCount(int uid) +{ + if (timerCount_.empty()) { + timerCount_.push_back(std::make_pair(uid, 1)); + } else { + auto it = std::find_if(timerCount_.begin(), timerCount_.end(), + [uid](const std::pair& pair) { + return pair.first == uid; + }); + if (it == timerCount_.end()) { + timerCount_.push_back(std::make_pair(uid, 1)); + } else { + it->second++; + } + TIME_HILOGI(TIME_MODULE_SERVICE, "uid: %{public}d has created %{public}d timer", + it->first, it->second); + } +} + +void TimerManager::DecreaseTimerCount(int uid) +{ + auto it = std::find_if(timerCount_.begin(), timerCount_.end(), + [uid](const std::pair& pair) { + return pair.first == uid; + }); + if (it == timerCount_.end()) { + TIME_HILOGI(TIME_MODULE_SERVICE, "uid has no timer"); + } else { + it->second--; + } +} + +void TimerManager::WarningAlarmRecord() +{ + int count = static_cast(timerEntryMap_.size()); + // case1: The number of timers reaches the next standard. + if (count > (timerOutOfRangeTimes_ + 1) * TIMER_ALARM_COUNT) { + timerOutOfRangeFlag_ = 1; + timerOutOfRangeTimes_ += 1; + TIME_HILOGI(TIME_MODULE_SERVICE, "%{public}d timer in system", count); + ShowTimerCountByUid(); + return; + } + // case2: The number of timers decrease to this standard minus 10 + if (count == timerOutOfRangeTimes_ * TIMER_ALARM_COUNT - TIMER_ALRAM_WINDOW_COUNT) { + timerOutOfRangeFlag_ = 0; + timerOutOfRangeTimes_ -= 1; + return; + } + // case3: The number of timers keep this standard for 30 min + auto currentBootTime = GetBootTimeNs(); + if (count > timerOutOfRangeTimes_ * TIMER_ALARM_COUNT && + currentBootTime - lastTimerOutOdRangTime_ > std::chrono::minutes(TIMER_ALRAM_GAP_TIME)) { + TIME_HILOGI(TIME_MODULE_SERVICE, "%{public}d timer in system", count); + ShowTimerCountByUid(); + return; + } +} + +void TimerManager::ShowTimerCountByUid() +{ + auto size = static_cast(timerCount_.size()); + std::sort(timerCount_.begin(), timerCount_.end(), + [](const std::pair& a, std::pair& b) { + return a.second > b.second; + } + ); + auto limitedSize = (size > TIMER_COUNT_TOP_NUM) ? TIMER_COUNT_TOP_NUM : size; + std::for_each(std::begin(timerCount_), std::begin(timerCount_) + limitedSize, + [](const std::pair& pair) { + TIME_HILOGI(TIME_MODULE_SERVICE, "uid: %{public}d has created %{public}d timer", + pair.first, pair.second); + } + ); + lastTimerOutOdRangTime_ = GetBootTimeNs(); } int32_t TimerManager::StartTimer(uint64_t timerId, uint64_t triggerTime) @@ -265,7 +344,10 @@ int32_t TimerManager::StopTimerInner(uint64_t timerNumber, bool needDestroy) TimerProxy::GetInstance().EraseTimerFromProxyUidMap(timerNumber, it->second->uid); TimerProxy::GetInstance().EraseTimerFromProxyPidMap(timerNumber, it->second->pid); needRecoverOnReboot = CheckNeedRecoverOnReboot(it->second->bundleName, it->second->type); - if (needDestroy) { timerEntryMap_.erase(it); } + if (needDestroy) { + DecreaseTimerCount(it->second->uid) + timerEntryMap_.erase(it); + } } TIME_HILOGI(TIME_MODULE_SERVICE, "db bgn"); if (needRecoverOnReboot) {