• 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     auto timeSinceEpoch = std::chrono::steady_clock::now().time_since_epoch();
342     int64_t timeInSec = std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
343     int64_t refreshTime = timeInSec + nextGapTime * Constants::MS_PER_SECOND / timeSpeed_;
344     HILOG_INFO("%{public}s currentTime:%{public}s refreshTime:%{public}s", __func__,
345         std::to_string(timeInSec).c_str(), std::to_string(refreshTime).c_str());
346     bool isExist = false;
347     std::lock_guard<std::recursive_mutex> lock(dynamicMutex_);
348     for (auto &refreshItem : dynamicRefreshTasks_) {
349         if ((refreshItem.formId == formId) && (refreshItem.userId == userId)) {
350             refreshItem.settedTime = refreshTime;
351             isExist = true;
352             break;
353         }
354     }
355     if (!isExist) {
356         DynamicRefreshItem theItem;
357         theItem.formId = formId;
358         theItem.settedTime = refreshTime;
359         theItem.userId = userId;
360         dynamicRefreshTasks_.emplace_back(theItem);
361     }
362     std::sort(dynamicRefreshTasks_.begin(), dynamicRefreshTasks_.end(), CompareDynamicRefreshItem);
363     if (!UpdateDynamicAlarm()) {
364         HILOG_ERROR("%{public}s, failed to UpdateDynamicAlarm", __func__);
365         return false;
366     }
367     if (!UpdateLimiterAlarm()) {
368         HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
369         return false;
370     }
371     refreshLimiter_.AddItem(formId);
372     SetEnableFlag(formId, false);
373 
374     return true;
375 }
376 
SetEnableFlag(int64_t formId,bool flag)377 void FormTimerMgr::SetEnableFlag(int64_t formId, bool flag)
378 {
379     // try interval list
380     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
381     auto iter = intervalTimerTasks_.find(formId);
382     if (iter != intervalTimerTasks_.end()) {
383         iter->second.isEnable = flag;
384         HILOG_INFO("%{public}s, formId:%{public}" PRId64 ", isEnable:%{public}d", __func__, formId, flag);
385         return;
386     }
387 }
388 
389 /**
390  * @brief Get refresh count.
391  * @param formId The Id of the form.
392  * @return Returns refresh count.
393  */
GetRefreshCount(int64_t formId) const394 int FormTimerMgr::GetRefreshCount(int64_t formId) const
395 {
396     return refreshLimiter_.GetRefreshCount(formId);
397 }
398 /**
399  * @brief Mark remind.
400  * @param formId The Id of the form.
401  * @return true or false.
402  */
MarkRemind(int64_t formId)403 void FormTimerMgr::MarkRemind(int64_t formId)
404 {
405     refreshLimiter_.MarkRemind(formId);
406 }
407 /**
408  * @brief Add update at timer.
409  * @param task Update time task.
410  * @return Returns true on success, false on failure.
411  */
AddUpdateAtTimer(const FormTimer & task)412 bool FormTimerMgr::AddUpdateAtTimer(const FormTimer &task)
413 {
414     HILOG_INFO("%{public}s start", __func__);
415     {
416         std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
417         for (const auto &updateAtTimer : updateAtTimerTasks_) {
418             if (updateAtTimer.refreshTask.formId == task.formId) {
419                 HILOG_WARN("%{public}s, already exist formTimer, formId:%{public}" PRId64 " task",
420                     __func__, task.formId);
421                 return true;
422             }
423         }
424     }
425     UpdateAtItem atItem;
426     atItem.refreshTask = task;
427     atItem.updateAtTime = task.hour * Constants::MIN_PER_HOUR + task.min;
428     AddUpdateAtItem(atItem);
429     if (!UpdateLimiterAlarm()) {
430         HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
431         return false;
432     }
433 
434     if (!UpdateAtTimerAlarm()) {
435         HILOG_ERROR("%{public}s, failed to update at timer alarm.", __func__);
436         return false;
437     }
438 
439     return refreshLimiter_.AddItem(task.formId);
440 }
441 /**
442  * @brief Add update interval timer task.
443  * @param task Update interval timer task.
444  * @return Returns true on success, false on failure.
445  */
AddIntervalTimer(const FormTimer & task)446 bool FormTimerMgr::AddIntervalTimer(const FormTimer &task)
447 {
448     HILOG_INFO("%{public}s start", __func__);
449     {
450         std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
451         EnsureInitIntervalTimer();
452         if (intervalTimerTasks_.find(task.formId) != intervalTimerTasks_.end()) {
453             HILOG_WARN("%{public}s, already exist formTimer, formId:%{public}" PRId64 " task", __func__, task.formId);
454             return true;
455         }
456         intervalTimerTasks_.emplace(task.formId, task);
457     }
458     if (!UpdateLimiterAlarm()) {
459         HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
460         return false;
461     }
462     return refreshLimiter_.AddItem(task.formId);
463 }
464 /**
465  * @brief Add update at timer item.
466  * @param task Update at timer item.
467  */
AddUpdateAtItem(const UpdateAtItem & atItem)468 void FormTimerMgr::AddUpdateAtItem(const UpdateAtItem &atItem)
469 {
470     std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
471     if (updateAtTimerTasks_.empty()) {
472         updateAtTimerTasks_.emplace_back(atItem);
473         return;
474     }
475 
476     UpdateAtItem firstItem = updateAtTimerTasks_.front();
477     if (atItem.updateAtTime < firstItem.updateAtTime) {
478         updateAtTimerTasks_.emplace_front(atItem);
479         return;
480     }
481 
482     bool isInsert = false;
483     std::list<UpdateAtItem>::iterator itItem;
484     for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
485         if (atItem.updateAtTime < itItem->updateAtTime) {
486             updateAtTimerTasks_.insert(itItem, atItem);
487             isInsert = true;
488             break;
489         }
490     }
491 
492     if (!isInsert) {
493         updateAtTimerTasks_.emplace_back(atItem);
494     }
495 }
496 /**
497  * @brief Handle system time changed.
498  * @return Returns true on success, false on failure.
499  */
HandleSystemTimeChanged()500 bool FormTimerMgr::HandleSystemTimeChanged()
501 {
502     HILOG_INFO("%{public}s start", __func__);
503     std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
504     if (!updateAtTimerTasks_.empty()) {
505         atTimerWakeUpTime_ = LONG_MAX;
506         UpdateAtTimerAlarm();
507     }
508     UpdateLimiterAlarm();
509     HILOG_INFO("%{public}s end", __func__);
510     return true;
511 }
512 /**
513  * @brief Reset form limiter.
514  * @return Returns true on success, false on failure.
515  */
HandleResetLimiter()516 bool FormTimerMgr::HandleResetLimiter()
517 {
518     HILOG_INFO("%{public}s start", __func__);
519 
520     std::vector<FormTimer> remindTasks;
521     bool bGetTasks = GetRemindTasks(remindTasks);
522     if (bGetTasks) {
523         HILOG_INFO("%{public}s failed, remind when reset limiter", __func__);
524         for (auto &task : remindTasks) {
525             ExecTimerTask(task);
526         }
527     }
528 
529     HILOG_INFO("%{public}s end", __func__);
530     return true;
531 }
532 /**
533  * @brief Update at time trigger.
534  * @param updateTime Update time.
535  * @return Returns true on success, false on failure.
536  */
OnUpdateAtTrigger(long updateTime)537 bool FormTimerMgr::OnUpdateAtTrigger(long updateTime)
538 {
539     HILOG_INFO("%{public}s start, updateTime:%{public}ld", __func__, updateTime);
540     std::vector<UpdateAtItem> updateList;
541     {
542         std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
543         std::list<UpdateAtItem>::iterator itItem;
544         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
545             if (itItem->updateAtTime == updateTime && itItem->refreshTask.isEnable) {
546                 updateList.emplace_back(*itItem);
547             }
548         }
549     }
550 
551     if (!UpdateAtTimerAlarm()) {
552         HILOG_ERROR("%{public}s, failed to update at timer alarm.", __func__);
553         return false;
554     }
555 
556     if (!updateList.empty()) {
557         HILOG_INFO("%{public}s, update at timer triggered, trigger time: %{public}ld", __func__, updateTime);
558         for (auto &item : updateList) {
559             ExecTimerTask(item.refreshTask);
560         }
561     }
562 
563     HILOG_INFO("%{public}s end", __func__);
564     return true;
565 }
566 /**
567  * @brief Dynamic time trigger.
568  * @param updateTime Update time.
569  * @return Returns true on success, false on failure.
570  */
OnDynamicTimeTrigger(int64_t updateTime)571 bool FormTimerMgr::OnDynamicTimeTrigger(int64_t updateTime)
572 {
573     HILOG_INFO("%{public}s start, updateTime:%{public}" PRId64 "", __func__, updateTime);
574     std::vector<FormTimer> updateList;
575     {
576         std::lock_guard<std::recursive_mutex> lock(dynamicMutex_);
577         auto timeSinceEpoch = std::chrono::steady_clock::now().time_since_epoch();
578         auto timeInSec = std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
579         int64_t markedTime = timeInSec + Constants::ABS_REFRESH_MS;
580         std::vector<DynamicRefreshItem>::iterator itItem;
581         for (itItem = dynamicRefreshTasks_.begin(); itItem != dynamicRefreshTasks_.end();) {
582             if (itItem->settedTime <= updateTime || itItem->settedTime <= markedTime) {
583                 if (refreshLimiter_.IsEnableRefresh(itItem->formId)) {
584                     FormTimer timerTask(itItem->formId, true, itItem->userId);
585                     updateList.emplace_back(timerTask);
586                 }
587                 SetIntervalEnableFlag(itItem->formId, true);
588                 itItem = dynamicRefreshTasks_.erase(itItem);
589             } else {
590                 itItem++;
591             }
592         }
593         std::sort(dynamicRefreshTasks_.begin(), dynamicRefreshTasks_.end(),  CompareDynamicRefreshItem);
594     }
595 
596     if (!UpdateDynamicAlarm()) {
597         HILOG_ERROR("%{public}s, failed to update dynamic alarm.", __func__);
598         return false;
599     }
600 
601     if (!updateList.empty()) {
602         HILOG_INFO("%{public}s triggered, trigger time: %{public}" PRId64 "", __func__, updateTime);
603         for (auto &task : updateList) {
604             ExecTimerTask(task);
605         }
606     }
607 
608     HILOG_INFO("%{public}s end", __func__);
609     return true;
610 }
611 /**
612  * @brief Get remind tasks.
613  * @param remindTasks Remind tasks.
614  * @return Returns true on success, false on failure.
615  */
GetRemindTasks(std::vector<FormTimer> & remindTasks)616 bool FormTimerMgr::GetRemindTasks(std::vector<FormTimer> &remindTasks)
617 {
618     HILOG_INFO("%{public}s start", __func__);
619     std::vector<int64_t> remindList = refreshLimiter_.GetRemindListAndResetLimit();
620     for (int64_t id : remindList) {
621         FormTimer formTimer(id, false);
622         remindTasks.emplace_back(formTimer);
623     }
624 
625     if (!UpdateLimiterAlarm()) {
626         HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
627         return false;
628     }
629 
630     if (remindTasks.size() > 0) {
631         HILOG_INFO("%{public}s end", __func__);
632         return true;
633     } else {
634         HILOG_INFO("%{public}s end, remindTasks is empty", __func__);
635         return false;
636     }
637 }
638 /**
639  * @brief Set enableFlag for interval timer task.
640  * @param formId The Id of the form.
641  * @param flag Enable flag.
642  */
SetIntervalEnableFlag(int64_t formId,bool flag)643 void FormTimerMgr::SetIntervalEnableFlag(int64_t formId, bool flag)
644 {
645     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
646     // try interval list
647     auto refreshTask = intervalTimerTasks_.find(formId);
648     if (refreshTask != intervalTimerTasks_.end()) {
649         refreshTask->second.isEnable = flag;
650         HILOG_INFO("%{public}s, formId:%{public}" PRId64 ", isEnable:%{public}d", __func__, formId, flag);
651         return;
652     }
653 }
654 /**
655  * @brief Get interval timer task.
656  * @param formId The Id of the form.
657  * @return Returns true on success, false on failure.
658  */
GetIntervalTimer(int64_t formId,FormTimer & formTimer)659 bool FormTimerMgr::GetIntervalTimer(int64_t formId, FormTimer &formTimer)
660 {
661     HILOG_INFO("%{public}s start", __func__);
662     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
663     auto intervalTask = intervalTimerTasks_.find(formId);
664     if (intervalTask == intervalTimerTasks_.end()) {
665         HILOG_INFO("%{public}s, interval timer not find", __func__);
666         return false;
667     }
668     formTimer = intervalTask->second;
669     HILOG_INFO("%{public}s, get interval timer successfully", __func__);
670     return true;
671 }
672 /**
673  * @brief Get update at timer.
674  * @param formId The Id of the form.
675  * @return Returns true on success, false on failure.
676  */
GetUpdateAtTimer(int64_t formId,UpdateAtItem & updateAtItem)677 bool FormTimerMgr::GetUpdateAtTimer(int64_t formId, UpdateAtItem &updateAtItem)
678 {
679     HILOG_INFO("%{public}s start", __func__);
680     {
681         std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
682         std::list<UpdateAtItem>::iterator itItem;
683         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
684             if (itItem->refreshTask.formId == formId) {
685                 updateAtItem.refreshTask = itItem->refreshTask;
686                 updateAtItem.updateAtTime = itItem->updateAtTime;
687                 HILOG_INFO("%{public}s, get update at timer successfully", __func__);
688                 return true;
689             }
690         }
691     }
692     HILOG_INFO("%{public}s, update at timer not find", __func__);
693     return false;
694 }
695 /**
696  * @brief Get dynamic refresh item.
697  * @param formId The Id of the form.
698  * @return Returns true on success, false on failure.
699  */
GetDynamicItem(int64_t formId,DynamicRefreshItem & dynamicItem)700 bool FormTimerMgr::GetDynamicItem(int64_t formId, DynamicRefreshItem &dynamicItem)
701 {
702     HILOG_INFO("%{public}s start", __func__);
703     std::lock_guard<std::recursive_mutex> lock(dynamicMutex_);
704     std::vector<DynamicRefreshItem>::iterator itItem;
705     for (itItem = dynamicRefreshTasks_.begin(); itItem != dynamicRefreshTasks_.end();) {
706         if (itItem->formId == formId) {
707             dynamicItem.formId = itItem->formId;
708             dynamicItem.settedTime = itItem->settedTime;
709             dynamicItem.userId = itItem->userId;
710             HILOG_INFO("%{public}s, get dynamic item successfully", __func__);
711             return true;
712         }
713     }
714     HILOG_INFO("%{public}s, dynamic item not find", __func__);
715     return false;
716 }
717 /**
718  * @brief Set time speed.
719  * @param timeSpeed The time speed.
720  */
SetTimeSpeed(int32_t timeSpeed)721 void FormTimerMgr::SetTimeSpeed(int32_t timeSpeed)
722 {
723     HILOG_INFO("%{public}s set time speed to:%{public}d", __func__, timeSpeed);
724     timeSpeed_ = timeSpeed;
725     HandleResetLimiter();
726     ClearIntervalTimer();
727 }
728 /**
729  * @brief Delete interval timer task.
730  * @param formId The Id of the form.
731  * @return Returns true on success, false on failure.
732  */
DeleteIntervalTimer(int64_t formId)733 bool FormTimerMgr::DeleteIntervalTimer(int64_t formId)
734 {
735     HILOG_INFO("%{public}s start", __func__);
736     bool isExist = false;
737     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
738     auto intervalTask = intervalTimerTasks_.find(formId);
739     if (intervalTask != intervalTimerTasks_.end()) {
740         intervalTimerTasks_.erase(intervalTask);
741         isExist = true;
742     }
743 
744     if (intervalTimerTasks_.empty()) {
745         ClearIntervalTimer();
746     }
747     HILOG_INFO("%{public}s end", __func__);
748     return isExist;
749 }
750 /**
751  * @brief Delete update at timer.
752  * @param formId The Id of the form.
753  * @return Returns true on success, false on failure.
754  */
DeleteUpdateAtTimer(int64_t formId)755 bool FormTimerMgr::DeleteUpdateAtTimer(int64_t formId)
756 {
757     HILOG_INFO("%{public}s start", __func__);
758     {
759         std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
760         std::list<UpdateAtItem>::iterator itItem;
761         for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
762             if (itItem->refreshTask.formId == formId) {
763                 updateAtTimerTasks_.erase(itItem);
764                 break;
765             }
766         }
767     }
768 
769     if (!UpdateAtTimerAlarm()) {
770         HILOG_ERROR("%{public}s, failed to update at timer alarm.", __func__);
771         return false;
772     }
773     HILOG_INFO("%{public}s end", __func__);
774     return true;
775 }
776 /**
777  * @brief Delete dynamic refresh item.
778  * @param formId The Id of the form.
779  */
DeleteDynamicItem(int64_t formId)780 bool FormTimerMgr::DeleteDynamicItem(int64_t formId)
781 {
782     HILOG_INFO("%{public}s start", __func__);
783     std::lock_guard<std::recursive_mutex> lock(dynamicMutex_);
784     std::vector<DynamicRefreshItem>::iterator itItem;
785     for (itItem = dynamicRefreshTasks_.begin(); itItem != dynamicRefreshTasks_.end();) {
786         if (itItem->formId == formId) {
787             itItem = dynamicRefreshTasks_.erase(itItem);
788             if (itItem != dynamicRefreshTasks_.end()) {
789                 SetIntervalEnableFlag(itItem->formId, true);
790             }
791             break;
792         }
793         ++itItem;
794     }
795     std::sort(dynamicRefreshTasks_.begin(), dynamicRefreshTasks_.end(),  CompareDynamicRefreshItem);
796 
797     if (!UpdateDynamicAlarm()) {
798         HILOG_ERROR("%{public}s, failed to UpdateDynamicAlarm", __func__);
799         return false;
800     }
801     HILOG_INFO("%{public}s end", __func__);
802     return true;
803 }
804 /**
805 * @brief interval timer task timeout.
806 */
OnIntervalTimeOut()807 void FormTimerMgr::OnIntervalTimeOut()
808 {
809     HILOG_INFO("%{public}s start", __func__);
810     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
811     std::vector<FormTimer> updateList;
812     int64_t currentTime = FormUtil::GetCurrentNanosecond() / Constants::TIME_1000000;
813     for (auto &intervalPair : intervalTimerTasks_) {
814         FormTimer &intervalTask = intervalPair.second;
815         HILOG_INFO("intervalTask form id is %{public}" PRId64 ", period is %{public}" PRId64 "",
816             intervalTask.formId, intervalTask.period);
817         if (((currentTime - intervalTask.refreshTime) >= intervalTask.period ||
818             std::abs((currentTime - intervalTask.refreshTime) - intervalTask.period) < Constants::ABS_TIME) &&
819             intervalTask.isEnable && refreshLimiter_.IsEnableRefresh(intervalTask.formId)) {
820             intervalTask.refreshTime = currentTime;
821             updateList.emplace_back(intervalTask);
822         }
823     }
824 
825     if (!updateList.empty()) {
826         for (auto &task : updateList) {
827             ExecTimerTask(task);
828         }
829     }
830     HILOG_INFO("%{public}s end", __func__);
831 }
832 
833 /**
834  * @brief Update at timer task alarm.
835  * @return Returns true on success, false on failure.
836  */
UpdateAtTimerAlarm()837 bool FormTimerMgr::UpdateAtTimerAlarm()
838 {
839     HILOG_INFO("%{public}s start", __func__);
840     struct tm tmAtTime = {0};
841     auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
842     struct tm* ptm = localtime_r(&tt, &tmAtTime);
843     if (ptm == nullptr) {
844         HILOG_ERROR("%{public}s failed, localtime error", __func__);
845         return false;
846     }
847 
848     long nowAtTime = tmAtTime.tm_hour * Constants::MIN_PER_HOUR + tmAtTime.tm_min;
849     int64_t currentTime = FormUtil::GetCurrentMillisecond();
850     UpdateAtItem foundItem;
851     bool found = FindNextAtTimerItem(nowAtTime, foundItem);
852     if (!found) {
853         {
854             std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
855             if (!updateAtTimerTasks_.empty()) {
856                 HILOG_WARN("%{public}s, updateAtTimerTasks_ is not empty", __func__);
857                 return true;
858             }
859         }
860         ClearUpdateAtTimerResource();
861         atTimerWakeUpTime_ = LONG_MAX;
862         HILOG_INFO("%{public}s, no update at task in system now.", __func__);
863         return true;
864     }
865 
866     long nextWakeUpTime = foundItem.updateAtTime;
867     tmAtTime.tm_sec = 0;
868     tmAtTime.tm_hour = foundItem.refreshTask.hour;
869     tmAtTime.tm_min = foundItem.refreshTask.min;
870     int64_t selectTime = FormUtil::GetMillisecondFromTm(tmAtTime);
871     if (selectTime < currentTime) {
872         selectTime += Constants::MS_PER_DAY;
873         nextWakeUpTime += (Constants::HOUR_PER_DAY * Constants::MIN_PER_HOUR);
874     }
875     HILOG_INFO("%{public}s, selectTime: %{public}" PRId64 ", currentTime: %{public}" PRId64 ".",
876         __func__, selectTime, currentTime);
877 
878     if (nextWakeUpTime == atTimerWakeUpTime_) {
879         HILOG_WARN("%{public}s end, wakeUpTime not change, no need update alarm.", __func__);
880         return true;
881     }
882 
883     auto timerOption = std::make_shared<FormTimerOption>();
884     int32_t flag = ((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
885       | ((unsigned int)(timerOption->TIMER_TYPE_WAKEUP)) | ((unsigned int)(timerOption->TIMER_TYPE_EXACT));
886     HILOG_DEBUG("timerOption type is %{public}d", flag);
887     timerOption->SetType(flag);
888     timerOption->SetRepeat(false);
889     timerOption->SetInterval(0);
890     int32_t userId = foundItem.refreshTask.userId;
891     std::shared_ptr<WantAgent> wantAgent = GetUpdateAtWantAgent(foundItem.updateAtTime, userId);
892     if (wantAgent == nullptr) {
893         HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
894         return false;
895     }
896     timerOption->SetWantAgent(wantAgent);
897 
898     atTimerWakeUpTime_ = nextWakeUpTime;
899     if (currentUpdateAtWantAgent_ != nullptr) {
900         ClearUpdateAtTimerResource();
901     }
902     auto timeSinceEpoch = GetBootTimeNs().time_since_epoch();
903     int64_t timeInSec = std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
904     HILOG_DEBUG("timeInSec: %{public}" PRId64 ".", timeInSec);
905     int64_t nextTime = timeInSec + (selectTime - currentTime);
906     HILOG_INFO("%{public}s, nextTime: %{public}" PRId64 ".", __func__, nextTime);
907 
908     currentUpdateAtWantAgent_ = wantAgent;
909     updateAtTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
910     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(updateAtTimerId_,
911         static_cast<uint64_t>(nextTime));
912     if (!bRet) {
913         HILOG_ERROR("%{public}s failed, init update at timer task error", __func__);
914         return false;
915     }
916 
917     HILOG_INFO("%{public}s end", __func__);
918     return true;
919 }
920 
GetBootTimeNs()921 std::chrono::steady_clock::time_point FormTimerMgr::GetBootTimeNs()
922 {
923     int64_t timeNow = -1;
924     struct timespec tv {};
925     if (clock_gettime(CLOCK_BOOTTIME, &tv) < 0) {
926         HILOG_WARN("Get bootTime by clock_gettime failed, use std::chrono::steady_clock");
927         return std::chrono::steady_clock::now();
928     }
929     timeNow = tv.tv_sec * NANO_TO_SECOND + tv.tv_nsec;
930     std::chrono::steady_clock::time_point tp_epoch ((std::chrono::nanoseconds(timeNow)));
931     return tp_epoch;
932 }
933 
934 /**
935  * @brief Get WantAgent.
936  * @param updateAtTime The next update time.
937  * @return Returns WantAgent.
938  */
GetUpdateAtWantAgent(long updateAtTime,int32_t userId)939 std::shared_ptr<WantAgent> FormTimerMgr::GetUpdateAtWantAgent(long updateAtTime, int32_t userId)
940 {
941     std::shared_ptr<Want> want = std::make_shared<Want>();
942     ElementName element("", "", "");
943     want->SetElement(element);
944     want->SetAction(Constants::ACTION_UPDATEATTIMER);
945     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_STATIC_UPDATE);
946     want->SetParam(Constants::KEY_WAKEUP_TIME, updateAtTime);
947 
948     std::vector<std::shared_ptr<AAFwk::Want>> wants;
949     wants.emplace_back(want);
950     WantAgentInfo wantAgentInfo(REQUEST_UPDATE_AT_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
951         WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
952     return IN_PROCESS_CALL(WantAgentHelper::GetWantAgent(wantAgentInfo, userId));
953 }
954 
955 /**
956  * @brief Clear update at timer resource.
957  */
ClearUpdateAtTimerResource()958 void FormTimerMgr::ClearUpdateAtTimerResource()
959 {
960     HILOG_INFO("%{public}s start", __func__);
961     if (updateAtTimerId_ != 0L) {
962         HILOG_INFO("%{public}s clear update at timer start", __func__);
963         MiscServices::TimeServiceClient::GetInstance()->StopTimer(updateAtTimerId_);
964         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(updateAtTimerId_);
965         HILOG_INFO("%{public}s clear update at timer end", __func__);
966         updateAtTimerId_ = 0L;
967     }
968     if (currentUpdateAtWantAgent_ != nullptr) {
969         WantAgentHelper::Cancel(currentUpdateAtWantAgent_);
970         currentUpdateAtWantAgent_ = nullptr;
971     }
972     HILOG_INFO("%{public}s end", __func__);
973 }
974 
975 /**
976  * @brief Update limiter task alarm.
977  * @return Returns true on success, false on failure.
978  */
UpdateLimiterAlarm()979 bool FormTimerMgr::UpdateLimiterAlarm()
980 {
981     HILOG_INFO("%{public}s start", __func__);
982     if (limiterTimerId_ != 0L) {
983         HILOG_INFO("%{public}s clear limiter timer start", __func__);
984         MiscServices::TimeServiceClient::GetInstance()->StopTimer(limiterTimerId_);
985         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(limiterTimerId_);
986         HILOG_INFO("%{public}s clear limiter timer end", __func__);
987         limiterTimerId_ = 0L;
988     }
989 
990     // make limiter wakeup time
991     struct tm tmAtTime = {0};
992     auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
993     struct tm* ptm = localtime_r(&tt, &tmAtTime);
994     if (ptm == nullptr) {
995         HILOG_ERROR("%{public}s failed, localtime error", __func__);
996         return false;
997     }
998     tmAtTime.tm_sec = Constants::MAX_SECOND; // max value can be 61
999     tmAtTime.tm_hour = Constants::MAX_HOUR;
1000     tmAtTime.tm_min = Constants::MAX_MINUTE;
1001     int64_t limiterWakeUpTime = FormUtil::GetMillisecondFromTm(tmAtTime);
1002 
1003     auto timerOption = std::make_shared<FormTimerOption>();
1004     timerOption->SetType(timerOption->TIMER_TYPE_WAKEUP);
1005     timerOption->SetRepeat(false);
1006     timerOption->SetInterval(0);
1007     std::shared_ptr<WantAgent> wantAgent = GetLimiterWantAgent();
1008     if (!wantAgent) {
1009         HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
1010         return false;
1011     }
1012     timerOption->SetWantAgent(wantAgent);
1013 
1014     if (currentLimiterWantAgent_ != nullptr) {
1015         ClearLimiterTimerResource();
1016     }
1017     currentLimiterWantAgent_ = wantAgent;
1018 
1019     limiterTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
1020     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(limiterTimerId_,
1021         static_cast<uint64_t>(limiterWakeUpTime));
1022     if (!bRet) {
1023         HILOG_ERROR("%{public}s failed, init limiter timer task error", __func__);
1024         return false;
1025     }
1026     HILOG_INFO("%{public}s end", __func__);
1027     return true;
1028 }
1029 /**
1030  * @brief Clear limiter timer resource.
1031  */
ClearLimiterTimerResource()1032 void FormTimerMgr::ClearLimiterTimerResource()
1033 {
1034     HILOG_INFO("%{public}s start", __func__);
1035     if (limiterTimerId_ != 0L) {
1036         HILOG_INFO("%{public}s clear limiter timer start", __func__);
1037         MiscServices::TimeServiceClient::GetInstance()->StopTimer(limiterTimerId_);
1038         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(limiterTimerId_);
1039         HILOG_INFO("%{public}s clear limiter timer end", __func__);
1040         limiterTimerId_ = 0L;
1041     }
1042     if (currentLimiterWantAgent_ != nullptr) {
1043         WantAgentHelper::Cancel(currentLimiterWantAgent_);
1044         currentLimiterWantAgent_ = nullptr;
1045     }
1046     HILOG_INFO("%{public}s end", __func__);
1047 }
1048 
1049 /**
1050  * @brief Get WantAgent.
1051  * @return Returns WantAgent.
1052  */
GetLimiterWantAgent()1053 std::shared_ptr<WantAgent> FormTimerMgr::GetLimiterWantAgent()
1054 {
1055     std::shared_ptr<Want> want = std::make_shared<Want>();
1056     ElementName element("", "", "");
1057     want->SetElement(element);
1058     want->SetAction(Constants::ACTION_UPDATEATTIMER);
1059     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_RESET_LIMIT);
1060 
1061     std::vector<std::shared_ptr<AAFwk::Want>> wants;
1062     wants.emplace_back(want);
1063     WantAgentInfo wantAgentInfo(REQUEST_LIMITER_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1064         WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
1065     return IN_PROCESS_CALL(WantAgentHelper::GetWantAgent(wantAgentInfo));
1066 }
1067 
1068 /**
1069  * @brief Update dynamic refresh task alarm.
1070  * @return Returns true on success, false on failure.
1071  */
UpdateDynamicAlarm()1072 bool FormTimerMgr::UpdateDynamicAlarm()
1073 {
1074     HILOG_INFO("%{public}s start", __func__);
1075     std::lock_guard<std::recursive_mutex> lock(dynamicMutex_);
1076     if (dynamicRefreshTasks_.empty()) {
1077         ClearDynamicResource();
1078         dynamicWakeUpTime_ = INT64_MAX;
1079         return true;
1080     }
1081 
1082     bool needUpdate = false;
1083     DynamicRefreshItem firstTask = dynamicRefreshTasks_.at(0);
1084     if (dynamicWakeUpTime_ != firstTask.settedTime) {
1085         dynamicWakeUpTime_ = firstTask.settedTime;
1086         needUpdate = true;
1087     }
1088 
1089     if (!needUpdate) {
1090         HILOG_ERROR("%{public}s failed, no need to  UpdateDynamicAlarm.", __func__);
1091         return true;
1092     }
1093 
1094     auto timerOption = std::make_shared<FormTimerOption>();
1095     timerOption->SetType(((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
1096      | ((unsigned int)(timerOption->TIMER_TYPE_WAKEUP)));
1097     timerOption->SetRepeat(false);
1098     timerOption->SetInterval(0);
1099     std::shared_ptr<WantAgent> wantAgent = GetDynamicWantAgent(dynamicWakeUpTime_, firstTask.userId);
1100     if (!wantAgent) {
1101         HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
1102         return false;
1103     }
1104     timerOption->SetWantAgent(wantAgent);
1105 
1106     if (currentDynamicWantAgent_ != nullptr) {
1107         ClearDynamicResource();
1108     }
1109     currentDynamicWantAgent_ = wantAgent;
1110 
1111     dynamicAlarmTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
1112     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(dynamicAlarmTimerId_,
1113         static_cast<uint64_t>(dynamicWakeUpTime_));
1114     if (!bRet) {
1115         HILOG_ERROR("%{public}s failed, init dynamic timer task error", __func__);
1116     }
1117     HILOG_INFO("%{public}s end, dynamicWakeUpTime_ : %{public}" PRId64 ".", __func__, dynamicWakeUpTime_);
1118     return true;
1119 }
1120 /**
1121  * @brief Get WantAgent.
1122  * @param nextTime The next update time.
1123  * @return Returns WantAgent.
1124  */
GetDynamicWantAgent(int64_t nextTime,int32_t userId)1125 std::shared_ptr<WantAgent> FormTimerMgr::GetDynamicWantAgent(int64_t nextTime, int32_t userId)
1126 {
1127     std::shared_ptr<Want> want = std::make_shared<Want>();
1128     ElementName element("", "", "");
1129     want->SetElement(element);
1130     want->SetAction(Constants::ACTION_UPDATEATTIMER);
1131     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_DYNAMIC_UPDATE);
1132     int nextTimeRight = static_cast<int>(nextTime);
1133     int nextTimLeft = static_cast<int>(nextTime >> SHIFT_BIT_LENGTH);
1134 
1135     want->SetParam(Constants::KEY_WAKEUP_TIME_LEFT, nextTimLeft);
1136     want->SetParam(Constants::KEY_WAKEUP_TIME_RIGHT, nextTimeRight);
1137     std::vector<std::shared_ptr<AAFwk::Want>> wants;
1138     wants.emplace_back(want);
1139     WantAgentInfo wantAgentInfo(REQUEST_DYNAMIC_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1140         WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
1141     return IN_PROCESS_CALL(WantAgentHelper::GetWantAgent(wantAgentInfo, userId));
1142 }
1143 
1144 /**
1145  * @brief Clear dynamic refresh resource.
1146  */
ClearDynamicResource()1147 void FormTimerMgr::ClearDynamicResource()
1148 {
1149     HILOG_INFO("%{public}s start", __func__);
1150     if (dynamicAlarmTimerId_ != 0L) {
1151         HILOG_INFO("%{public}s clear dynamic timer start", __func__);
1152         MiscServices::TimeServiceClient::GetInstance()->StopTimer(dynamicAlarmTimerId_);
1153         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(dynamicAlarmTimerId_);
1154         HILOG_INFO("%{public}s clear dynamic timer end", __func__);
1155         dynamicAlarmTimerId_ = 0L;
1156     }
1157 
1158     if (currentDynamicWantAgent_ != nullptr) {
1159         WantAgentHelper::Cancel(currentDynamicWantAgent_);
1160         currentDynamicWantAgent_ = nullptr;
1161     }
1162     HILOG_INFO("%{public}s end", __func__);
1163 }
1164 /**
1165  * @brief Find next at timer item.
1166  * @param nowTime Update time.
1167  * @param updateAtItem Next at timer item.
1168  * @return Returns true on success, false on failure.
1169  */
FindNextAtTimerItem(long nowTime,UpdateAtItem & updateAtItem)1170 bool FormTimerMgr::FindNextAtTimerItem(long nowTime, UpdateAtItem &updateAtItem)
1171 {
1172     HILOG_INFO("%{public}s start", __func__);
1173     std::lock_guard<std::recursive_mutex> lock(updateAtMutex_);
1174     if (updateAtTimerTasks_.empty()) {
1175         HILOG_WARN("%{public}s, updateAtTimerTasks_ is empty", __func__);
1176         return false;
1177     }
1178 
1179     std::list<UpdateAtItem>::iterator itItem;
1180     for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
1181         if (itItem->updateAtTime > nowTime) {
1182             updateAtItem = *itItem;
1183             break;
1184         }
1185     }
1186 
1187     if (itItem == updateAtTimerTasks_.end()) {
1188         updateAtItem = updateAtTimerTasks_.front();
1189     }
1190     HILOG_INFO("%{public}s end", __func__);
1191     return true;
1192 }
1193 
1194 /**
1195  * @brief Ensure init interval timer resource.
1196  */
EnsureInitIntervalTimer()1197 void FormTimerMgr::EnsureInitIntervalTimer()
1198 {
1199     HILOG_INFO("%{public}s, init base timer task", __func__);
1200     if (intervalTimer_ != nullptr) {
1201         return;
1202     }
1203 
1204     intervalTimer_ = std::make_shared<Utils::Timer>("interval timer");
1205     auto timeCallback = []() { FormTimerMgr::GetInstance().OnIntervalTimeOut(); };
1206     intervalTimer_->Register(timeCallback, Constants::MIN_PERIOD / timeSpeed_);
1207     intervalTimer_->Setup();
1208 
1209     HILOG_INFO("%{public}s end", __func__);
1210 }
1211 /**
1212  * @brief Clear interval timer resource.
1213  */
ClearIntervalTimer()1214 void FormTimerMgr::ClearIntervalTimer()
1215 {
1216     HILOG_INFO("%{public}s start", __func__);
1217     std::lock_guard<std::recursive_mutex> lock(intervalMutex_);
1218     if (intervalTimer_ != nullptr) {
1219         intervalTimer_->Shutdown();
1220         intervalTimer_.reset();
1221     }
1222     HILOG_INFO("%{public}s end", __func__);
1223 }
1224 /**
1225  * @brief Creat thread pool for timer task.
1226  */
1227 
CreatTaskThreadExecutor()1228 void FormTimerMgr::CreatTaskThreadExecutor()
1229 {
1230     HILOG_INFO("%{public}s start", __func__);
1231     if (taskExecutor_ == nullptr) {
1232         taskExecutor_ = std::make_unique<ThreadPool>("timer task thread");
1233         taskExecutor_->Start(Constants::WORK_POOL_SIZE);
1234     }
1235     HILOG_INFO("%{public}s end", __func__);
1236     return;
1237 }
1238 
1239 /**
1240  * @brief Execute Form timer task.
1241  * @param timerTask Form timer task.
1242  */
ExecTimerTask(const FormTimer & timerTask)1243 void FormTimerMgr::ExecTimerTask(const FormTimer &timerTask)
1244 {
1245     HILOG_INFO("%{public}s start", __func__);
1246     CreatTaskThreadExecutor();
1247     if (taskExecutor_ != nullptr) {
1248         HILOG_INFO("%{public}s run", __func__);
1249         AAFwk::Want want;
1250         if (timerTask.isCountTimer) {
1251             want.SetParam(Constants::KEY_IS_TIMER, true);
1252         }
1253         if (timerTask.isCountTimer || timerTask.isUpdateAt) {
1254             want.SetParam(Constants::KEY_TIMER_REFRESH, true);
1255         }
1256         // multi user
1257         if (IsActiveUser(timerTask.userId)) {
1258             HILOG_INFO("timerTask.userId is current user");
1259             want.SetParam(Constants::PARAM_FORM_USER_ID, timerTask.userId);
1260         }
1261         HILOG_INFO("%{public}s, userId:%{public}d", __func__, timerTask.userId);
1262         auto task = [id = timerTask.formId, want]() {
1263             FormProviderMgr::GetInstance().RefreshForm(id, want, false);
1264         };
1265         taskExecutor_->AddTask(task);
1266     }
1267     HILOG_INFO("%{public}s end", __func__);
1268 }
1269 
1270 /**
1271  * @brief Init.
1272  */
Init()1273 void FormTimerMgr::Init()
1274 {
1275     HILOG_INFO("%{public}s start", __func__);
1276     timerReceiver_ = nullptr;
1277     EventFwk::MatchingSkills matchingSkills;
1278     matchingSkills.AddEvent(Constants::ACTION_UPDATEATTIMER);
1279     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
1280     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED);
1281 #ifdef FORM_EVENT_FOR_TEST
1282     matchingSkills.AddEvent(FMS_TIME_SPEED);
1283 #endif
1284     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
1285     timerReceiver_ = std::make_shared<TimerReceiver>(subscribeInfo);
1286     EventFwk::CommonEventManager::SubscribeCommonEvent(timerReceiver_);
1287 
1288     intervalTimer_ = nullptr;
1289     updateAtTimerId_ = 0L;
1290     dynamicAlarmTimerId_ = 0L;
1291     limiterTimerId_ = 0L;
1292     taskExecutor_ = nullptr;
1293 
1294     HILOG_INFO("%{public}s end", __func__);
1295 }
1296 
1297 /**
1298  * @brief Receiver Constructor.
1299  * @param subscriberInfo Subscriber info.
1300  */
TimerReceiver(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)1301 FormTimerMgr::TimerReceiver::TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
1302     : EventFwk::CommonEventSubscriber(subscriberInfo)
1303 {}
1304 /**
1305  * @brief Receive common event.
1306  * @param eventData Common event data.
1307  */
OnReceiveEvent(const EventFwk::CommonEventData & eventData)1308 void FormTimerMgr::TimerReceiver::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
1309 {
1310     AAFwk::Want want = eventData.GetWant();
1311     std::string action = want.GetAction();
1312 
1313     HILOG_INFO("%{public}s, action:%{public}s.", __func__, action.c_str());
1314 
1315     if (action == FMS_TIME_SPEED) {
1316         // Time speed must between 1 and 1000.
1317         auto timeSpeed = std::clamp(eventData.GetCode(), Constants::MIN_TIME_SPEED, Constants::MAX_TIME_SPEED);
1318         FormTimerMgr::GetInstance().SetTimeSpeed(timeSpeed);
1319     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED
1320         || action == EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED) {
1321         FormTimerMgr::GetInstance().HandleSystemTimeChanged();
1322     } else if (action == Constants::ACTION_UPDATEATTIMER) {
1323         int type = want.GetIntParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_STATIC_UPDATE);
1324         if (type == Constants::TYPE_RESET_LIMIT) {
1325             FormTimerMgr::GetInstance().HandleResetLimiter();
1326         } else if (type == Constants::TYPE_STATIC_UPDATE) {
1327             long updateTime = want.GetLongParam(Constants::KEY_WAKEUP_TIME, -1);
1328             if (updateTime < 0) {
1329                 HILOG_ERROR("%{public}s failed, invalid updateTime:%{public}ld.", __func__, updateTime);
1330                 return;
1331             }
1332             FormTimerMgr::GetInstance().OnUpdateAtTrigger(updateTime);
1333         } else if (type == Constants::TYPE_DYNAMIC_UPDATE) {
1334             int updateTimeLeft = want.GetIntParam(Constants::KEY_WAKEUP_TIME_LEFT, -1);
1335             int updateTimeRight = want.GetIntParam(Constants::KEY_WAKEUP_TIME_RIGHT, -1);
1336             int64_t updateTime = static_cast<int64_t>(updateTimeLeft);
1337             updateTime = updateTime << SHIFT_BIT_LENGTH;
1338             updateTime |= updateTimeRight;
1339             if (updateTime <= 0) {
1340                 HILOG_ERROR("%{public}s failed, invalid updateTime:%{public}" PRId64 "", __func__, updateTime);
1341                 return;
1342             }
1343             FormTimerMgr::GetInstance().OnDynamicTimeTrigger(updateTime);
1344         } else {
1345             HILOG_ERROR("%{public}s failed, invalid type when action is update at timer.", __func__);
1346         }
1347     } else {
1348         HILOG_ERROR("%{public}s failed, invalid action.", __func__);
1349     }
1350 }
1351 /**
1352  * @brief check if user is active or not.
1353  *
1354  * @param userId User ID.
1355  * @return true:active, false:inactive
1356  */
IsActiveUser(int32_t userId)1357 bool FormTimerMgr::IsActiveUser(int32_t userId)
1358 {
1359     std::vector<int32_t> activeList;
1360     auto errCode = DelayedSingleton<OsAccountManagerWrapper>::GetInstance()->QueryActiveOsAccountIds(activeList);
1361     auto iter = std::find(activeList.begin(), activeList.end(), userId);
1362     if (iter != activeList.end() && errCode == ERR_OK) {
1363         return true;
1364     }
1365     return false;
1366 }
1367 }  // namespace AppExecFwk
1368 }  // namespace OHOS
1369