• 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 "common_event_manager.h"
21 #include "common_event_support.h"
22 #include "context/context.h"
23 #include "form_constants.h"
24 #include "form_provider_mgr.h"
25 #include "form_timer_option.h"
26 #include "form_util.h"
27 #include "hilog_wrapper.h"
28 #include "in_process_call_wrapper.h"
29 #include "os_account_manager_wrapper.h"
30 #include "time_service_client.h"
31 #include "want.h"
32 
33 namespace OHOS {
34 namespace AppExecFwk {
35 namespace {
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 int NANO_TO_SECOND =  1000000000;
41 const std::string FMS_TIME_SPEED = "fms.time_speed";
42 } // namespace
43 
FormTimerMgr()44 FormTimerMgr::FormTimerMgr()
45 {
46     Init();
47 }
~FormTimerMgr()48 FormTimerMgr::~FormTimerMgr()
49 {
50     ClearIntervalTimer();
51 }
52 /**
53  * @brief Add form timer by timer task.
54  * @param task The form timer task.
55  * @return Returns true on success, false on failure.
56  */
AddFormTimer(const FormTimer & task)57 bool FormTimerMgr::AddFormTimer(const FormTimer &task)
58 {
59     HILOG_INFO("%{public}s formId:%{public}s userId:%{public}d", __func__,
60         std::to_string(task.formId).c_str(), task.userId);
61     if (task.isUpdateAt) {
62         if (task.hour >= Constants::MIN_TIME && task.hour <= Constants::MAX_HOUR &&
63             task.min >= Constants::MIN_TIME && task.min <= Constants::MAX_MINUTE) {
64             return AddUpdateAtTimer(task);
65         } else {
66             HILOG_ERROR("%{public}s failed, update at time is invalid", __func__);
67             return false;
68         }
69     } else {
70         if (task.period >= (Constants::MIN_PERIOD / timeSpeed_) && // Min period is 30 minutes
71             task.period <= (Constants::MAX_PERIOD / timeSpeed_) && // Max period is 1 week
72             task.period % (Constants::MIN_PERIOD / timeSpeed_) == 0) {
73             return AddIntervalTimer(task);
74         } else {
75             HILOG_ERROR("%{public}s failed, interval time is invalid", __func__);
76             return false;
77         }
78     }
79 }
80 /**
81  * @brief Add duration form timer.
82  * @param formId The Id of the form.
83  * @param updateDuration Update duration
84  * @param userId User ID.
85  * @return Returns true on success, false on failure.
86  */
AddFormTimer(int64_t formId,long updateDuration,int32_t userId)87 bool FormTimerMgr::AddFormTimer(int64_t formId, long updateDuration, int32_t userId)
88 {
89     auto duration = updateDuration / timeSpeed_;
90     HILOG_INFO("%{public}s formId:%{public}s duration:%{public}s", __func__,
91         std::to_string(formId).c_str(), std::to_string(duration).c_str());
92     FormTimer timerTask(formId, duration, userId);
93     return AddFormTimer(timerTask);
94 }
95 /**
96  * @brief Add scheduled form timer.
97  * @param formId The Id of the form.
98  * @param updateAtHour Hour.
99  * @param updateAtMin Min.
100  * @param userId User ID.
101  * @return Returns true on success, false on failure.
102  */
AddFormTimer(int64_t formId,long updateAtHour,long updateAtMin,int32_t userId)103 bool FormTimerMgr::AddFormTimer(int64_t formId, long updateAtHour, long updateAtMin, int32_t userId)
104 {
105     HILOG_INFO("%{public}s formId:%{public}s time:%{public}s-%{public}s", __func__,
106         std::to_string(formId).c_str(), std::to_string(updateAtHour).c_str(), std::to_string(updateAtMin).c_str());
107     FormTimer timerTask(formId, updateAtHour, updateAtMin, userId);
108     return AddFormTimer(timerTask);
109 }
110 /**
111  * @brief Remove form timer by form id.
112  * @param formId The Id of the form.
113  * @return Returns true on success, false on failure.
114  */
RemoveFormTimer(int64_t formId)115 bool FormTimerMgr::RemoveFormTimer(int64_t formId)
116 {
117     HILOG_INFO("%{public}s, task: %{public}" PRId64 "", __func__, formId);
118 
119     if (!DeleteIntervalTimer(formId)) {
120         if (!DeleteUpdateAtTimer(formId)) {
121             HILOG_ERROR("%{public}s, failed to DeleteUpdateAtTimer", __func__);
122             return false;
123         }
124     }
125 
126     if (!DeleteDynamicItem(formId)) {
127         HILOG_ERROR("%{public}s, failed to DeleteDynamicItem", __func__);
128         return false;
129     }
130     refreshLimiter_.DeleteItem(formId);
131 
132     return true;
133 }
134 /**
135  * @brief Update form timer.
136  * @param formId The Id of the form.
137  * @param type Timer type.
138  * @param timerCfg Timer config.
139  * @return Returns true on success, false on failure.
140  */
UpdateFormTimer(int64_t formId,const UpdateType & type,const FormTimerCfg & timerCfg)141 bool FormTimerMgr::UpdateFormTimer(int64_t formId, const UpdateType &type, const FormTimerCfg &timerCfg)
142 {
143     if (!timerCfg.enableUpdate) {
144         HILOG_WARN("%{public}s, enableUpdate is false", __func__);
145         return false;
146     }
147 
148     switch (type) {
149         case UpdateType::TYPE_INTERVAL_CHANGE: {
150             return UpdateIntervalValue(formId, timerCfg);
151         }
152         case UpdateType::TYPE_ATTIME_CHANGE: {
153             return UpdateAtTimerValue(formId, timerCfg);
154         }
155         case UpdateType::TYPE_INTERVAL_TO_ATTIME: {
156             return IntervalToAtTimer(formId, timerCfg);
157         }
158         case UpdateType::TYPE_ATTIME_TO_INTERVAL: {
159             return AtTimerToIntervalTimer(formId, timerCfg);
160         }
161         default: {
162             HILOG_ERROR("%{public}s failed, invalid UpdateType", __func__);
163             return false;
164         }
165     }
166 }
167 /**
168  * @brief Update Interval timer task value.
169  * @param formId The Id of the form.
170  * @param timerCfg task value.
171  * @return Returns true on success, false on failure.
172  */
UpdateIntervalValue(int64_t formId,const FormTimerCfg & timerCfg)173 bool FormTimerMgr::UpdateIntervalValue(int64_t formId, const FormTimerCfg &timerCfg)
174 {
175     if (timerCfg.updateDuration < Constants::MIN_PERIOD || timerCfg.updateDuration > Constants::MAX_PERIOD
176         || (timerCfg.updateDuration % Constants::MIN_PERIOD) != 0) {
177         HILOG_ERROR("%{public}s failed, invalid param", __func__);
178         return false;
179     }
180 
181     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
182     auto intervalTask = intervalTimerTasks_.find(formId);
183     if (intervalTask != intervalTimerTasks_.end()) {
184         intervalTask->second.period = timerCfg.updateDuration / timeSpeed_;
185         return true;
186     } else {
187         HILOG_ERROR("%{public}s failed, the interval timer is not exist", __func__);
188         return false;
189     }
190 }
191 /**
192  * @brief Update update at timer task value.
193  * @param formId The Id of the form.
194  * @param timerCfg task value.
195  * @return Returns true on success, false on failure.
196  */
UpdateAtTimerValue(int64_t formId,const FormTimerCfg & timerCfg)197 bool FormTimerMgr::UpdateAtTimerValue(int64_t formId, const FormTimerCfg &timerCfg)
198 {
199     if (timerCfg.updateAtHour < Constants::MIN_TIME || timerCfg.updateAtHour > Constants::MAX_HOUR
200         || timerCfg.updateAtMin < Constants::MIN_TIME || timerCfg.updateAtMin > Constants::MAX_MINUTE) {
201         HILOG_ERROR("%{public}s failed, time is invalid", __func__);
202         return false;
203     }
204     {
205         std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
206         std::list<UpdateAtItem>::iterator itItem;
207         UpdateAtItem changedItem;
208         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
209             if (itItem->refreshTask.formId == formId) {
210                 changedItem = *itItem;
211                 updateAtTimerTasks_.erase(itItem);
212                 break;
213             }
214         }
215 
216         if (changedItem.refreshTask.formId == 0) {
217             HILOG_ERROR("%{public}s failed, the update at timer is not exist", __func__);
218             return false;
219         }
220         changedItem.refreshTask.hour = timerCfg.updateAtHour;
221         changedItem.refreshTask.min = timerCfg.updateAtMin;
222         changedItem.updateAtTime = changedItem.refreshTask.hour * Constants::MIN_PER_HOUR + changedItem.refreshTask.min;
223         AddUpdateAtItem(changedItem);
224     }
225 
226     if (!UpdateAtTimerAlarm()) {
227         HILOG_ERROR("%{public}s, failed to update at timer alarm.", __func__);
228         return false;
229     }
230     return true;
231 }
232 /**
233  * @brief Interval timer task to update at timer task.
234  * @param formId The Id of the form.
235  * @param timerCfg task value.
236  * @return Returns true on success, false on failure.
237  */
IntervalToAtTimer(int64_t formId,const FormTimerCfg & timerCfg)238 bool FormTimerMgr::IntervalToAtTimer(int64_t formId, const FormTimerCfg &timerCfg)
239 {
240     if (timerCfg.updateAtHour < Constants::MIN_TIME || timerCfg.updateAtHour > Constants::MAX_HOUR
241         || timerCfg.updateAtMin < Constants::MIN_TIME || timerCfg.updateAtMin > Constants::MAX_MINUTE) {
242         HILOG_ERROR("%{public}s failed, time is invalid", __func__);
243         return false;
244     }
245 
246     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
247     FormTimer timerTask;
248     auto intervalTask = intervalTimerTasks_.find(formId);
249     if (intervalTask != intervalTimerTasks_.end()) {
250         timerTask = intervalTask->second;
251         intervalTimerTasks_.erase(intervalTask);
252 
253         timerTask.isUpdateAt = true;
254         timerTask.hour = timerCfg.updateAtHour;
255         timerTask.min = timerCfg.updateAtMin;
256         if (!AddUpdateAtTimer(timerTask)) {
257             HILOG_ERROR("%{public}s, failed to add update at timer", __func__);
258             return false;
259         }
260         return true;
261     } else {
262         HILOG_ERROR("%{public}s failed, the interval timer is not exist", __func__);
263         return false;
264     }
265 }
266 /**
267  * @brief Update at timer task to interval timer task.
268  * @param formId The Id of the form.
269  * @param timerCfg task value.
270  * @return Returns true on success, false on failure.
271  */
AtTimerToIntervalTimer(int64_t formId,const FormTimerCfg & timerCfg)272 bool FormTimerMgr::AtTimerToIntervalTimer(int64_t formId, const FormTimerCfg &timerCfg)
273 {
274     if (timerCfg.updateDuration < Constants::MIN_PERIOD || timerCfg.updateDuration > Constants::MAX_PERIOD
275         || (timerCfg.updateDuration % Constants::MIN_PERIOD) != 0) {
276         HILOG_ERROR("%{public}s failed, time is invalid", __func__);
277         return false;
278     }
279 
280     UpdateAtItem targetItem;
281     {
282         std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
283         std::list<UpdateAtItem>::iterator itItem;
284         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
285             if (itItem->refreshTask.formId == formId) {
286                 targetItem = *itItem;
287                 updateAtTimerTasks_.erase(itItem);
288                 break;
289             }
290         }
291     }
292 
293     if (!UpdateAtTimerAlarm()) {
294         HILOG_ERROR("%{public}s, failed to update at timer alarm.", __func__);
295         return false;
296     }
297 
298     if (targetItem.refreshTask.formId == 0) {
299         HILOG_ERROR("%{public}s failed, the update at timer is not exist", __func__);
300         return false;
301     }
302     targetItem.refreshTask.isUpdateAt = false;
303     targetItem.refreshTask.period = timerCfg.updateDuration;
304     targetItem.refreshTask.refreshTime = FormUtil::GetCurrentNanosecond() / Constants::TIME_1000000;
305     if (!AddIntervalTimer(targetItem.refreshTask)) {
306         HILOG_ERROR("%{public}s, failed to add interval timer", __func__);
307         return false;
308     }
309     return true;
310 }
311 /**
312  * @brief Is limiter enable refresh.
313  * @param formId The Id of the form.
314  * @return Returns true on success, false on failure.
315  */
IsLimiterEnableRefresh(int64_t formId)316 bool FormTimerMgr::IsLimiterEnableRefresh(int64_t formId)
317 {
318     return refreshLimiter_.IsEnableRefresh(formId);
319 }
320 /**
321  * @brief Increase refresh count.
322  * @param formId The Id of the form.
323  */
IncreaseRefreshCount(int64_t formId)324 void FormTimerMgr::IncreaseRefreshCount(int64_t formId)
325 {
326     refreshLimiter_.Increase(formId);
327 }
328 /**
329  * @brief Set next refresh time.
330  * @param formId The Id of the form.
331  * @param nextGapTime Next gap time(ms).
332  * @param userId User ID.
333  * @return Returns true on success, false on failure.
334  */
SetNextRefreshTime(int64_t formId,long nextGapTime,int32_t userId)335 bool FormTimerMgr::SetNextRefreshTime(int64_t formId, long nextGapTime, int32_t userId)
336 {
337     if (nextGapTime < Constants::MIN_NEXT_TIME) {
338         HILOG_ERROR("%{public}s failed, nextGapTime is invalid, nextGapTime:%{public}ld", __func__, nextGapTime);
339         return false;
340     }
341     int64_t timeInSec = GetBootTimeMs();
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     bool isExist = false;
346     std::lock_guard<std::recursive_mutex> lock(dynamicMutex_);
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     dynamicRefreshTasks_.sort(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     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
380     auto iter = intervalTimerTasks_.find(formId);
381     if (iter != intervalTimerTasks_.end()) {
382         iter->second.isEnable = flag;
383         HILOG_INFO("%{public}s, formId:%{public}" PRId64 ", isEnable:%{public}d", __func__, formId, flag);
384         return;
385     }
386 }
387 
388 /**
389  * @brief Get refresh count.
390  * @param formId The Id of the form.
391  * @return Returns refresh count.
392  */
GetRefreshCount(int64_t formId) const393 int FormTimerMgr::GetRefreshCount(int64_t formId) const
394 {
395     return refreshLimiter_.GetRefreshCount(formId);
396 }
397 /**
398  * @brief Mark remind.
399  * @param formId The Id of the form.
400  * @return true or false.
401  */
MarkRemind(int64_t formId)402 void FormTimerMgr::MarkRemind(int64_t formId)
403 {
404     refreshLimiter_.MarkRemind(formId);
405 }
406 /**
407  * @brief Add update at timer.
408  * @param task Update time task.
409  * @return Returns true on success, false on failure.
410  */
AddUpdateAtTimer(const FormTimer & task)411 bool FormTimerMgr::AddUpdateAtTimer(const FormTimer &task)
412 {
413     HILOG_INFO("%{public}s start", __func__);
414     {
415         std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
416         for (const auto &updateAtTimer : updateAtTimerTasks_) {
417             if (updateAtTimer.refreshTask.formId == task.formId) {
418                 HILOG_WARN("%{public}s, already exist formTimer, formId:%{public}" PRId64 " task",
419                     __func__, task.formId);
420                 return true;
421             }
422         }
423     }
424     UpdateAtItem atItem;
425     atItem.refreshTask = task;
426     atItem.updateAtTime = task.hour * Constants::MIN_PER_HOUR + task.min;
427     AddUpdateAtItem(atItem);
428     if (!UpdateLimiterAlarm()) {
429         HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
430         return false;
431     }
432 
433     if (!UpdateAtTimerAlarm()) {
434         HILOG_ERROR("%{public}s, failed to update at timer alarm.", __func__);
435         return false;
436     }
437 
438     return refreshLimiter_.AddItem(task.formId);
439 }
440 /**
441  * @brief Add update interval timer task.
442  * @param task Update interval timer task.
443  * @return Returns true on success, false on failure.
444  */
AddIntervalTimer(const FormTimer & task)445 bool FormTimerMgr::AddIntervalTimer(const FormTimer &task)
446 {
447     HILOG_INFO("%{public}s start", __func__);
448     {
449         std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
450         EnsureInitIntervalTimer();
451         if (intervalTimerTasks_.find(task.formId) != intervalTimerTasks_.end()) {
452             HILOG_WARN("%{public}s, already exist formTimer, formId:%{public}" PRId64 " task", __func__, task.formId);
453             return true;
454         }
455         intervalTimerTasks_.emplace(task.formId, task);
456     }
457     if (!UpdateLimiterAlarm()) {
458         HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
459         return false;
460     }
461     return refreshLimiter_.AddItem(task.formId);
462 }
463 /**
464  * @brief Add update at timer item.
465  * @param task Update at timer item.
466  */
AddUpdateAtItem(const UpdateAtItem & atItem)467 void FormTimerMgr::AddUpdateAtItem(const UpdateAtItem &atItem)
468 {
469     std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
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     std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
503     if (!updateAtTimerTasks_.empty()) {
504         atTimerWakeUpTime_ = LONG_MAX;
505         UpdateAtTimerAlarm();
506     }
507     UpdateLimiterAlarm();
508     HILOG_INFO("%{public}s end", __func__);
509     return true;
510 }
511 /**
512  * @brief Reset form limiter.
513  * @return Returns true on success, false on failure.
514  */
HandleResetLimiter()515 bool FormTimerMgr::HandleResetLimiter()
516 {
517     HILOG_INFO("%{public}s start", __func__);
518 
519     std::vector<FormTimer> remindTasks;
520     bool bGetTasks = GetRemindTasks(remindTasks);
521     if (bGetTasks) {
522         HILOG_INFO("%{public}s failed, remind when reset limiter", __func__);
523         for (auto &task : remindTasks) {
524             ExecTimerTask(task);
525         }
526     }
527 
528     HILOG_INFO("%{public}s end", __func__);
529     return true;
530 }
531 /**
532  * @brief Update at time trigger.
533  * @param updateTime Update time.
534  * @return Returns true on success, false on failure.
535  */
OnUpdateAtTrigger(long updateTime)536 bool FormTimerMgr::OnUpdateAtTrigger(long updateTime)
537 {
538     HILOG_INFO("%{public}s start, updateTime:%{public}ld", __func__, updateTime);
539     std::vector<UpdateAtItem> updateList;
540     {
541         std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
542         std::list<UpdateAtItem>::iterator itItem;
543         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
544             if (itItem->updateAtTime == updateTime && itItem->refreshTask.isEnable) {
545                 updateList.emplace_back(*itItem);
546             }
547         }
548     }
549 
550     if (!UpdateAtTimerAlarm()) {
551         HILOG_ERROR("%{public}s, failed to update at timer alarm.", __func__);
552         return false;
553     }
554 
555     if (!updateList.empty()) {
556         HILOG_INFO("%{public}s, update at timer triggered, trigger time: %{public}ld", __func__, updateTime);
557         for (auto &item : updateList) {
558             ExecTimerTask(item.refreshTask);
559         }
560     }
561 
562     HILOG_INFO("%{public}s end", __func__);
563     return true;
564 }
565 /**
566  * @brief Dynamic time trigger.
567  * @param updateTime Update time.
568  * @return Returns true on success, false on failure.
569  */
OnDynamicTimeTrigger(int64_t updateTime)570 bool FormTimerMgr::OnDynamicTimeTrigger(int64_t updateTime)
571 {
572     HILOG_INFO("%{public}s start, updateTime:%{public}" PRId64 "", __func__, updateTime);
573     std::vector<FormTimer> updateList;
574     {
575         std::lock_guard<std::recursive_mutex> lock(dynamicMutex_);
576         auto timeInSec = GetBootTimeMs();
577         int64_t markedTime = timeInSec + Constants::ABS_REFRESH_MS;
578         std::list<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         dynamicRefreshTasks_.sort(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, trigger 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::recursive_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);
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(int64_t formId,FormTimer & formTimer)657 bool FormTimerMgr::GetIntervalTimer(int64_t formId, FormTimer &formTimer)
658 {
659     HILOG_INFO("%{public}s start", __func__);
660     std::lock_guard<std::recursive_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(int64_t formId,UpdateAtItem & updateAtItem)675 bool FormTimerMgr::GetUpdateAtTimer(int64_t formId, UpdateAtItem &updateAtItem)
676 {
677     HILOG_INFO("%{public}s start", __func__);
678     {
679         std::lock_guard<std::recursive_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(int64_t formId,DynamicRefreshItem & dynamicItem)698 bool FormTimerMgr::GetDynamicItem(int64_t formId, DynamicRefreshItem &dynamicItem)
699 {
700     HILOG_INFO("%{public}s start", __func__);
701     std::lock_guard<std::recursive_mutex> lock(dynamicMutex_);
702     std::list<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(int64_t formId)731 bool FormTimerMgr::DeleteIntervalTimer(int64_t formId)
732 {
733     HILOG_INFO("%{public}s start", __func__);
734     bool isExist = false;
735     std::lock_guard<std::recursive_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(int64_t formId)753 bool FormTimerMgr::DeleteUpdateAtTimer(int64_t formId)
754 {
755     HILOG_INFO("%{public}s start", __func__);
756     {
757         std::lock_guard<std::recursive_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 at timer 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(int64_t formId)778 bool FormTimerMgr::DeleteDynamicItem(int64_t formId)
779 {
780     HILOG_INFO("%{public}s start", __func__);
781     std::lock_guard<std::recursive_mutex> lock(dynamicMutex_);
782     std::list<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         ++itItem;
792     }
793     dynamicRefreshTasks_.sort(CompareDynamicRefreshItem);
794 
795     if (!UpdateDynamicAlarm()) {
796         HILOG_ERROR("%{public}s, failed to UpdateDynamicAlarm", __func__);
797         return false;
798     }
799     HILOG_INFO("%{public}s end", __func__);
800     return true;
801 }
802 /**
803 * @brief interval timer task timeout.
804 */
OnIntervalTimeOut()805 void FormTimerMgr::OnIntervalTimeOut()
806 {
807     HILOG_INFO("%{public}s start", __func__);
808     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
809     std::vector<FormTimer> updateList;
810     int64_t currentTime = FormUtil::GetCurrentNanosecond() / Constants::TIME_1000000;
811     for (auto &intervalPair : intervalTimerTasks_) {
812         FormTimer &intervalTask = intervalPair.second;
813         HILOG_INFO("intervalTask form id is %{public}" PRId64 ", period is %{public}" PRId64 "",
814             intervalTask.formId, intervalTask.period);
815         if (((currentTime - intervalTask.refreshTime) >= intervalTask.period ||
816             std::abs((currentTime - intervalTask.refreshTime) - intervalTask.period) < Constants::ABS_TIME) &&
817             intervalTask.isEnable && refreshLimiter_.IsEnableRefresh(intervalTask.formId)) {
818             intervalTask.refreshTime = currentTime;
819             updateList.emplace_back(intervalTask);
820         }
821     }
822 
823     if (!updateList.empty()) {
824         for (auto &task : updateList) {
825             ExecTimerTask(task);
826         }
827     }
828     HILOG_INFO("%{public}s end", __func__);
829 }
830 
831 /**
832  * @brief Update at timer task alarm.
833  * @return Returns true on success, false on failure.
834  */
UpdateAtTimerAlarm()835 bool FormTimerMgr::UpdateAtTimerAlarm()
836 {
837     HILOG_INFO("%{public}s start", __func__);
838     struct tm tmAtTime = {0};
839     auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
840     struct tm* ptm = localtime_r(&tt, &tmAtTime);
841     if (ptm == nullptr) {
842         HILOG_ERROR("%{public}s failed, localtime error", __func__);
843         return false;
844     }
845 
846     long nowAtTime = tmAtTime.tm_hour * Constants::MIN_PER_HOUR + tmAtTime.tm_min;
847     int64_t currentTime = FormUtil::GetCurrentMillisecond();
848     UpdateAtItem foundItem;
849     bool found = FindNextAtTimerItem(nowAtTime, foundItem);
850     if (!found) {
851         {
852             std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
853             if (!updateAtTimerTasks_.empty()) {
854                 HILOG_WARN("%{public}s, updateAtTimerTasks_ is not empty", __func__);
855                 return true;
856             }
857         }
858         ClearUpdateAtTimerResource();
859         atTimerWakeUpTime_ = LONG_MAX;
860         HILOG_INFO("%{public}s, no update at task in system now.", __func__);
861         return true;
862     }
863 
864     long nextWakeUpTime = foundItem.updateAtTime;
865     tmAtTime.tm_sec = 0;
866     tmAtTime.tm_hour = foundItem.refreshTask.hour;
867     tmAtTime.tm_min = foundItem.refreshTask.min;
868     int64_t selectTime = FormUtil::GetMillisecondFromTm(tmAtTime);
869     if (selectTime < currentTime) {
870         selectTime += Constants::MS_PER_DAY;
871         nextWakeUpTime += (Constants::HOUR_PER_DAY * Constants::MIN_PER_HOUR);
872     }
873     HILOG_INFO("%{public}s, selectTime: %{public}" PRId64 ", currentTime: %{public}" PRId64 ".",
874         __func__, selectTime, currentTime);
875 
876     if (nextWakeUpTime == atTimerWakeUpTime_) {
877         HILOG_WARN("%{public}s end, wakeUpTime not change, no need update alarm.", __func__);
878         return true;
879     }
880 
881     auto timerOption = std::make_shared<FormTimerOption>();
882     int32_t flag = ((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
883       | ((unsigned int)(timerOption->TIMER_TYPE_WAKEUP)) | ((unsigned int)(timerOption->TIMER_TYPE_EXACT));
884     HILOG_DEBUG("timerOption type is %{public}d", flag);
885     timerOption->SetType(flag);
886     timerOption->SetRepeat(false);
887     timerOption->SetInterval(0);
888     int32_t userId = foundItem.refreshTask.userId;
889     std::shared_ptr<WantAgent> wantAgent = GetUpdateAtWantAgent(foundItem.updateAtTime, userId);
890     if (wantAgent == nullptr) {
891         HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
892         return false;
893     }
894     timerOption->SetWantAgent(wantAgent);
895 
896     atTimerWakeUpTime_ = nextWakeUpTime;
897     if (currentUpdateAtWantAgent_ != nullptr) {
898         ClearUpdateAtTimerResource();
899     }
900     int64_t timeInSec = GetBootTimeMs();
901     HILOG_DEBUG("timeInSec: %{public}" PRId64 ".", timeInSec);
902     int64_t nextTime = timeInSec + (selectTime - currentTime);
903     HILOG_INFO("%{public}s, nextTime: %{public}" PRId64 ".", __func__, nextTime);
904 
905     currentUpdateAtWantAgent_ = wantAgent;
906     updateAtTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
907     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(updateAtTimerId_,
908         static_cast<uint64_t>(nextTime));
909     if (!bRet) {
910         HILOG_ERROR("%{public}s failed, init update at timer task error", __func__);
911         return false;
912     }
913 
914     HILOG_INFO("%{public}s end", __func__);
915     return true;
916 }
917 
GetBootTimeMs()918 int64_t FormTimerMgr::GetBootTimeMs()
919 {
920     int64_t timeNow = -1;
921     struct timespec tv {};
922     if (clock_gettime(CLOCK_BOOTTIME, &tv) < 0) {
923         HILOG_WARN("Get bootTime by clock_gettime failed, use std::chrono::steady_clock");
924         auto timeSinceEpoch = std::chrono::steady_clock::now().time_since_epoch();
925         return std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
926     }
927     timeNow = tv.tv_sec * NANO_TO_SECOND + tv.tv_nsec;
928     std::chrono::steady_clock::time_point tp_epoch ((std::chrono::nanoseconds(timeNow)));
929     auto timeSinceEpoch = tp_epoch.time_since_epoch();
930     return std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
931 }
932 
933 /**
934  * @brief Get WantAgent.
935  * @param updateAtTime The next update time.
936  * @return Returns WantAgent.
937  */
GetUpdateAtWantAgent(long updateAtTime,int32_t userId)938 std::shared_ptr<WantAgent> FormTimerMgr::GetUpdateAtWantAgent(long updateAtTime, int32_t userId)
939 {
940     std::shared_ptr<Want> want = std::make_shared<Want>();
941     ElementName element("", "", "");
942     want->SetElement(element);
943     want->SetAction(Constants::ACTION_UPDATEATTIMER);
944     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_STATIC_UPDATE);
945     want->SetParam(Constants::KEY_WAKEUP_TIME, updateAtTime);
946 
947     std::vector<std::shared_ptr<AAFwk::Want>> wants;
948     wants.emplace_back(want);
949     WantAgentInfo wantAgentInfo(REQUEST_UPDATE_AT_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
950         WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
951     return IN_PROCESS_CALL(WantAgentHelper::GetWantAgent(wantAgentInfo, userId));
952 }
953 
954 /**
955  * @brief Clear update at timer resource.
956  */
ClearUpdateAtTimerResource()957 void FormTimerMgr::ClearUpdateAtTimerResource()
958 {
959     HILOG_INFO("%{public}s start", __func__);
960     if (updateAtTimerId_ != 0L) {
961         HILOG_INFO("%{public}s clear update at timer start", __func__);
962         MiscServices::TimeServiceClient::GetInstance()->StopTimer(updateAtTimerId_);
963         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(updateAtTimerId_);
964         HILOG_INFO("%{public}s clear update at timer end", __func__);
965         updateAtTimerId_ = 0L;
966     }
967     if (currentUpdateAtWantAgent_ != nullptr) {
968         WantAgentHelper::Cancel(currentUpdateAtWantAgent_);
969         currentUpdateAtWantAgent_ = nullptr;
970     }
971     HILOG_INFO("%{public}s end", __func__);
972 }
973 
974 /**
975  * @brief Update limiter task alarm.
976  * @return Returns true on success, false on failure.
977  */
UpdateLimiterAlarm()978 bool FormTimerMgr::UpdateLimiterAlarm()
979 {
980     HILOG_INFO("%{public}s start", __func__);
981     if (limiterTimerId_ != 0L) {
982         HILOG_INFO("%{public}s clear limiter timer start", __func__);
983         MiscServices::TimeServiceClient::GetInstance()->StopTimer(limiterTimerId_);
984         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(limiterTimerId_);
985         HILOG_INFO("%{public}s clear limiter timer end", __func__);
986         limiterTimerId_ = 0L;
987     }
988 
989     // make limiter wakeup time
990     struct tm tmAtTime = {0};
991     auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
992     struct tm* ptm = localtime_r(&tt, &tmAtTime);
993     if (ptm == nullptr) {
994         HILOG_ERROR("%{public}s failed, localtime error", __func__);
995         return false;
996     }
997     tmAtTime.tm_sec = Constants::MAX_SECOND; // max value can be 61
998     tmAtTime.tm_hour = Constants::MAX_HOUR;
999     tmAtTime.tm_min = Constants::MAX_MINUTE;
1000     int64_t limiterWakeUpTime = FormUtil::GetMillisecondFromTm(tmAtTime);
1001 
1002     auto timerOption = std::make_shared<FormTimerOption>();
1003     timerOption->SetType(timerOption->TIMER_TYPE_WAKEUP);
1004     timerOption->SetRepeat(false);
1005     timerOption->SetInterval(0);
1006     std::shared_ptr<WantAgent> wantAgent = GetLimiterWantAgent();
1007     if (!wantAgent) {
1008         HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
1009         return false;
1010     }
1011     timerOption->SetWantAgent(wantAgent);
1012 
1013     if (currentLimiterWantAgent_ != nullptr) {
1014         ClearLimiterTimerResource();
1015     }
1016     currentLimiterWantAgent_ = wantAgent;
1017 
1018     limiterTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
1019     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(limiterTimerId_,
1020         static_cast<uint64_t>(limiterWakeUpTime));
1021     if (!bRet) {
1022         HILOG_ERROR("%{public}s failed, init limiter timer task error", __func__);
1023         return false;
1024     }
1025     HILOG_INFO("%{public}s end", __func__);
1026     return true;
1027 }
1028 /**
1029  * @brief Clear limiter timer resource.
1030  */
ClearLimiterTimerResource()1031 void FormTimerMgr::ClearLimiterTimerResource()
1032 {
1033     HILOG_INFO("%{public}s start", __func__);
1034     if (limiterTimerId_ != 0L) {
1035         HILOG_INFO("%{public}s clear limiter timer start", __func__);
1036         MiscServices::TimeServiceClient::GetInstance()->StopTimer(limiterTimerId_);
1037         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(limiterTimerId_);
1038         HILOG_INFO("%{public}s clear limiter timer end", __func__);
1039         limiterTimerId_ = 0L;
1040     }
1041     if (currentLimiterWantAgent_ != nullptr) {
1042         WantAgentHelper::Cancel(currentLimiterWantAgent_);
1043         currentLimiterWantAgent_ = nullptr;
1044     }
1045     HILOG_INFO("%{public}s end", __func__);
1046 }
1047 
1048 /**
1049  * @brief Get WantAgent.
1050  * @return Returns WantAgent.
1051  */
GetLimiterWantAgent()1052 std::shared_ptr<WantAgent> FormTimerMgr::GetLimiterWantAgent()
1053 {
1054     std::shared_ptr<Want> want = std::make_shared<Want>();
1055     ElementName element("", "", "");
1056     want->SetElement(element);
1057     want->SetAction(Constants::ACTION_UPDATEATTIMER);
1058     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_RESET_LIMIT);
1059 
1060     std::vector<std::shared_ptr<AAFwk::Want>> wants;
1061     wants.emplace_back(want);
1062     WantAgentInfo wantAgentInfo(REQUEST_LIMITER_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1063         WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
1064     return IN_PROCESS_CALL(WantAgentHelper::GetWantAgent(wantAgentInfo));
1065 }
1066 
1067 /**
1068  * @brief Update dynamic refresh task alarm.
1069  * @return Returns true on success, false on failure.
1070  */
UpdateDynamicAlarm()1071 bool FormTimerMgr::UpdateDynamicAlarm()
1072 {
1073     HILOG_INFO("%{public}s start", __func__);
1074     std::lock_guard<std::recursive_mutex> lock(dynamicMutex_);
1075     if (dynamicRefreshTasks_.empty()) {
1076         ClearDynamicResource();
1077         dynamicWakeUpTime_ = INT64_MAX;
1078         return true;
1079     }
1080 
1081     if (!IsNeedUpdate()) {
1082         HILOG_ERROR("%{public}s failed, no need to  UpdateDynamicAlarm.", __func__);
1083         return true;
1084     }
1085 
1086     auto firstTask = dynamicRefreshTasks_.begin();
1087     auto timerOption = std::make_shared<FormTimerOption>();
1088     timerOption->SetType(((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
1089      | ((unsigned int)(timerOption->TIMER_TYPE_WAKEUP)));
1090     timerOption->SetRepeat(false);
1091     timerOption->SetInterval(0);
1092     std::shared_ptr<WantAgent> wantAgent = GetDynamicWantAgent(dynamicWakeUpTime_, firstTask->userId);
1093     if (!wantAgent) {
1094         HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
1095         return false;
1096     }
1097     timerOption->SetWantAgent(wantAgent);
1098 
1099     if (currentDynamicWantAgent_ != nullptr) {
1100         ClearDynamicResource();
1101     }
1102     currentDynamicWantAgent_ = wantAgent;
1103 
1104     dynamicAlarmTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
1105     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(dynamicAlarmTimerId_,
1106         static_cast<uint64_t>(dynamicWakeUpTime_));
1107     if (!bRet) {
1108         HILOG_ERROR("%{public}s failed, init dynamic timer task error", __func__);
1109     }
1110     HILOG_INFO("%{public}s end, dynamicWakeUpTime_ : %{public}" PRId64 ".", __func__, dynamicWakeUpTime_);
1111     return true;
1112 }
1113 
IsNeedUpdate()1114 bool FormTimerMgr::IsNeedUpdate()
1115 {
1116     auto firstTask = dynamicRefreshTasks_.begin();
1117     if (dynamicWakeUpTime_ != firstTask->settedTime) {
1118         dynamicWakeUpTime_ = firstTask->settedTime;
1119         return true;
1120     }
1121     if (dynamicWakeUpTime_ == firstTask->settedTime &&
1122         GetBootTimeMs() - Constants::ABS_REFRESH_MS > dynamicWakeUpTime_) {
1123         HILOG_WARN("The dynamicWakeUpTime_ is invalid, dynamicWakeUpTime_ is less than currentTime, remove it.");
1124         firstTask = dynamicRefreshTasks_.erase(dynamicRefreshTasks_.begin());
1125         if (firstTask == dynamicRefreshTasks_.end()) {
1126             return false;
1127         }
1128         dynamicWakeUpTime_ = firstTask->settedTime;
1129         return true;
1130     }
1131     return false;
1132 }
1133 
1134 /**
1135  * @brief Get WantAgent.
1136  * @param nextTime The next update time.
1137  * @return Returns WantAgent.
1138  */
GetDynamicWantAgent(int64_t nextTime,int32_t userId)1139 std::shared_ptr<WantAgent> FormTimerMgr::GetDynamicWantAgent(int64_t nextTime, int32_t userId)
1140 {
1141     std::shared_ptr<Want> want = std::make_shared<Want>();
1142     ElementName element("", "", "");
1143     want->SetElement(element);
1144     want->SetAction(Constants::ACTION_UPDATEATTIMER);
1145     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_DYNAMIC_UPDATE);
1146     int nextTimeRight = static_cast<int>(nextTime);
1147     int nextTimLeft = static_cast<int>(nextTime >> SHIFT_BIT_LENGTH);
1148 
1149     want->SetParam(Constants::KEY_WAKEUP_TIME_LEFT, nextTimLeft);
1150     want->SetParam(Constants::KEY_WAKEUP_TIME_RIGHT, nextTimeRight);
1151     std::vector<std::shared_ptr<AAFwk::Want>> wants;
1152     wants.emplace_back(want);
1153     WantAgentInfo wantAgentInfo(REQUEST_DYNAMIC_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1154         WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
1155     return IN_PROCESS_CALL(WantAgentHelper::GetWantAgent(wantAgentInfo, userId));
1156 }
1157 
1158 /**
1159  * @brief Clear dynamic refresh resource.
1160  */
ClearDynamicResource()1161 void FormTimerMgr::ClearDynamicResource()
1162 {
1163     HILOG_INFO("%{public}s start", __func__);
1164     if (dynamicAlarmTimerId_ != 0L) {
1165         HILOG_INFO("%{public}s clear dynamic timer start", __func__);
1166         MiscServices::TimeServiceClient::GetInstance()->StopTimer(dynamicAlarmTimerId_);
1167         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(dynamicAlarmTimerId_);
1168         HILOG_INFO("%{public}s clear dynamic timer end", __func__);
1169         dynamicAlarmTimerId_ = 0L;
1170     }
1171 
1172     if (currentDynamicWantAgent_ != nullptr) {
1173         WantAgentHelper::Cancel(currentDynamicWantAgent_);
1174         currentDynamicWantAgent_ = nullptr;
1175     }
1176     HILOG_INFO("%{public}s end", __func__);
1177 }
1178 /**
1179  * @brief Find next at timer item.
1180  * @param nowTime Update time.
1181  * @param updateAtItem Next at timer item.
1182  * @return Returns true on success, false on failure.
1183  */
FindNextAtTimerItem(long nowTime,UpdateAtItem & updateAtItem)1184 bool FormTimerMgr::FindNextAtTimerItem(long nowTime, UpdateAtItem &updateAtItem)
1185 {
1186     HILOG_INFO("%{public}s start", __func__);
1187     std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
1188     if (updateAtTimerTasks_.empty()) {
1189         HILOG_WARN("%{public}s, updateAtTimerTasks_ is empty", __func__);
1190         return false;
1191     }
1192 
1193     std::list<UpdateAtItem>::iterator itItem;
1194     for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
1195         if (itItem->updateAtTime > nowTime) {
1196             updateAtItem = *itItem;
1197             break;
1198         }
1199     }
1200 
1201     if (itItem == updateAtTimerTasks_.end()) {
1202         updateAtItem = updateAtTimerTasks_.front();
1203     }
1204     HILOG_INFO("%{public}s end", __func__);
1205     return true;
1206 }
1207 
1208 /**
1209  * @brief Ensure init interval timer resource.
1210  */
EnsureInitIntervalTimer()1211 void FormTimerMgr::EnsureInitIntervalTimer()
1212 {
1213     HILOG_INFO("%{public}s, init base timer task", __func__);
1214     if (intervalTimer_ != nullptr) {
1215         return;
1216     }
1217 
1218     intervalTimer_ = std::make_shared<Utils::Timer>("interval timer");
1219     auto timeCallback = []() { FormTimerMgr::GetInstance().OnIntervalTimeOut(); };
1220     intervalTimer_->Register(timeCallback, Constants::MIN_PERIOD / timeSpeed_);
1221     intervalTimer_->Setup();
1222 
1223     HILOG_INFO("%{public}s end", __func__);
1224 }
1225 /**
1226  * @brief Clear interval timer resource.
1227  */
ClearIntervalTimer()1228 void FormTimerMgr::ClearIntervalTimer()
1229 {
1230     HILOG_INFO("%{public}s start", __func__);
1231     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
1232     if (intervalTimer_ != nullptr) {
1233         intervalTimer_->Shutdown();
1234         intervalTimer_.reset();
1235     }
1236     HILOG_INFO("%{public}s end", __func__);
1237 }
1238 /**
1239  * @brief Creat thread pool for timer task.
1240  */
1241 
CreatTaskThreadExecutor()1242 void FormTimerMgr::CreatTaskThreadExecutor()
1243 {
1244     HILOG_INFO("%{public}s start", __func__);
1245     if (taskExecutor_ == nullptr) {
1246         taskExecutor_ = std::make_unique<ThreadPool>("timer task thread");
1247         taskExecutor_->Start(Constants::WORK_POOL_SIZE);
1248     }
1249     HILOG_INFO("%{public}s end", __func__);
1250     return;
1251 }
1252 
1253 /**
1254  * @brief Execute Form timer task.
1255  * @param timerTask Form timer task.
1256  */
ExecTimerTask(const FormTimer & timerTask)1257 void FormTimerMgr::ExecTimerTask(const FormTimer &timerTask)
1258 {
1259     HILOG_INFO("%{public}s start", __func__);
1260     CreatTaskThreadExecutor();
1261     if (taskExecutor_ != nullptr) {
1262         HILOG_INFO("%{public}s run", __func__);
1263         AAFwk::Want want;
1264         if (timerTask.isCountTimer) {
1265             want.SetParam(Constants::KEY_IS_TIMER, true);
1266         }
1267         if (timerTask.isCountTimer || timerTask.isUpdateAt) {
1268             want.SetParam(Constants::KEY_TIMER_REFRESH, true);
1269         }
1270         // multi user
1271         if (IsActiveUser(timerTask.userId)) {
1272             HILOG_INFO("timerTask.userId is current user");
1273             want.SetParam(Constants::PARAM_FORM_USER_ID, timerTask.userId);
1274         }
1275         HILOG_INFO("%{public}s, userId:%{public}d", __func__, timerTask.userId);
1276         auto task = [id = timerTask.formId, want]() {
1277             FormProviderMgr::GetInstance().RefreshForm(id, want, false);
1278         };
1279         taskExecutor_->AddTask(task);
1280     }
1281     HILOG_INFO("%{public}s end", __func__);
1282 }
1283 
1284 /**
1285  * @brief Init.
1286  */
Init()1287 void FormTimerMgr::Init()
1288 {
1289     HILOG_INFO("%{public}s start", __func__);
1290     timerReceiver_ = nullptr;
1291     EventFwk::MatchingSkills matchingSkills;
1292     matchingSkills.AddEvent(Constants::ACTION_UPDATEATTIMER);
1293     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
1294     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED);
1295 #ifdef FORM_EVENT_FOR_TEST
1296     matchingSkills.AddEvent(FMS_TIME_SPEED);
1297 #endif
1298     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
1299     timerReceiver_ = std::make_shared<TimerReceiver>(subscribeInfo);
1300     EventFwk::CommonEventManager::SubscribeCommonEvent(timerReceiver_);
1301 
1302     intervalTimer_ = nullptr;
1303     updateAtTimerId_ = 0L;
1304     dynamicAlarmTimerId_ = 0L;
1305     limiterTimerId_ = 0L;
1306     taskExecutor_ = nullptr;
1307 
1308     HILOG_INFO("%{public}s end", __func__);
1309 }
1310 
1311 /**
1312  * @brief Receiver Constructor.
1313  * @param subscriberInfo Subscriber info.
1314  */
TimerReceiver(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)1315 FormTimerMgr::TimerReceiver::TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
1316     : EventFwk::CommonEventSubscriber(subscriberInfo)
1317 {}
1318 /**
1319  * @brief Receive common event.
1320  * @param eventData Common event data.
1321  */
OnReceiveEvent(const EventFwk::CommonEventData & eventData)1322 void FormTimerMgr::TimerReceiver::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
1323 {
1324     AAFwk::Want want = eventData.GetWant();
1325     std::string action = want.GetAction();
1326 
1327     HILOG_INFO("%{public}s, action:%{public}s.", __func__, action.c_str());
1328 
1329     if (action == FMS_TIME_SPEED) {
1330         // Time speed must between 1 and 1000.
1331         auto timeSpeed = std::clamp(eventData.GetCode(), Constants::MIN_TIME_SPEED, Constants::MAX_TIME_SPEED);
1332         FormTimerMgr::GetInstance().SetTimeSpeed(timeSpeed);
1333     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED
1334         || action == EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED) {
1335         FormTimerMgr::GetInstance().HandleSystemTimeChanged();
1336     } else if (action == Constants::ACTION_UPDATEATTIMER) {
1337         int type = want.GetIntParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_STATIC_UPDATE);
1338         if (type == Constants::TYPE_RESET_LIMIT) {
1339             FormTimerMgr::GetInstance().HandleResetLimiter();
1340         } else if (type == Constants::TYPE_STATIC_UPDATE) {
1341             long updateTime = want.GetLongParam(Constants::KEY_WAKEUP_TIME, -1);
1342             if (updateTime < 0) {
1343                 HILOG_ERROR("%{public}s failed, invalid updateTime:%{public}ld.", __func__, updateTime);
1344                 return;
1345             }
1346             FormTimerMgr::GetInstance().OnUpdateAtTrigger(updateTime);
1347         } else if (type == Constants::TYPE_DYNAMIC_UPDATE) {
1348             int updateTimeLeft = want.GetIntParam(Constants::KEY_WAKEUP_TIME_LEFT, -1);
1349             int updateTimeRight = want.GetIntParam(Constants::KEY_WAKEUP_TIME_RIGHT, -1);
1350             int64_t updateTime = static_cast<int64_t>(updateTimeLeft);
1351             updateTime = updateTime << SHIFT_BIT_LENGTH;
1352             updateTime |= updateTimeRight;
1353             if (updateTime <= 0) {
1354                 HILOG_ERROR("%{public}s failed, invalid updateTime:%{public}" PRId64 "", __func__, updateTime);
1355                 return;
1356             }
1357             FormTimerMgr::GetInstance().OnDynamicTimeTrigger(updateTime);
1358         } else {
1359             HILOG_ERROR("%{public}s failed, invalid type when action is update at timer.", __func__);
1360         }
1361     } else {
1362         HILOG_ERROR("%{public}s failed, invalid action.", __func__);
1363     }
1364 }
1365 /**
1366  * @brief check if user is active or not.
1367  *
1368  * @param userId User ID.
1369  * @return true:active, false:inactive
1370  */
IsActiveUser(int32_t userId)1371 bool FormTimerMgr::IsActiveUser(int32_t userId)
1372 {
1373     std::vector<int32_t> activeList;
1374     auto errCode = DelayedSingleton<OsAccountManagerWrapper>::GetInstance()->QueryActiveOsAccountIds(activeList);
1375     auto iter = std::find(activeList.begin(), activeList.end(), userId);
1376     if (iter != activeList.end() && errCode == ERR_OK) {
1377         return true;
1378     }
1379     return false;
1380 }
1381 }  // namespace AppExecFwk
1382 }  // namespace OHOS
1383