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