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