• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "form_timer_mgr.h"
17 
18 #include <cinttypes>
19 
20 #include "ability_context.h"
21 #include "appexecfwk_errors.h"
22 #include "common_event_manager.h"
23 #include "common_event_support.h"
24 #include "context/context.h"
25 #include "form_constants.h"
26 #include "form_provider_mgr.h"
27 #include "form_refresh_limiter.h"
28 #include "form_timer_option.h"
29 #include "form_util.h"
30 #include "hilog_wrapper.h"
31 #include "os_account_manager.h"
32 #include "want.h"
33 
34 namespace OHOS {
35 namespace AppExecFwk {
36 const int REQUEST_UPDATE_AT_CODE = 1;
37 const int REQUEST_LIMITER_CODE = 2;
38 const int REQUEST_DYNAMIC_CODE = 3;
39 const int SHIFT_BIT_LENGTH = 32;
40 const std::string FMS_TIME_SPEED = "fms.time_speed";
41 
FormTimerMgr()42 FormTimerMgr::FormTimerMgr()
43 {
44     Init();
45 }
~FormTimerMgr()46 FormTimerMgr::~FormTimerMgr()
47 {
48     ClearIntervalTimer();
49 }
50 /**
51  * @brief Add form timer by timer task.
52  * @param task The form timer task.
53  * @return Returns true on success, false on failure.
54  */
AddFormTimer(const FormTimer & task)55 bool FormTimerMgr::AddFormTimer(const FormTimer &task)
56 {
57     HILOG_INFO("%{public}s formId:%{public}s userId:%{public}d", __func__,
58         std::to_string(task.formId).c_str(), task.userId);
59     if (task.isUpdateAt) {
60         if (task.hour >= Constants::MIN_TIME && task.hour <= Constants::MAX_HOUR &&
61             task.min >= Constants::MIN_TIME && task.min <= Constants::MAX_MINUTE) {
62             return AddUpdateAtTimer(task);
63         } else {
64             HILOG_ERROR("%{public}s failed, update at time is invalid", __func__);
65             return false;
66         }
67     } else {
68         if (task.period >= (Constants::MIN_PERIOD / timeSpeed_) && // Min period is 30 minutes
69             task.period <= (Constants::MAX_PERIOD / timeSpeed_) && // Max period is 1 week
70             task.period % (Constants::MIN_PERIOD / timeSpeed_) == 0) {
71             return AddIntervalTimer(task);
72         } else {
73             HILOG_ERROR("%{public}s failed, interval time is invalid", __func__);
74             return false;
75         }
76     }
77 }
78 /**
79  * @brief Add duration form timer.
80  * @param formId The Id of the form.
81  * @param updateDuration Update duration
82  * @param userId User ID.
83  * @return Returns true on success, false on failure.
84  */
AddFormTimer(const int64_t formId,const long updateDuration,const int32_t userId)85 bool FormTimerMgr::AddFormTimer(const int64_t formId, const long updateDuration, const int32_t userId)
86 {
87     auto duration = updateDuration / timeSpeed_;
88     HILOG_INFO("%{public}s formId:%{public}s duration:%{public}s", __func__,
89         std::to_string(formId).c_str(), std::to_string(duration).c_str());
90     FormTimer timerTask(formId, duration, userId);
91     return AddFormTimer(timerTask);
92 }
93 /**
94  * @brief Add scheduled form timer.
95  * @param formId The Id of the form.
96  * @param updateAtHour Hour.
97  * @param updateAtMin Min.
98  * @param userId User ID.
99  * @return Returns true on success, false on failure.
100  */
AddFormTimer(const int64_t formId,const long updateAtHour,const long updateAtMin,const int32_t userId)101 bool FormTimerMgr::AddFormTimer(const int64_t formId, const long updateAtHour,
102                                 const long updateAtMin, const int32_t userId)
103 {
104     HILOG_INFO("%{public}s formId:%{public}s time:%{public}s-%{public}s", __func__,
105         std::to_string(formId).c_str(), std::to_string(updateAtHour).c_str(), std::to_string(updateAtMin).c_str());
106     FormTimer timerTask(formId, updateAtHour, updateAtMin, userId);
107     return AddFormTimer(timerTask);
108 }
109 /**
110  * @brief Remove form timer by form id.
111  * @param formId The Id of the form.
112  * @return Returns true on success, false on failure.
113  */
RemoveFormTimer(const int64_t formId)114 bool FormTimerMgr::RemoveFormTimer(const int64_t formId)
115 {
116     HILOG_INFO("%{public}s, task: %{public}" PRId64 "", __func__, formId);
117 
118     if (!DeleteIntervalTimer(formId)) {
119         if (!DeleteUpdateAtTimer(formId)) {
120             HILOG_ERROR("%{public}s, failed to DeleteUpdateAtTimer", __func__);
121             return false;
122         }
123     }
124 
125     if (!DeleteDynamicItem(formId)) {
126         HILOG_ERROR("%{public}s, failed to DeleteDynamicItem", __func__);
127         return false;
128     }
129     refreshLimiter_.DeleteItem(formId);
130 
131     return true;
132 }
133 /**
134  * @brief Update form timer.
135  * @param formId The Id of the form.
136  * @param type Timer type.
137  * @param timerCfg Timer config.
138  * @return Returns true on success, false on failure.
139  */
UpdateFormTimer(const int64_t formId,const UpdateType & type,const FormTimerCfg & timerCfg)140 bool FormTimerMgr::UpdateFormTimer(const int64_t formId, const UpdateType &type, const FormTimerCfg &timerCfg)
141 {
142     if (!timerCfg.enableUpdate) {
143         HILOG_WARN("%{public}s, enableUpdate is false", __func__);
144         return false;
145     }
146 
147     switch (type) {
148         case UpdateType::TYPE_INTERVAL_CHANGE: {
149             return UpdateIntervalValue(formId, timerCfg);
150         }
151         case UpdateType::TYPE_ATTIME_CHANGE: {
152             return UpdateAtTimerValue(formId, timerCfg);
153         }
154         case UpdateType::TYPE_INTERVAL_TO_ATTIME: {
155             return IntervalToAtTimer(formId, timerCfg);
156         }
157         case UpdateType::TYPE_ATTIME_TO_INTERVAL: {
158             return AtTimerToIntervalTimer(formId, timerCfg);
159         }
160         default: {
161             HILOG_ERROR("%{public}s failed, invalid UpdateType", __func__);
162             return false;
163         }
164     }
165 }
166 /**
167  * @brief Update Interval timer task value.
168  * @param formId The Id of the form.
169  * @param timerCfg task value.
170  * @return Returns true on success, false on failure.
171  */
UpdateIntervalValue(const int64_t formId,const FormTimerCfg & timerCfg)172 bool FormTimerMgr::UpdateIntervalValue(const int64_t formId, const FormTimerCfg &timerCfg)
173 {
174     if (timerCfg.updateDuration < Constants::MIN_PERIOD || timerCfg.updateDuration > Constants::MAX_PERIOD
175         || (timerCfg.updateDuration % Constants::MIN_PERIOD) != 0) {
176         HILOG_ERROR("%{public}s failed, invalid param", __func__);
177         return false;
178     }
179 
180     std::lock_guard<std::mutex> lock(intervalMutex_);
181     auto intervalTask = intervalTimerTasks_.find(formId);
182     if (intervalTask != intervalTimerTasks_.end()) {
183         intervalTask->second.period = timerCfg.updateDuration;
184         return true;
185     } else {
186         HILOG_ERROR("%{public}s failed, the interval timer is not exist", __func__);
187         return false;
188     }
189 }
190 /**
191  * @brief Update update at timer task value.
192  * @param formId The Id of the form.
193  * @param timerCfg task value.
194  * @return Returns true on success, false on failure.
195  */
UpdateAtTimerValue(const int64_t formId,const FormTimerCfg & timerCfg)196 bool FormTimerMgr::UpdateAtTimerValue(const int64_t formId, const FormTimerCfg &timerCfg)
197 {
198     if (timerCfg.updateAtHour < Constants::MIN_TIME || timerCfg.updateAtHour > Constants::MAX_HOUR
199         || timerCfg.updateAtMin < Constants::MIN_TIME || timerCfg.updateAtMin > Constants::MAX_MINUTE) {
200         HILOG_ERROR("%{public}s failed, time is invalid", __func__);
201         return false;
202     }
203     {
204         std::lock_guard<std::mutex> lock(updateAtMutex_);
205         std::list<UpdateAtItem>::iterator itItem;
206         UpdateAtItem changedItem;
207         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
208             if (itItem->refreshTask.formId == formId) {
209                 changedItem = *itItem;
210                 updateAtTimerTasks_.erase(itItem);
211                 break;
212             }
213         }
214 
215         if (changedItem.refreshTask.formId == 0) {
216             HILOG_ERROR("%{public}s failed, the update at timer is not exist", __func__);
217             return false;
218         }
219         changedItem.refreshTask.hour = timerCfg.updateAtHour;
220         changedItem.refreshTask.min = timerCfg.updateAtMin;
221         changedItem.updateAtTime = changedItem.refreshTask.hour * Constants::MIN_PER_HOUR + changedItem.refreshTask.min;
222         AddUpdateAtItem(changedItem);
223     }
224 
225     if (!UpdateAtTimerAlarm()) {
226         HILOG_ERROR("%{public}s, failed to update attimer alarm.", __func__);
227         return false;
228     }
229     return true;
230 }
231 /**
232  * @brief Interval timer task to update at timer task.
233  * @param formId The Id of the form.
234  * @param timerCfg task value.
235  * @return Returns true on success, false on failure.
236  */
IntervalToAtTimer(const int64_t formId,const FormTimerCfg & timerCfg)237 bool FormTimerMgr::IntervalToAtTimer(const int64_t formId, const FormTimerCfg &timerCfg)
238 {
239     if (timerCfg.updateAtHour < Constants::MIN_TIME || timerCfg.updateAtHour > Constants::MAX_HOUR
240         || timerCfg.updateAtMin < Constants::MIN_TIME || timerCfg.updateAtMin > Constants::MAX_MINUTE) {
241         HILOG_ERROR("%{public}s failed, time is invalid", __func__);
242         return false;
243     }
244 
245     std::lock_guard<std::mutex> lock(intervalMutex_);
246     FormTimer timerTask;
247     auto intervalTask = intervalTimerTasks_.find(formId);
248     if (intervalTask != intervalTimerTasks_.end()) {
249         timerTask = intervalTask->second;
250         intervalTimerTasks_.erase(intervalTask);
251 
252         timerTask.isUpdateAt = true;
253         timerTask.hour = timerCfg.updateAtHour;
254         timerTask.min = timerCfg.updateAtMin;
255         if (!AddUpdateAtTimer(timerTask)) {
256             HILOG_ERROR("%{public}s, failed to add update at timer", __func__);
257             return false;
258         }
259         return true;
260     } else {
261         HILOG_ERROR("%{public}s failed, the interval timer is not exist", __func__);
262         return false;
263     }
264 }
265 /**
266  * @brief Update at timer task to interval timer task.
267  * @param formId The Id of the form.
268  * @param timerCfg task value.
269  * @return Returns true on success, false on failure.
270  */
AtTimerToIntervalTimer(const int64_t formId,const FormTimerCfg & timerCfg)271 bool FormTimerMgr::AtTimerToIntervalTimer(const int64_t formId, const FormTimerCfg &timerCfg)
272 {
273     if (timerCfg.updateDuration < Constants::MIN_PERIOD || timerCfg.updateDuration > Constants::MAX_PERIOD
274         || (timerCfg.updateDuration % Constants::MIN_PERIOD) != 0) {
275         HILOG_ERROR("%{public}s failed, time is invalid", __func__);
276         return false;
277     }
278 
279     UpdateAtItem targetItem;
280     {
281         std::lock_guard<std::mutex> lock(updateAtMutex_);
282         std::list<UpdateAtItem>::iterator itItem;
283         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
284             if (itItem->refreshTask.formId == formId) {
285                 targetItem = *itItem;
286                 updateAtTimerTasks_.erase(itItem);
287                 break;
288             }
289         }
290     }
291 
292     if (!UpdateAtTimerAlarm()) {
293         HILOG_ERROR("%{public}s, failed to update attimer alarm.", __func__);
294         return false;
295     }
296 
297     if (targetItem.refreshTask.formId == 0) {
298         HILOG_ERROR("%{public}s failed, the update at timer is not exist", __func__);
299         return false;
300     }
301     targetItem.refreshTask.isUpdateAt = false;
302     targetItem.refreshTask.period = timerCfg.updateDuration;
303     targetItem.refreshTask.refreshTime = INT64_MAX;
304     if (!AddIntervalTimer(targetItem.refreshTask)) {
305         HILOG_ERROR("%{public}s, failed to add interval timer", __func__);
306         return false;
307     }
308     return true;
309 }
310 /**
311  * @brief Is limiter enable refresh.
312  * @param formId The Id of the form.
313  * @return Returns true on success, false on failure.
314  */
IsLimiterEnableRefresh(const int64_t formId)315 bool FormTimerMgr::IsLimiterEnableRefresh(const int64_t formId)
316 {
317     return refreshLimiter_.IsEnableRefresh(formId);
318 }
319 /**
320  * @brief Increase refresh count.
321  * @param formId The Id of the form.
322  */
IncreaseRefreshCount(const int64_t formId)323 void FormTimerMgr::IncreaseRefreshCount(const int64_t formId)
324 {
325     refreshLimiter_.Increase(formId);
326 }
327 /**
328  * @brief Set next refresh time.
329  * @param formId The Id of the form.
330  * @param nextGapTime Next gap time(ms).
331  * @param userId User ID.
332  * @return Returns true on success, false on failure.
333  */
SetNextRefreshTime(const int64_t formId,const long nextGapTime,const int32_t userId)334 bool FormTimerMgr::SetNextRefreshTime(const int64_t formId, const long nextGapTime, const int32_t userId)
335 {
336     if (nextGapTime < Constants::MIN_NEXT_TIME) {
337         HILOG_ERROR("%{public}s failed, nextGapTime is invalid, nextGapTime:%{public}ld", __func__, nextGapTime);
338         return false;
339     }
340     auto timeSinceEpoch = std::chrono::steady_clock::now().time_since_epoch();
341     int64_t timeInSec = std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
342     int64_t refreshTime = timeInSec + nextGapTime * Constants::MS_PER_SECOND / timeSpeed_;
343     HILOG_INFO("%{public}s currentTime:%{public}s refreshTime:%{public}s", __func__,
344         std::to_string(timeInSec).c_str(), std::to_string(refreshTime).c_str());
345     std::lock_guard<std::mutex> lock(refreshMutex_);
346     bool isExist = false;
347     for (auto &refreshItem : dynamicRefreshTasks_) {
348         if ((refreshItem.formId == formId) && (refreshItem.userId == userId)) {
349             refreshItem.settedTime = refreshTime;
350             isExist = true;
351             break;
352         }
353     }
354     if (!isExist) {
355         DynamicRefreshItem theItem;
356         theItem.formId = formId;
357         theItem.settedTime = refreshTime;
358         theItem.userId = userId;
359         dynamicRefreshTasks_.emplace_back(theItem);
360     }
361     std::sort(dynamicRefreshTasks_.begin(), dynamicRefreshTasks_.end(), CompareDynamicRefreshItem);
362     if (!UpdateDynamicAlarm()) {
363         HILOG_ERROR("%{public}s, failed to UpdateDynamicAlarm", __func__);
364         return false;
365     }
366     if (!UpdateLimiterAlarm()) {
367         HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
368         return false;
369     }
370     refreshLimiter_.AddItem(formId);
371     SetEnableFlag(formId, false);
372 
373     return true;
374 }
375 
SetEnableFlag(int64_t formId,bool flag)376 void FormTimerMgr::SetEnableFlag(int64_t formId, bool flag)
377 {
378     // try interval list
379     auto iter = intervalTimerTasks_.find(formId);
380     if (iter != intervalTimerTasks_.end()) {
381         iter->second.isEnable = flag;
382         HILOG_INFO("%{public}s, formId:%{public}" PRId64 ", isEnable:%{public}d", __func__, formId, flag ? 1 : 0);
383         return;
384     }
385 }
386 
387 /**
388  * @brief Get refresh count.
389  * @param formId The Id of the form.
390  * @return Returns refresh count.
391  */
GetRefreshCount(const int64_t formId) const392 int FormTimerMgr::GetRefreshCount(const int64_t formId) const
393 {
394     return refreshLimiter_.GetRefreshCount(formId);
395 }
396 /**
397  * @brief Mark remind.
398  * @param formId The Id of the form.
399  * @return true or false.
400  */
MarkRemind(const int64_t formId)401 void FormTimerMgr::MarkRemind(const int64_t  formId)
402 {
403     refreshLimiter_.MarkRemind(formId);
404 }
405 /**
406  * @brief Add update at timer.
407  * @param task Update time task.
408  * @return Returns true on success, false on failure.
409  */
AddUpdateAtTimer(const FormTimer & task)410 bool FormTimerMgr::AddUpdateAtTimer(const FormTimer &task)
411 {
412     HILOG_INFO("%{public}s start", __func__);
413     {
414         std::lock_guard<std::mutex> lock(updateAtMutex_);
415         for (auto &updateAtTimer : updateAtTimerTasks_) {
416             if (updateAtTimer.refreshTask.formId == task.formId) {
417                 HILOG_WARN(
418                     "%{public}s, already exist formTimer, formId:%{public}" PRId64 " task", __func__, task.formId);
419                 return true;
420             }
421         }
422 
423         UpdateAtItem atItem;
424         atItem.refreshTask = task;
425         atItem.updateAtTime = task.hour * Constants::MIN_PER_HOUR + task.min;
426 
427         AddUpdateAtItem(atItem);
428     }
429     if (!UpdateLimiterAlarm()) {
430         HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
431         return false;
432     }
433 
434     if (!UpdateAtTimerAlarm()) {
435         HILOG_ERROR("%{public}s, failed to update attimer alarm.", __func__);
436         return false;
437     }
438 
439     return refreshLimiter_.AddItem(task.formId);
440 }
441 /**
442  * @brief Add update interval timer task.
443  * @param task Update interval timer task.
444  * @return Returns true on success, false on failure.
445  */
AddIntervalTimer(const FormTimer & task)446 bool FormTimerMgr::AddIntervalTimer(const FormTimer &task)
447 {
448     HILOG_INFO("%{public}s start", __func__);
449     {
450         std::lock_guard<std::mutex> lock(intervalMutex_);
451         EnsureInitIntervalTimer();
452         if (intervalTimerTasks_.find(task.formId) != intervalTimerTasks_.end()) {
453             HILOG_WARN("%{public}s, already exist formTimer, formId:%{public}" PRId64 " task", __func__, task.formId);
454             return true;
455         }
456         intervalTimerTasks_.emplace(task.formId, task);
457     }
458     if (!UpdateLimiterAlarm()) {
459         HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
460         return false;
461     }
462     return refreshLimiter_.AddItem(task.formId);
463 }
464 /**
465  * @brief Add update at timer item.
466  * @param task Update at timer item.
467  */
AddUpdateAtItem(const UpdateAtItem & atItem)468 void FormTimerMgr::AddUpdateAtItem(const UpdateAtItem &atItem)
469 {
470     if (updateAtTimerTasks_.empty()) {
471         updateAtTimerTasks_.emplace_back(atItem);
472         return;
473     }
474 
475     UpdateAtItem firstItem = updateAtTimerTasks_.front();
476     if (atItem.updateAtTime < firstItem.updateAtTime) {
477         updateAtTimerTasks_.emplace_front(atItem);
478         return;
479     }
480 
481     bool isInsert = false;
482     std::list<UpdateAtItem>::iterator itItem;
483     for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
484         if (atItem.updateAtTime < itItem->updateAtTime) {
485             updateAtTimerTasks_.insert(itItem, atItem);
486             isInsert = true;
487             break;
488         }
489     }
490 
491     if (!isInsert) {
492         updateAtTimerTasks_.emplace_back(atItem);
493     }
494 }
495 /**
496  * @brief Handle system time changed.
497  * @return Returns true on success, false on failure.
498  */
HandleSystemTimeChanged()499 bool FormTimerMgr::HandleSystemTimeChanged()
500 {
501     HILOG_INFO("%{public}s start", __func__);
502     if (!updateAtTimerTasks_.empty()) {
503         atTimerWakeUpTime_ = LONG_MAX;
504         UpdateAtTimerAlarm();
505     }
506     UpdateLimiterAlarm();
507     HILOG_INFO("%{public}s end", __func__);
508     return true;
509 }
510 /**
511  * @brief Reset form limiter.
512  * @return Returns true on success, false on failure.
513  */
HandleResetLimiter()514 bool FormTimerMgr::HandleResetLimiter()
515 {
516     HILOG_INFO("%{public}s start", __func__);
517 
518     std::vector<FormTimer> remindTasks;
519     bool bGetTasks = GetRemindTasks(remindTasks);
520     if (bGetTasks) {
521         HILOG_INFO("%{public}s failed, remind when reset limiter", __func__);
522         for (auto &task : remindTasks) {
523             ExecTimerTask(task);
524         }
525     }
526 
527     HILOG_INFO("%{public}s end", __func__);
528     return true;
529 }
530 /**
531  * @brief Update attime trigger.
532  * @param updateTime Update time.
533  * @return Returns true on success, false on failure.
534  */
OnUpdateAtTrigger(long updateTime)535 bool FormTimerMgr::OnUpdateAtTrigger(long updateTime)
536 {
537     HILOG_INFO("%{public}s start, updateTime:%{public}ld", __func__, updateTime);
538     std::vector<UpdateAtItem> updateList;
539     {
540         std::lock_guard<std::mutex> lock(updateAtMutex_);
541         std::list<UpdateAtItem>::iterator itItem;
542         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
543             if (itItem->updateAtTime == updateTime && itItem->refreshTask.isEnable) {
544                 updateList.emplace_back(*itItem);
545             }
546         }
547     }
548 
549     if (!UpdateAtTimerAlarm()) {
550         HILOG_ERROR("%{public}s, failed to update attimer alarm.", __func__);
551         return false;
552     }
553 
554     if (!updateList.empty()) {
555         HILOG_INFO("%{public}s, update at timer triggered, trigged time: %{public}ld", __func__, updateTime);
556         for (auto &item : updateList) {
557             ExecTimerTask(item.refreshTask);
558         }
559     }
560 
561     HILOG_INFO("%{public}s end", __func__);
562     return true;
563 }
564 /**
565  * @brief Dynamic time trigger.
566  * @param updateTime Update time.
567  * @return Returns true on success, false on failure.
568  */
OnDynamicTimeTrigger(int64_t updateTime)569 bool FormTimerMgr::OnDynamicTimeTrigger(int64_t updateTime)
570 {
571     HILOG_INFO("%{public}s start, updateTime:%{public}" PRId64 "", __func__, updateTime);
572     std::vector<FormTimer> updateList;
573     {
574         std::lock_guard<std::mutex> lock(dynamicMutex_);
575         auto timeSinceEpoch = std::chrono::steady_clock::now().time_since_epoch();
576         auto timeInSec = std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
577         int64_t markedTime = timeInSec + Constants::ABS_REFRESH_MS;
578         std::vector<DynamicRefreshItem>::iterator itItem;
579         for (itItem = dynamicRefreshTasks_.begin(); itItem != dynamicRefreshTasks_.end();) {
580             if (itItem->settedTime <= updateTime || itItem->settedTime <= markedTime) {
581                 if (refreshLimiter_.IsEnableRefresh(itItem->formId)) {
582                     FormTimer timerTask(itItem->formId, true, itItem->userId);
583                     updateList.emplace_back(timerTask);
584                 }
585                 SetIntervalEnableFlag(itItem->formId, true);
586                 itItem = dynamicRefreshTasks_.erase(itItem);
587             } else {
588                 itItem++;
589             }
590         }
591         std::sort(dynamicRefreshTasks_.begin(), dynamicRefreshTasks_.end(),  CompareDynamicRefreshItem);
592     }
593 
594     if (!UpdateDynamicAlarm()) {
595         HILOG_ERROR("%{public}s, failed to update dynamic alarm.", __func__);
596         return false;
597     }
598 
599     if (!updateList.empty()) {
600         HILOG_INFO("%{public}s triggered, trigged time: %{public}" PRId64 "", __func__, updateTime);
601         for (auto &task : updateList) {
602             ExecTimerTask(task);
603         }
604     }
605 
606     HILOG_INFO("%{public}s end", __func__);
607     return true;
608 }
609 /**
610  * @brief Get remind tasks.
611  * @param remindTasks Remind tasks.
612  * @return Returns true on success, false on failure.
613  */
GetRemindTasks(std::vector<FormTimer> & remindTasks)614 bool FormTimerMgr::GetRemindTasks(std::vector<FormTimer> &remindTasks)
615 {
616     HILOG_INFO("%{public}s start", __func__);
617     std::vector<int64_t> remindList = refreshLimiter_.GetRemindListAndResetLimit();
618     for (int64_t id : remindList) {
619         FormTimer formTimer(id, false);
620         remindTasks.emplace_back(formTimer);
621     }
622 
623     if (!UpdateLimiterAlarm()) {
624         HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
625         return false;
626     }
627 
628     if (remindTasks.size() > 0) {
629         HILOG_INFO("%{public}s end", __func__);
630         return true;
631     } else {
632         HILOG_INFO("%{public}s end, remindTasks is empty", __func__);
633         return false;
634     }
635 }
636 /**
637  * @brief Set enableFlag for interval timer task.
638  * @param formId The Id of the form.
639  * @param flag Enable flag.
640  */
SetIntervalEnableFlag(int64_t formId,bool flag)641 void FormTimerMgr::SetIntervalEnableFlag(int64_t formId, bool flag)
642 {
643     std::lock_guard<std::mutex> lock(intervalMutex_);
644     // try interval list
645     auto refreshTask = intervalTimerTasks_.find(formId);
646     if (refreshTask != intervalTimerTasks_.end()) {
647         refreshTask->second.isEnable = flag;
648         HILOG_INFO("%{public}s, formId:%{public}" PRId64 ", isEnable:%{public}d", __func__, formId, flag ? 1 : 0);
649         return;
650     }
651 }
652 /**
653  * @brief Get interval timer task.
654  * @param formId The Id of the form.
655  * @return Returns true on success, false on failure.
656  */
GetIntervalTimer(const int64_t formId,FormTimer & formTimer)657 bool FormTimerMgr::GetIntervalTimer(const int64_t formId, FormTimer &formTimer)
658 {
659     HILOG_INFO("%{public}s start", __func__);
660     std::lock_guard<std::mutex> lock(intervalMutex_);
661     auto intervalTask = intervalTimerTasks_.find(formId);
662     if (intervalTask == intervalTimerTasks_.end()) {
663         HILOG_INFO("%{public}s, interval timer not find", __func__);
664         return false;
665     }
666     formTimer = intervalTask->second;
667     HILOG_INFO("%{public}s, get interval timer successfully", __func__);
668     return true;
669 }
670 /**
671  * @brief Get update at timer.
672  * @param formId The Id of the form.
673  * @return Returns true on success, false on failure.
674  */
GetUpdateAtTimer(const int64_t formId,UpdateAtItem & updateAtItem)675 bool FormTimerMgr::GetUpdateAtTimer(const int64_t formId, UpdateAtItem &updateAtItem)
676 {
677     HILOG_INFO("%{public}s start", __func__);
678     {
679         std::lock_guard<std::mutex> lock(updateAtMutex_);
680         std::list<UpdateAtItem>::iterator itItem;
681         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
682             if (itItem->refreshTask.formId == formId) {
683                 updateAtItem.refreshTask = itItem->refreshTask;
684                 updateAtItem.updateAtTime = itItem->updateAtTime;
685                 HILOG_INFO("%{public}s, get update at timer successfully", __func__);
686                 return true;
687             }
688         }
689     }
690     HILOG_INFO("%{public}s, update at timer not find", __func__);
691     return false;
692 }
693 /**
694  * @brief Get dynamic refresh item.
695  * @param formId The Id of the form.
696  * @return Returns true on success, false on failure.
697  */
GetDynamicItem(const int64_t formId,DynamicRefreshItem & dynamicItem)698 bool FormTimerMgr::GetDynamicItem(const int64_t formId, DynamicRefreshItem &dynamicItem)
699 {
700     HILOG_INFO("%{public}s start", __func__);
701     std::lock_guard<std::mutex> lock(dynamicMutex_);
702     std::vector<DynamicRefreshItem>::iterator itItem;
703     for (itItem = dynamicRefreshTasks_.begin(); itItem != dynamicRefreshTasks_.end();) {
704         if (itItem->formId == formId) {
705             dynamicItem.formId = itItem->formId;
706             dynamicItem.settedTime = itItem->settedTime;
707             dynamicItem.userId = itItem->userId;
708             HILOG_INFO("%{public}s, get dynamic item successfully", __func__);
709             return true;
710         }
711     }
712     HILOG_INFO("%{public}s, dynamic item not find", __func__);
713     return false;
714 }
715 /**
716  * @brief Set time speed.
717  * @param timeSpeed The time speed.
718  */
SetTimeSpeed(int32_t timeSpeed)719 void FormTimerMgr::SetTimeSpeed(int32_t timeSpeed)
720 {
721     HILOG_INFO("%{public}s set time speed to:%{public}d", __func__, timeSpeed);
722     timeSpeed_ = timeSpeed;
723     HandleResetLimiter();
724     ClearIntervalTimer();
725 }
726 /**
727  * @brief Delete interval timer task.
728  * @param formId The Id of the form.
729  * @return Returns true on success, false on failure.
730  */
DeleteIntervalTimer(const int64_t formId)731 bool FormTimerMgr::DeleteIntervalTimer(const int64_t formId)
732 {
733     HILOG_INFO("%{public}s start", __func__);
734     bool isExist = false;
735     std::lock_guard<std::mutex> lock(intervalMutex_);
736     auto intervalTask = intervalTimerTasks_.find(formId);
737     if (intervalTask != intervalTimerTasks_.end()) {
738         intervalTimerTasks_.erase(intervalTask);
739         isExist = true;
740     }
741 
742     if (intervalTimerTasks_.empty()) {
743         ClearIntervalTimer();
744     }
745     HILOG_INFO("%{public}s end", __func__);
746     return isExist;
747 }
748 /**
749  * @brief Delete update at timer.
750  * @param formId The Id of the form.
751  * @return Returns true on success, false on failure.
752  */
DeleteUpdateAtTimer(const int64_t formId)753 bool FormTimerMgr::DeleteUpdateAtTimer(const int64_t formId)
754 {
755     HILOG_INFO("%{public}s start", __func__);
756     {
757         std::lock_guard<std::mutex> lock(updateAtMutex_);
758         std::list<UpdateAtItem>::iterator itItem;
759         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
760             if (itItem->refreshTask.formId == formId) {
761                 updateAtTimerTasks_.erase(itItem);
762                 break;
763             }
764         }
765     }
766 
767     if (!UpdateAtTimerAlarm()) {
768         HILOG_ERROR("%{public}s, failed to update attimer alarm.", __func__);
769         return false;
770     }
771     HILOG_INFO("%{public}s end", __func__);
772     return true;
773 }
774 /**
775  * @brief Delete dynamic refresh item.
776  * @param formId The Id of the form.
777  */
DeleteDynamicItem(const int64_t formId)778 bool FormTimerMgr::DeleteDynamicItem(const int64_t formId)
779 {
780     HILOG_INFO("%{public}s start", __func__);
781     std::lock_guard<std::mutex> lock(dynamicMutex_);
782     std::vector<DynamicRefreshItem>::iterator itItem;
783     for (itItem = dynamicRefreshTasks_.begin(); itItem != dynamicRefreshTasks_.end();) {
784         if (itItem->formId == formId) {
785             itItem = dynamicRefreshTasks_.erase(itItem);
786             if (itItem != dynamicRefreshTasks_.end()) {
787                 SetIntervalEnableFlag(itItem->formId, true);
788             }
789             break;
790         }
791     }
792     std::sort(dynamicRefreshTasks_.begin(), dynamicRefreshTasks_.end(),  CompareDynamicRefreshItem);
793 
794     if (!UpdateDynamicAlarm()) {
795         HILOG_ERROR("%{public}s, failed to UpdateDynamicAlarm", __func__);
796         return false;
797     }
798     HILOG_INFO("%{public}s end", __func__);
799     return true;
800 }
801 /**
802 * @brief interval timer task timeout.
803 */
OnIntervalTimeOut()804 void FormTimerMgr::OnIntervalTimeOut()
805 {
806     HILOG_INFO("%{public}s start", __func__);
807     std::lock_guard<std::mutex> lock(intervalMutex_);
808     std::vector<FormTimer> updateList;
809     int64_t currentTime = FormUtil::GetCurrentNanosecond() / Constants::TIME_1000000;
810     for (auto &intervalPair : intervalTimerTasks_) {
811         FormTimer &intervalTask = intervalPair.second;
812         if ((intervalTask.refreshTime == INT64_MAX || (currentTime - intervalTask.refreshTime) >= intervalTask.period ||
813             std::abs((currentTime - intervalTask.refreshTime) - intervalTask.period) < Constants::ABS_TIME) &&
814             intervalTask.isEnable && refreshLimiter_.IsEnableRefresh(intervalTask.formId)) {
815             intervalTask.refreshTime = currentTime;
816             updateList.emplace_back(intervalTask);
817         }
818     }
819 
820     if (!updateList.empty()) {
821         for (auto &task : updateList) {
822             ExecTimerTask(task);
823         }
824     }
825     HILOG_INFO("%{public}s end", __func__);
826 }
827 
828 /**
829  * @brief Update at timer task alarm.
830  * @return Returns true on success, false on failure.
831  */
UpdateAtTimerAlarm()832 bool FormTimerMgr::UpdateAtTimerAlarm()
833 {
834     HILOG_INFO("%{public}s start", __func__);
835     struct tm tmAtTime = {0};
836     auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
837     struct tm* ptm = localtime_r(&tt, &tmAtTime);
838     if (ptm == nullptr) {
839         HILOG_ERROR("%{public}s failed, localtime error", __func__);
840         return false;
841     }
842 
843     long nowAtTime = tmAtTime.tm_hour * Constants::MIN_PER_HOUR + tmAtTime.tm_min;
844     int64_t currentTime = FormUtil::GetCurrentMillisecond();
845     UpdateAtItem findedItem;
846     bool bFinded = FindNextAtTimerItem(nowAtTime, findedItem);
847     if (!bFinded) {
848         if (!updateAtTimerTasks_.empty()) {
849             HILOG_WARN("%{public}s, updateAtTimerTasks_ is not empty", __func__);
850             return true;
851         }
852         ClearUpdateAtTimerResource();
853         atTimerWakeUpTime_ = LONG_MAX;
854         HILOG_INFO("%{public}s, no update at task in system now.", __func__);
855         return true;
856     }
857 
858     long nextWakeUpTime = findedItem.updateAtTime;
859     tmAtTime.tm_sec = 0;
860     tmAtTime.tm_hour = findedItem.refreshTask.hour;
861     tmAtTime.tm_min = findedItem.refreshTask.min;
862     int64_t selectTime = FormUtil::GetMillisecondFromTm(tmAtTime);
863     if (selectTime < currentTime) {
864         selectTime += Constants::MS_PER_DAY;
865         nextWakeUpTime += (Constants::HOUR_PER_DAY * Constants::MIN_PER_HOUR);
866     }
867     HILOG_INFO("%{public}s, selectTime: %{public}" PRId64 ", currentTime: %{public}" PRId64 ".",
868         __func__, selectTime, currentTime);
869 
870     if (nextWakeUpTime == atTimerWakeUpTime_) {
871         HILOG_WARN("%{public}s end, wakeUpTime not change, no need update alarm.", __func__);
872         return true;
873     }
874 
875     auto timerOption = std::make_shared<FormTimerOption>();
876     timerOption->SetType(((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
877       | ((unsigned int)(timerOption->TIMER_TYPE_WAKEUP)));
878     timerOption->SetRepeat(false);
879     timerOption->SetInterval(0);
880     int32_t userId = findedItem.refreshTask.userId;
881     std::shared_ptr<WantAgent> wantAgent = GetUpdateAtWantAgent(findedItem.updateAtTime, userId);
882     if (wantAgent == nullptr) {
883         HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
884         return false;
885     }
886     timerOption->SetWantAgent(wantAgent);
887 
888     atTimerWakeUpTime_ = nextWakeUpTime;
889     if (currentUpdateAtWantAgent != nullptr) {
890         ClearUpdateAtTimerResource();
891     }
892     auto timeSinceEpoch = std::chrono::steady_clock::now().time_since_epoch();
893     int64_t timeInSec = std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
894     int64_t nextTime = timeInSec + (selectTime - currentTime);
895     HILOG_INFO("%{public}s, nextTime: %{public}" PRId64 ".", __func__, nextTime);
896 
897     currentUpdateAtWantAgent = wantAgent;
898     updateAtTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
899     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(updateAtTimerId_,
900         static_cast<uint64_t>(nextTime));
901     if (!bRet) {
902         HILOG_ERROR("%{public}s failed, init update at timer task error", __func__);
903         return false;
904     }
905 
906     HILOG_INFO("%{public}s end", __func__);
907     return true;
908 }
909 
910 /**
911  * @brief Get WantAgent.
912  * @param updateAtTime The next update time.
913  * @return Returns WantAgent.
914  */
GetUpdateAtWantAgent(long updateAtTime,int32_t userId)915 std::shared_ptr<WantAgent> FormTimerMgr::GetUpdateAtWantAgent(long updateAtTime, int32_t userId)
916 {
917     std::shared_ptr<Want> want = std::make_shared<Want>();
918     ElementName element("", "", "");
919     want->SetElement(element);
920     want->SetAction(Constants::ACTION_UPDATEATTIMER);
921     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_STATIC_UPDATE);
922     want->SetParam(Constants::KEY_WAKEUP_TIME, updateAtTime);
923 
924     std::vector<std::shared_ptr<AAFwk::Want>> wants;
925     wants.emplace_back(want);
926     WantAgentInfo wantAgentInfo(REQUEST_UPDATE_AT_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
927         WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
928     return WantAgentHelper::GetWantAgent(wantAgentInfo, userId);
929 }
930 
931 /**
932  * @brief Clear update at timer resource.
933  */
ClearUpdateAtTimerResource()934 void FormTimerMgr::ClearUpdateAtTimerResource()
935 {
936     HILOG_INFO("%{public}s start", __func__);
937     if (updateAtTimerId_ != 0L) {
938         HILOG_INFO("%{public}s clear update at timer start", __func__);
939         MiscServices::TimeServiceClient::GetInstance()->StopTimer(updateAtTimerId_);
940         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(updateAtTimerId_);
941         HILOG_INFO("%{public}s clear update at timer end", __func__);
942         updateAtTimerId_ = 0L;
943     }
944     if (currentUpdateAtWantAgent != nullptr) {
945         WantAgentHelper::Cancel(currentUpdateAtWantAgent);
946         currentUpdateAtWantAgent = nullptr;
947     }
948     HILOG_INFO("%{public}s end", __func__);
949 }
950 
951 /**
952  * @brief Update limiter task alarm.
953  * @return Returns true on success, false on failure.
954  */
UpdateLimiterAlarm()955 bool FormTimerMgr::UpdateLimiterAlarm()
956 {
957     HILOG_INFO("%{public}s start", __func__);
958     if (limiterTimerId_ != 0L) {
959         HILOG_INFO("%{public}s clear limiter timer start", __func__);
960         MiscServices::TimeServiceClient::GetInstance()->StopTimer(limiterTimerId_);
961         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(limiterTimerId_);
962         HILOG_INFO("%{public}s clear limiter timer end", __func__);
963         limiterTimerId_ = 0L;
964     }
965 
966     // make limiter wakeup time
967     struct tm tmAtTime = {0};
968     auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
969     struct tm* ptm = localtime_r(&tt, &tmAtTime);
970     if (ptm == nullptr) {
971         HILOG_ERROR("%{public}s failed, localtime error", __func__);
972         return false;
973     }
974     tmAtTime.tm_sec = Constants::MAX_SECOND; // max value can be 61
975     tmAtTime.tm_hour = Constants::MAX_HOUR;
976     tmAtTime.tm_min = Constants::MAX_MINUTE;
977     int64_t limiterWakeUpTime = FormUtil::GetMillisecondFromTm(tmAtTime);
978 
979     auto timerOption = std::make_shared<FormTimerOption>();
980     timerOption->SetType(timerOption->TIMER_TYPE_WAKEUP);
981     timerOption->SetRepeat(false);
982     timerOption->SetInterval(0);
983     std::shared_ptr<WantAgent> wantAgent = GetLimiterWantAgent();
984     if (!wantAgent) {
985         HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
986         return false;
987     }
988     timerOption->SetWantAgent(wantAgent);
989 
990     if (currentLimiterWantAgent != nullptr) {
991         ClearLimiterTimerResource();
992     }
993     currentLimiterWantAgent = wantAgent;
994 
995     limiterTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
996     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(limiterTimerId_,
997         static_cast<uint64_t>(limiterWakeUpTime));
998     if (!bRet) {
999         HILOG_ERROR("%{public}s failed, init limiter timer task error", __func__);
1000         return false;
1001     }
1002     HILOG_INFO("%{public}s end", __func__);
1003     return true;
1004 }
1005 /**
1006  * @brief Clear limiter timer resource.
1007  */
ClearLimiterTimerResource()1008 void FormTimerMgr::ClearLimiterTimerResource()
1009 {
1010     HILOG_INFO("%{public}s start", __func__);
1011     if (limiterTimerId_ != 0L) {
1012         HILOG_INFO("%{public}s clear limiter timer start", __func__);
1013         MiscServices::TimeServiceClient::GetInstance()->StopTimer(limiterTimerId_);
1014         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(limiterTimerId_);
1015         HILOG_INFO("%{public}s clear limiter timer end", __func__);
1016         limiterTimerId_ = 0L;
1017     }
1018     if (currentLimiterWantAgent != nullptr) {
1019         WantAgentHelper::Cancel(currentLimiterWantAgent);
1020         currentLimiterWantAgent = nullptr;
1021     }
1022     HILOG_INFO("%{public}s end", __func__);
1023 }
1024 
1025 /**
1026  * @brief Get WantAgent.
1027  * @return Returns WantAgent.
1028  */
GetLimiterWantAgent()1029 std::shared_ptr<WantAgent> FormTimerMgr::GetLimiterWantAgent()
1030 {
1031     std::shared_ptr<Want> want = std::make_shared<Want>();
1032     ElementName element("", "", "");
1033     want->SetElement(element);
1034     want->SetAction(Constants::ACTION_UPDATEATTIMER);
1035     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_RESET_LIMIT);
1036 
1037     std::vector<std::shared_ptr<AAFwk::Want>> wants;
1038     wants.emplace_back(want);
1039     WantAgentInfo wantAgentInfo(REQUEST_LIMITER_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1040         WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
1041     return WantAgentHelper::GetWantAgent(wantAgentInfo);
1042 }
1043 
1044 /**
1045  * @brief Update dynamic refresh task alarm.
1046  * @return Returns true on success, false on failure.
1047  */
UpdateDynamicAlarm()1048 bool FormTimerMgr::UpdateDynamicAlarm()
1049 {
1050     HILOG_INFO("%{public}s start", __func__);
1051     if (dynamicRefreshTasks_.empty()) {
1052         ClearDynamicResource();
1053         dynamicWakeUpTime_ = INT64_MAX;
1054         return true;
1055     }
1056 
1057     bool needUpdate = false;
1058     DynamicRefreshItem firstTask = dynamicRefreshTasks_.at(0);
1059     if (dynamicWakeUpTime_ != firstTask.settedTime) {
1060         dynamicWakeUpTime_ = firstTask.settedTime;
1061         needUpdate = true;
1062     }
1063 
1064     if (!needUpdate) {
1065         HILOG_ERROR("%{public}s failed, no need to  UpdateDynamicAlarm.", __func__);
1066         return true;
1067     }
1068 
1069     auto timerOption = std::make_shared<FormTimerOption>();
1070     timerOption->SetType(((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
1071      | ((unsigned int)(timerOption->TIMER_TYPE_WAKEUP)));
1072     timerOption->SetRepeat(false);
1073     timerOption->SetInterval(0);
1074     std::shared_ptr<WantAgent> wantAgent = GetDynamicWantAgent(dynamicWakeUpTime_, firstTask.userId);
1075     if (!wantAgent) {
1076         HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
1077         return false;
1078     }
1079     timerOption->SetWantAgent(wantAgent);
1080 
1081     if (currentDynamicWantAgent != nullptr) {
1082         ClearDynamicResource();
1083     }
1084     currentDynamicWantAgent = wantAgent;
1085 
1086     dynamicAlarmTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
1087     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(dynamicAlarmTimerId_,
1088         static_cast<uint64_t>(dynamicWakeUpTime_));
1089     if (!bRet) {
1090         HILOG_ERROR("%{public}s failed, init dynamic timer task error", __func__);
1091     }
1092     HILOG_INFO("%{public}s end, dynamicWakeUpTime_ : %{public}" PRId64 ".", __func__, dynamicWakeUpTime_);
1093     return true;
1094 }
1095 /**
1096  * @brief Get WantAgent.
1097  * @param nextTime The next update time.
1098  * @return Returns WantAgent.
1099  */
GetDynamicWantAgent(int64_t nextTime,int32_t userId)1100 std::shared_ptr<WantAgent> FormTimerMgr::GetDynamicWantAgent(int64_t nextTime, int32_t userId)
1101 {
1102     std::shared_ptr<Want> want = std::make_shared<Want>();
1103     ElementName element("", "", "");
1104     want->SetElement(element);
1105     want->SetAction(Constants::ACTION_UPDATEATTIMER);
1106     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_DYNAMIC_UPDATE);
1107     int nextTimeRight = static_cast<int>(nextTime);
1108     int nextTimLeft = static_cast<int>(nextTime >> SHIFT_BIT_LENGTH);
1109 
1110     want->SetParam(Constants::KEY_WAKEUP_TIME_LEFT, nextTimLeft);
1111     want->SetParam(Constants::KEY_WAKEUP_TIME_RIGHT, nextTimeRight);
1112     std::vector<std::shared_ptr<AAFwk::Want>> wants;
1113     wants.emplace_back(want);
1114     WantAgentInfo wantAgentInfo(REQUEST_DYNAMIC_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1115         WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
1116     return WantAgentHelper::GetWantAgent(wantAgentInfo, userId);
1117 }
1118 
1119 /**
1120  * @brief Clear dynamic refresh resource.
1121  */
ClearDynamicResource()1122 void FormTimerMgr::ClearDynamicResource()
1123 {
1124     HILOG_INFO("%{public}s start", __func__);
1125     if (dynamicAlarmTimerId_ != 0L) {
1126         HILOG_INFO("%{public}s clear dynamic timer start", __func__);
1127         MiscServices::TimeServiceClient::GetInstance()->StopTimer(dynamicAlarmTimerId_);
1128         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(dynamicAlarmTimerId_);
1129         HILOG_INFO("%{public}s clear dynamic timer end", __func__);
1130         dynamicAlarmTimerId_ = 0L;
1131     }
1132 
1133     if (currentDynamicWantAgent != nullptr) {
1134         WantAgentHelper::Cancel(currentDynamicWantAgent);
1135         currentDynamicWantAgent = nullptr;
1136     }
1137     HILOG_INFO("%{public}s end", __func__);
1138 }
1139 /**
1140  * @brief Fint next at timer item.
1141  * @param nowTime Update time.
1142  * @param updateAtItem Next at timer item.
1143  * @return Returns true on success, false on failure.
1144  */
FindNextAtTimerItem(const long nowTime,UpdateAtItem & updateAtItem)1145 bool FormTimerMgr::FindNextAtTimerItem(const long nowTime, UpdateAtItem &updateAtItem)
1146 {
1147     HILOG_INFO("%{public}s start", __func__);
1148     if (updateAtTimerTasks_.empty()) {
1149         HILOG_WARN("%{public}s, updateAtTimerTasks_ is empty", __func__);
1150         return false;
1151     }
1152 
1153     std::lock_guard<std::mutex> lock(updateAtMutex_);
1154     std::list<UpdateAtItem>::iterator itItem;
1155     for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
1156         if (itItem->updateAtTime > nowTime) {
1157             updateAtItem = *itItem;
1158             break;
1159         }
1160     }
1161 
1162     if (itItem == updateAtTimerTasks_.end()) {
1163         updateAtItem = updateAtTimerTasks_.front();
1164     }
1165     HILOG_INFO("%{public}s end", __func__);
1166     return true;
1167 }
1168 
1169 /**
1170  * @brief Ensure init interval timer resource.
1171  */
EnsureInitIntervalTimer()1172 void FormTimerMgr::EnsureInitIntervalTimer()
1173 {
1174     HILOG_INFO("%{public}s, init base timer task", __func__);
1175     if (intervalTimer_ != nullptr) {
1176         return;
1177     }
1178 
1179     intervalTimer_ = std::make_shared<Utils::Timer>("interval timer");
1180     auto timeCallback = []() { FormTimerMgr::GetInstance().OnIntervalTimeOut(); };
1181     intervalTimer_->Register(timeCallback, Constants::MIN_PERIOD / timeSpeed_);
1182     intervalTimer_->Setup();
1183 
1184     HILOG_INFO("%{public}s end", __func__);
1185 }
1186 /**
1187  * @brief Clear interval timer resource.
1188  */
ClearIntervalTimer()1189 void FormTimerMgr::ClearIntervalTimer()
1190 {
1191     HILOG_INFO("%{public}s start", __func__);
1192     if (intervalTimer_ != nullptr) {
1193         intervalTimer_->Shutdown();
1194         intervalTimer_.reset();
1195     }
1196     HILOG_INFO("%{public}s end", __func__);
1197 }
1198 /**
1199  * @brief Creat thread pool for timer task.
1200  */
1201 
CreatTaskThreadExecutor()1202 void FormTimerMgr::CreatTaskThreadExecutor()
1203 {
1204     HILOG_INFO("%{public}s start", __func__);
1205     if (taskExecutor_ == nullptr) {
1206         taskExecutor_ = std::make_unique<ThreadPool>("timer task thread");
1207         taskExecutor_->Start(Constants::WORK_POOL_SIZE);
1208     }
1209     HILOG_INFO("%{public}s end", __func__);
1210     return;
1211 }
1212 
1213 /**
1214  * @brief Execute Form timer task.
1215  * @param timerTask Form timer task.
1216  */
ExecTimerTask(const FormTimer & timerTask)1217 void FormTimerMgr::ExecTimerTask(const FormTimer &timerTask)
1218 {
1219     HILOG_INFO("%{public}s start", __func__);
1220     CreatTaskThreadExecutor();
1221     if (taskExecutor_ != nullptr) {
1222         HILOG_INFO("%{public}s run", __func__);
1223         AAFwk::Want want;
1224         if (timerTask.isCountTimer) {
1225             want.SetParam(Constants::KEY_IS_TIMER, true);
1226         }
1227         // multi user
1228         if (IsActiveUser(timerTask.userId)) {
1229             HILOG_INFO("timerTask.userId is current user");
1230             want.SetParam(Constants::PARAM_FORM_USER_ID, timerTask.userId);
1231         }
1232         HILOG_INFO("%{public}s, userId:%{public}d", __func__, timerTask.userId);
1233 
1234         auto task = std::bind(&FormProviderMgr::RefreshForm, &FormProviderMgr::GetInstance(), timerTask.formId, want,
1235             false);
1236         taskExecutor_->AddTask(task);
1237     }
1238     HILOG_INFO("%{public}s end", __func__);
1239 }
1240 
1241 /**
1242  * @brief Init.
1243  */
Init()1244 void FormTimerMgr::Init()
1245 {
1246     HILOG_INFO("%{public}s start", __func__);
1247     timerReceiver_ = nullptr;
1248     EventFwk::MatchingSkills matchingSkills;
1249     matchingSkills.AddEvent(Constants::ACTION_UPDATEATTIMER);
1250     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
1251     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED);
1252     matchingSkills.AddEvent(FMS_TIME_SPEED);
1253 
1254     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
1255     timerReceiver_ = std::make_shared<TimerReceiver>(subscribeInfo);
1256     EventFwk::CommonEventManager::SubscribeCommonEvent(timerReceiver_);
1257 
1258     intervalTimer_ = nullptr;
1259     updateAtTimerId_ = 0L;
1260     dynamicAlarmTimerId_ = 0L;
1261     limiterTimerId_ = 0L;
1262     taskExecutor_ = nullptr;
1263 
1264     HILOG_INFO("%{public}s end", __func__);
1265 }
1266 
1267 /**
1268  * @brief Receiver Constructor.
1269  * @param subscriberInfo Subscriber info.
1270  */
TimerReceiver(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)1271 FormTimerMgr::TimerReceiver::TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
1272     : EventFwk::CommonEventSubscriber(subscriberInfo)
1273 {}
1274 /**
1275  * @brief Receive common event.
1276  * @param eventData Common event data.
1277  */
OnReceiveEvent(const EventFwk::CommonEventData & eventData)1278 void FormTimerMgr::TimerReceiver::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
1279 {
1280     AAFwk::Want want = eventData.GetWant();
1281     std::string action = want.GetAction();
1282 
1283     HILOG_INFO("%{public}s, action:%{public}s.", __func__, action.c_str());
1284 
1285     if (action == FMS_TIME_SPEED) {
1286         // Time speed must between 1 and 1000.
1287         auto timeSpeed = std::clamp(eventData.GetCode(), Constants::MIN_TIME_SPEED, Constants::MAX_TIME_SPEED);
1288         FormTimerMgr::GetInstance().SetTimeSpeed(timeSpeed);
1289     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED
1290         || action == EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED) {
1291         FormTimerMgr::GetInstance().HandleSystemTimeChanged();
1292     } else if (action == Constants::ACTION_UPDATEATTIMER) {
1293         int type = want.GetIntParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_STATIC_UPDATE);
1294         if (type == Constants::TYPE_RESET_LIMIT) {
1295             FormTimerMgr::GetInstance().HandleResetLimiter();
1296         } else if (type == Constants::TYPE_STATIC_UPDATE) {
1297             long updateTime = want.GetLongParam(Constants::KEY_WAKEUP_TIME, -1);
1298             if (updateTime < 0) {
1299                 HILOG_ERROR("%{public}s failed, invalid updateTime:%{public}ld.", __func__, updateTime);
1300                 return;
1301             }
1302             FormTimerMgr::GetInstance().OnUpdateAtTrigger(updateTime);
1303         } else if (type == Constants::TYPE_DYNAMIC_UPDATE) {
1304             int updateTimeLeft = want.GetIntParam(Constants::KEY_WAKEUP_TIME_LEFT, -1);
1305             int updateTimeRight = want.GetIntParam(Constants::KEY_WAKEUP_TIME_RIGHT, -1);
1306             int64_t updateTime = static_cast<int64_t>(updateTimeLeft);
1307             updateTime = updateTime << SHIFT_BIT_LENGTH;
1308             updateTime |= updateTimeRight;
1309             if (updateTime <= 0) {
1310                 HILOG_ERROR("%{public}s failed, invalid updateTime:%{public}" PRId64 "", __func__, updateTime);
1311                 return;
1312             }
1313             FormTimerMgr::GetInstance().OnDynamicTimeTrigger(updateTime);
1314         } else {
1315             HILOG_ERROR("%{public}s failed, invalid type when action is update at timer.", __func__);
1316         }
1317     } else {
1318         HILOG_ERROR("%{public}s failed, invalid action.", __func__);
1319     }
1320 }
1321 /**
1322  * @brief check if user is active or not.
1323  *
1324  * @param userId User ID.
1325  * @return true:active, false:inactive
1326  */
IsActiveUser(const int32_t userId)1327 bool FormTimerMgr::IsActiveUser(const int32_t userId)
1328 {
1329     std::vector<int32_t> activeList;
1330     auto refCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeList);
1331     auto iter = std::find(activeList.begin(), activeList.end(), userId);
1332     if (iter != activeList.end() && refCode == ERR_OK) {
1333         return true;
1334     }
1335     return false;
1336 }
1337 }  // namespace AppExecFwk
1338 }  // namespace OHOS
1339