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