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