1 /*
2 * Copyright (c) 2021-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 "timer_manager.h"
17
18 namespace OHOS {
19 namespace MMI {
AddTimer(int32_t intervalMs,int32_t repeatCount,std::function<void ()> callback)20 int32_t TimerManager::AddTimer(int32_t intervalMs, int32_t repeatCount, std::function<void()> callback)
21 {
22 return AddTimerInternal(intervalMs, repeatCount, callback);
23 }
24
RemoveTimer(int32_t timerId)25 int32_t TimerManager::RemoveTimer(int32_t timerId)
26 {
27 return RemoveTimerInternal(timerId);
28 }
29
ResetTimer(int32_t timerId)30 int32_t TimerManager::ResetTimer(int32_t timerId)
31 {
32 return ResetTimerInternal(timerId);
33 }
34
IsExist(int32_t timerId)35 bool TimerManager::IsExist(int32_t timerId)
36 {
37 return IsExistInternal(timerId);
38 }
39
CalcNextDelay()40 int32_t TimerManager::CalcNextDelay()
41 {
42 return CalcNextDelayInternal();
43 }
44
ProcessTimers()45 void TimerManager::ProcessTimers()
46 {
47 ProcessTimersInternal();
48 }
49
TakeNextTimerId()50 int32_t TimerManager::TakeNextTimerId()
51 {
52 uint64_t timerSlot = 0;
53 uint64_t one = 1;
54
55 for (const auto &timer : timers_) {
56 timerSlot |= (one << timer->id);
57 }
58
59 for (int32_t i = 0; i < MAX_TIMER_COUNT; i++) {
60 if ((timerSlot & (one << i)) == 0) {
61 return i;
62 }
63 }
64 return NONEXISTENT_ID;
65 }
66
AddTimerInternal(int32_t intervalMs,int32_t repeatCount,std::function<void ()> callback)67 int32_t TimerManager::AddTimerInternal(int32_t intervalMs, int32_t repeatCount, std::function<void()> callback)
68 {
69 if (intervalMs < MIN_INTERVAL) {
70 intervalMs = MIN_INTERVAL;
71 } else if (intervalMs > MAX_INTERVAL) {
72 intervalMs = MAX_INTERVAL;
73 }
74 if (!callback) {
75 return NONEXISTENT_ID;
76 }
77 int32_t timerId = TakeNextTimerId();
78 if (timerId < 0) {
79 return NONEXISTENT_ID;
80 }
81 auto timer = std::make_unique<TimerItem>();
82 timer->id = timerId;
83 timer->intervalMs = intervalMs;
84 timer->repeatCount = repeatCount;
85 timer->callbackCount = 0;
86 timer->nextCallTime = GetMillisTime() + intervalMs;
87 timer->callback = callback;
88 InsertTimerInternal(timer);
89 return timerId;
90 }
91
RemoveTimerInternal(int32_t timerId)92 int32_t TimerManager::RemoveTimerInternal(int32_t timerId)
93 {
94 for (auto it = timers_.begin(); it != timers_.end(); ++it) {
95 if ((*it)->id == timerId) {
96 timers_.erase(it);
97 return RET_OK;
98 }
99 }
100 return RET_ERR;
101 }
102
ResetTimerInternal(int32_t timerId)103 int32_t TimerManager::ResetTimerInternal(int32_t timerId)
104 {
105 for (auto it = timers_.begin(); it != timers_.end(); ++it) {
106 if ((*it)->id == timerId) {
107 auto timer = std::move(*it);
108 timers_.erase(it);
109 auto nowTime = GetMillisTime();
110 timer->nextCallTime = nowTime + timer->intervalMs;
111 timer->callbackCount = 0;
112 InsertTimerInternal(timer);
113 return RET_OK;
114 }
115 }
116 return RET_ERR;
117 }
118
IsExistInternal(int32_t timerId)119 bool TimerManager::IsExistInternal(int32_t timerId)
120 {
121 for (auto it = timers_.begin(); it != timers_.end(); ++it) {
122 if ((*it)->id == timerId) {
123 return true;
124 }
125 }
126 return false;
127 }
128
InsertTimerInternal(std::unique_ptr<TimerItem> & timer)129 std::unique_ptr<TimerManager::TimerItem>& TimerManager::InsertTimerInternal(std::unique_ptr<TimerItem>& timer)
130 {
131 for (auto it = timers_.begin(); it != timers_.end(); ++it) {
132 if ((*it)->nextCallTime > timer->nextCallTime) {
133 return *(timers_.insert(it, std::move(timer)));
134 }
135 }
136 timers_.push_back(std::move(timer));
137 return *timers_.rbegin();
138 }
139
CalcNextDelayInternal()140 int32_t TimerManager::CalcNextDelayInternal()
141 {
142 auto delay = MIN_DELAY;
143 auto nowTime = GetMillisTime();
144 for (const auto& timer : timers_) {
145 if (nowTime < timer->nextCallTime) {
146 delay = timer->nextCallTime - nowTime;
147 if (delay < MIN_DELAY) {
148 delay = MIN_DELAY;
149 break;
150 }
151 }
152 }
153 return delay;
154 }
155
ProcessTimersInternal()156 void TimerManager::ProcessTimersInternal()
157 {
158 if (timers_.empty()) {
159 return;
160 }
161 auto nowTime = GetMillisTime();
162 for (;;) {
163 auto it = timers_.begin();
164 if (it == timers_.end()) {
165 break;
166 }
167 if ((*it)->nextCallTime > nowTime) {
168 break;
169 }
170 auto curTimer = std::move(*it);
171 timers_.erase(it);
172 ++curTimer->callbackCount;
173 if ((curTimer->repeatCount >= 1) && (curTimer->callbackCount >= curTimer->repeatCount)) {
174 curTimer->callback();
175 continue;
176 }
177 curTimer->nextCallTime = nowTime + curTimer->intervalMs;
178 const auto& timer = InsertTimerInternal(curTimer);
179 timer->callback();
180 }
181 }
182 } // namespace MMI
183 } // namespace OHOS
184