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_INFO("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         limiterTimerId_ = 0L;
1014     }
1015 
1016     // make limiter wakeup time
1017     struct tm tmAtTime = {0};
1018     auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
1019     struct tm* ptm = localtime_r(&tt, &tmAtTime);
1020     if (ptm == nullptr) {
1021         HILOG_ERROR("localtime error");
1022         return false;
1023     }
1024     tmAtTime.tm_sec = Constants::MAX_SECOND; // max value can be 61
1025     tmAtTime.tm_hour = Constants::MAX_HOUR;
1026     tmAtTime.tm_min = Constants::MAX_MINUTE;
1027     int64_t limiterWakeUpTime = FormUtil::GetMillisecondFromTm(tmAtTime);
1028 
1029     if (!CreateLimiterTimer()) {
1030         return false;
1031     }
1032     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(limiterTimerId_,
1033         static_cast<uint64_t>(limiterWakeUpTime));
1034     if (!bRet) {
1035         HILOG_ERROR("init limiter timer task error");
1036         return false;
1037     }
1038     HILOG_INFO("end");
1039     return true;
1040 }
1041 /**
1042  * @brief Clear limiter timer resource.
1043  */
ClearLimiterTimerResource()1044 void FormTimerMgr::ClearLimiterTimerResource()
1045 {
1046     HILOG_INFO("start");
1047     if (limiterTimerId_ != 0L) {
1048         HILOG_INFO("clear limiter timer start");
1049         MiscServices::TimeServiceClient::GetInstance()->DestroyTimerAsync(limiterTimerId_);
1050         HILOG_INFO("clear limiter timer end");
1051         limiterTimerId_ = 0L;
1052     }
1053 
1054     if (currentLimiterWantAgent_ != nullptr) {
1055         IN_PROCESS_CALL(WantAgentHelper::Cancel(currentLimiterWantAgent_));
1056         currentLimiterWantAgent_ = nullptr;
1057     }
1058     HILOG_INFO("end");
1059 }
1060 
CreateLimiterTimer()1061 bool FormTimerMgr::CreateLimiterTimer()
1062 {
1063     HILOG_INFO("start");
1064     auto timerOption = std::make_shared<FormTimerOption>();
1065     timerOption->SetType(timerOption->TIMER_TYPE_EXACT);
1066     timerOption->SetRepeat(false);
1067     timerOption->SetInterval(0);
1068     std::shared_ptr<WantAgent> wantAgent = GetLimiterWantAgent();
1069     if (!wantAgent) {
1070         HILOG_ERROR("create wantAgent failed");
1071         return false;
1072     }
1073     timerOption->SetWantAgent(wantAgent);
1074     if (limiterTimerId_ == 0L) {
1075         limiterTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
1076         currentLimiterWantAgent_ = wantAgent;
1077     }
1078     HILOG_INFO("end");
1079     return true;
1080 }
1081 
1082 /**
1083  * @brief Get WantAgent.
1084  * @return Returns WantAgent.
1085  */
GetLimiterWantAgent()1086 std::shared_ptr<WantAgent> FormTimerMgr::GetLimiterWantAgent()
1087 {
1088     std::shared_ptr<Want> want = std::make_shared<Want>();
1089     ElementName element("", "", "");
1090     want->SetElement(element);
1091     want->SetAction(Constants::ACTION_UPDATEATTIMER);
1092     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_RESET_LIMIT);
1093 
1094     std::vector<std::shared_ptr<AAFwk::Want>> wants;
1095     wants.emplace_back(want);
1096     WantAgentInfo wantAgentInfo(REQUEST_LIMITER_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1097         WantAgentConstant::Flags::CANCEL_PRESENT_FLAG, wants, nullptr);
1098     return IN_PROCESS_CALL(WantAgentHelper::GetWantAgent(wantAgentInfo));
1099 }
1100 
1101 /**
1102  * @brief Update dynamic refresh task alarm.
1103  * @return Returns true on success, false on failure.
1104  */
UpdateDynamicAlarm()1105 bool FormTimerMgr::UpdateDynamicAlarm()
1106 {
1107     HILOG_INFO("start");
1108     std::lock_guard<std::mutex> lock(dynamicMutex_);
1109     if (dynamicRefreshTasks_.empty()) {
1110         ClearDynamicResource();
1111         dynamicWakeUpTime_ = INT64_MAX;
1112         return true;
1113     }
1114 
1115     if (!IsNeedUpdate()) {
1116         HILOG_ERROR("no need to  UpdateDynamicAlarm");
1117         return true;
1118     }
1119 
1120     auto firstTask = dynamicRefreshTasks_.begin();
1121     auto timerOption = std::make_shared<FormTimerOption>();
1122     timerOption->SetType(((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
1123      | ((unsigned int)(timerOption->TIMER_TYPE_EXACT)));
1124     timerOption->SetRepeat(false);
1125     timerOption->SetInterval(0);
1126     std::shared_ptr<WantAgent> wantAgent = GetDynamicWantAgent(dynamicWakeUpTime_, firstTask->userId);
1127     if (!wantAgent) {
1128         HILOG_ERROR("create wantAgent failed");
1129         return false;
1130     }
1131     timerOption->SetWantAgent(wantAgent);
1132 
1133     if (currentDynamicWantAgent_ != nullptr) {
1134         ClearDynamicResource();
1135     }
1136     currentDynamicWantAgent_ = wantAgent;
1137 
1138     dynamicAlarmTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
1139     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(dynamicAlarmTimerId_,
1140         static_cast<uint64_t>(dynamicWakeUpTime_));
1141     if (!bRet) {
1142         HILOG_ERROR("init dynamic timer task error");
1143     }
1144     HILOG_INFO("dynamicWakeUpTime_:%{public}" PRId64, dynamicWakeUpTime_);
1145     return true;
1146 }
1147 
IsNeedUpdate()1148 bool FormTimerMgr::IsNeedUpdate()
1149 {
1150     auto firstTask = dynamicRefreshTasks_.begin();
1151     if (dynamicWakeUpTime_ != firstTask->settedTime) {
1152         dynamicWakeUpTime_ = firstTask->settedTime;
1153         return true;
1154     }
1155     if (dynamicWakeUpTime_ == firstTask->settedTime &&
1156         GetBootTimeMs() - Constants::ABS_REFRESH_MS > dynamicWakeUpTime_) {
1157         HILOG_WARN("invalid dynamicWakeUpTime_ less than currentTime, remove it");
1158         firstTask = dynamicRefreshTasks_.erase(dynamicRefreshTasks_.begin());
1159         if (firstTask == dynamicRefreshTasks_.end()) {
1160             return false;
1161         }
1162         dynamicWakeUpTime_ = firstTask->settedTime;
1163         return true;
1164     }
1165     return false;
1166 }
1167 
1168 /**
1169  * @brief Get WantAgent.
1170  * @param nextTime The next update time.
1171  * @return Returns WantAgent.
1172  */
GetDynamicWantAgent(int64_t nextTime, int32_t userId)1173 std::shared_ptr<WantAgent> FormTimerMgr::GetDynamicWantAgent(int64_t nextTime, int32_t userId)
1174 {
1175     std::shared_ptr<Want> want = std::make_shared<Want>();
1176     ElementName element("", "", "");
1177     want->SetElement(element);
1178     want->SetAction(Constants::ACTION_UPDATEATTIMER);
1179     want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_DYNAMIC_UPDATE);
1180     int nextTimeRight = static_cast<int>(nextTime);
1181     int nextTimLeft = static_cast<int>(nextTime >> SHIFT_BIT_LENGTH);
1182 
1183     want->SetParam(Constants::KEY_WAKEUP_TIME_LEFT, nextTimLeft);
1184     want->SetParam(Constants::KEY_WAKEUP_TIME_RIGHT, nextTimeRight);
1185     std::vector<std::shared_ptr<AAFwk::Want>> wants;
1186     wants.emplace_back(want);
1187     WantAgentInfo wantAgentInfo(REQUEST_DYNAMIC_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1188         WantAgentConstant::Flags::CANCEL_PRESENT_FLAG, wants, nullptr);
1189     return IN_PROCESS_CALL(WantAgentHelper::GetWantAgent(wantAgentInfo, userId));
1190 }
1191 
1192 /**
1193  * @brief Clear dynamic refresh resource.
1194  */
ClearDynamicResource()1195 void FormTimerMgr::ClearDynamicResource()
1196 {
1197     HILOG_INFO("start");
1198     if (dynamicAlarmTimerId_ != 0L) {
1199         MiscServices::TimeServiceClient::GetInstance()->DestroyTimerAsync(dynamicAlarmTimerId_);
1200         HILOG_INFO("clear dynamic timer end");
1201         dynamicAlarmTimerId_ = 0L;
1202     }
1203 
1204     if (currentDynamicWantAgent_ != nullptr) {
1205         IN_PROCESS_CALL(WantAgentHelper::Cancel(currentDynamicWantAgent_));
1206         currentDynamicWantAgent_ = nullptr;
1207         HILOG_INFO("Cancel");
1208     }
1209 }
1210 /**
1211  * @brief Find next at timer item.
1212  * @param nowTime Update time.
1213  * @param updateAtItem Next at timer item.
1214  * @return Returns true on success, false on failure.
1215  */
FindNextAtTimerItem(long nowTime, UpdateAtItem &updateAtItem)1216 bool FormTimerMgr::FindNextAtTimerItem(long nowTime, UpdateAtItem &updateAtItem)
1217 {
1218     HILOG_INFO("start");
1219     std::lock_guard<std::mutex> lock(updateAtMutex_);
1220     if (updateAtTimerTasks_.empty()) {
1221         HILOG_WARN("empty updateAtTimerTasks_");
1222         return false;
1223     }
1224 
1225     std::list<UpdateAtItem>::iterator itItem;
1226     for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
1227         if (itItem->updateAtTime > nowTime) {
1228             updateAtItem = *itItem;
1229             break;
1230         }
1231     }
1232 
1233     if (itItem == updateAtTimerTasks_.end()) {
1234         updateAtItem = updateAtTimerTasks_.front();
1235     }
1236     HILOG_INFO("end");
1237     return true;
1238 }
1239 
1240 /**
1241  * @brief Ensure init interval timer resource.
1242  */
EnsureInitIntervalTimer()1243 void FormTimerMgr::EnsureInitIntervalTimer()
1244 {
1245     HILOG_INFO("init base timer task");
1246     if (intervalTimerId_ != 0L) {
1247         return;
1248     }
1249 
1250     HILOG_INFO("Create intervalTimer");
1251     // 1. Create Timer Option
1252     auto timerOption = std::make_shared<FormTimerOption>();
1253     int32_t flag = ((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
1254       | ((unsigned int)(timerOption->TIMER_TYPE_EXACT));
1255     timerOption->SetType(flag);
1256     timerOption->SetRepeat(true);
1257     int64_t interval = Constants::MIN_PERIOD / timeSpeed_;
1258     timerOption->SetInterval(interval);
1259     auto timeCallback = []() { FormTimerMgr::GetInstance().OnIntervalTimeOut(); };
1260     timerOption->SetCallbackInfo(timeCallback);
1261 
1262     // 2. Create Timer and get TimerId
1263     intervalTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
1264     int64_t timeInSec = GetBootTimeMs();
1265     HILOG_INFO("TimerId:%{public}" PRId64 ", timeInSec:%{public}" PRId64 ", interval:%{public}" PRId64,
1266         intervalTimerId_, timeInSec, interval);
1267 
1268     // 3. Start Timer
1269     int64_t startTime = timeInSec + interval;
1270     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(intervalTimerId_,
1271         static_cast<uint64_t>(startTime));
1272     if (!bRet) {
1273         HILOG_ERROR("init intervalTimer task error");
1274         InnerClearIntervalTimer();
1275     }
1276     HILOG_INFO("end");
1277 }
1278 
FormRefreshCountReport()1279 void FormTimerMgr::FormRefreshCountReport()
1280 {
1281     HILOG_INFO("init base Refresh count task");
1282     if (limiterTimerReportId_ != 0L) {
1283         return;
1284     }
1285     auto timerOption = std::make_shared<FormTimerOption>();
1286     int32_t flag = ((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
1287       | ((unsigned int)(timerOption->TIMER_TYPE_EXACT));
1288     timerOption->SetType(flag);
1289     timerOption->SetRepeat(true);
1290     int64_t interval = Constants::MS_PER_DAY / timeSpeed_;
1291     timerOption->SetInterval(interval);
1292     auto timeCallback = []() { FormRecordReport::GetInstance().HandleFormRefreshCount(); };
1293     timerOption->SetCallbackInfo(timeCallback);
1294     limiterTimerReportId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
1295     int64_t timeInSec = GetBootTimeMs();
1296     HILOG_INFO("TimerId:%{public}" PRId64 ", timeInSec:%{public}" PRId64 ", interval:%{public}" PRId64 ".",
1297         limiterTimerReportId_, timeInSec, interval);
1298     int64_t startTime = timeInSec + interval;
1299     bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(limiterTimerReportId_,
1300         static_cast<uint64_t>(startTime));
1301     if (!bRet) {
1302         HILOG_ERROR("init limiterTimerReport task error");
1303         InnerClearIntervalReportTimer();
1304     }
1305     HILOG_INFO("Create intervalTimer end");
1306 }
1307 /**
1308  * @brief Clear interval timer resource.
1309  */
ClearIntervalTimer()1310 void FormTimerMgr::ClearIntervalTimer()
1311 {
1312     HILOG_INFO("start");
1313     std::lock_guard<std::mutex> lock(intervalMutex_);
1314     InnerClearIntervalTimer();
1315     InnerClearIntervalReportTimer();
1316     HILOG_INFO("end");
1317 }
1318 
InnerClearIntervalTimer()1319 void FormTimerMgr::InnerClearIntervalTimer()
1320 {
1321     HILOG_INFO("start");
1322     if (intervalTimerId_ != 0L) {
1323         HILOG_INFO("Destroy intervalTimer");
1324         MiscServices::TimeServiceClient::GetInstance()->DestroyTimerAsync(intervalTimerId_);
1325         intervalTimerId_ = 0L;
1326     }
1327     HILOG_INFO("end");
1328 }
1329 
InnerClearIntervalReportTimer()1330 void FormTimerMgr::InnerClearIntervalReportTimer()
1331 {
1332     HILOG_INFO("start");
1333     if (limiterTimerReportId_ != 0L) {
1334         HILOG_INFO("Destroy interval Report Timerr");
1335         MiscServices::TimeServiceClient::GetInstance()->DestroyTimerAsync(limiterTimerReportId_);
1336         limiterTimerReportId_ = 0L;
1337     }
1338     HILOG_INFO("end");
1339 }
1340 
1341 #ifdef RES_SCHEDULE_ENABLE
SetTimerTaskNeeded(bool isTimerTaskNeeded)1342 void FormTimerMgr::SetTimerTaskNeeded(bool isTimerTaskNeeded)
1343 {
1344     HILOG_INFO("isTimerTaskNeeded_:%{public}s", isTimerTaskNeeded ? "true" : "false");
1345     if (!isTimerTaskNeeded_ && isTimerTaskNeeded) {
1346         TriggerAndClearNotExecTaskVec();
1347     }
1348     isTimerTaskNeeded_ = isTimerTaskNeeded;
1349 }
1350 
AddToNotExecTaskVec(const FormTimer &task)1351 void FormTimerMgr::AddToNotExecTaskVec(const FormTimer &task)
1352 {
1353     for (auto &item : notExecTaskVec_) {
1354         if (item.formId == task.formId && item.userId == task.userId) {
1355             item = task;
1356             return;
1357         }
1358     }
1359     notExecTaskVec_.emplace_back(task);
1360     HILOG_DEBUG("the task(formId:%{public}" PRId64 ", userId:%{public}d) is added to notExecTaskVec",
1361         task.formId, task.userId);
1362 }
1363 
TriggerAndClearNotExecTaskVec()1364 void FormTimerMgr::TriggerAndClearNotExecTaskVec()
1365 {
1366     for (auto &item : notExecTaskVec_) {
1367         ExecTimerTaskCore(item);
1368         HILOG_INFO("the task(formId:%{public}" PRId64 ", userId:%{public}d) is triggered when level is down",
1369             item.formId, item.userId);
1370     }
1371     notExecTaskVec_.clear();
1372 }
1373 
1374 /**
1375  * @brief Execute Form timer task.
1376  * @param timerTask Form timer task.
1377  */
ExecTimerTask(const FormTimer &timerTask)1378 void FormTimerMgr::ExecTimerTask(const FormTimer &timerTask)
1379 {
1380     if (!isTimerTaskNeeded_) {
1381         AddToNotExecTaskVec(timerTask);
1382         return;
1383     }
1384 
1385     ExecTimerTaskCore(timerTask);
1386 }
1387 
1388 /**
1389  * @brief Execute Form timer task.
1390  * @param timerTask Form timer task core.
1391  */
ExecTimerTaskCore(const FormTimer &timerTask)1392 void FormTimerMgr::ExecTimerTaskCore(const FormTimer &timerTask)
1393 #else
1394 /**
1395  * @brief Execute Form timer task.
1396  * @param timerTask Form timer task.
1397  */
1398 void FormTimerMgr::ExecTimerTask(const FormTimer &timerTask)
1399 #endif // RES_SCHEDULE_ENABLE
1400 {
1401     HILOG_INFO("start");
1402     AAFwk::Want want;
1403     if (timerTask.isCountTimer) {
1404         want.SetParam(Constants::KEY_IS_TIMER, true);
1405     }
1406     if (timerTask.isCountTimer || timerTask.isUpdateAt) {
1407         want.SetParam(Constants::KEY_TIMER_REFRESH, true);
1408     }
1409     // multi user
1410     if (IsActiveUser(timerTask.userId)) {
1411         HILOG_INFO("timerTask.userId is current user");
1412         want.SetParam(Constants::PARAM_FORM_USER_ID, timerTask.userId);
1413     }
1414     HILOG_INFO("userId:%{public}d", timerTask.userId);
1415     auto task = [id = timerTask.formId, want]() {
1416         FormProviderMgr::GetInstance().RefreshForm(id, want, false);
1417     };
1418     ffrt::submit(task);
1419     HILOG_INFO("end");
1420 }
1421 
RefreshWhenFormVisible(const int64_t &formId, const int32_t &userId)1422 void FormTimerMgr::RefreshWhenFormVisible(const int64_t &formId, const int32_t &userId)
1423 {
1424     FormTimer timerTask(formId, true, userId);
1425     ExecTimerTask(timerTask);
1426 }
1427 
1428 /**
1429  * @brief Init.
1430  */
Init()1431 void FormTimerMgr::Init()
1432 {
1433     HILOG_INFO("start");
1434     systemTimerEventReceiver_ = nullptr;
1435     EventFwk::MatchingSkills systemEventMatchingSkills;
1436     systemEventMatchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
1437     systemEventMatchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED);
1438 #ifdef FORM_EVENT_FOR_TEST
1439     systemEventMatchingSkills.AddEvent(FMS_TIME_SPEED);
1440 #endif
1441     EventFwk::CommonEventSubscribeInfo systemTimerEventSubInfo(systemEventMatchingSkills);
1442     systemTimerEventSubInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
1443     systemTimerEventReceiver_ = std::make_shared<TimerReceiver>(systemTimerEventSubInfo);
1444     EventFwk::CommonEventManager::SubscribeCommonEvent(systemTimerEventReceiver_);
1445 
1446     // Custom timer event need to set specified publisher uid
1447     customTimerEventReceiver_ = nullptr;
1448     EventFwk::MatchingSkills customEventMatchingSkills;
1449     customEventMatchingSkills.AddEvent(Constants::ACTION_UPDATEATTIMER);
1450     EventFwk::CommonEventSubscribeInfo customTimerEventSubInfo(customEventMatchingSkills);
1451     customTimerEventSubInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
1452     customTimerEventSubInfo.SetPublisherUid(FOUNDATION_UID);
1453     customTimerEventReceiver_ = std::make_shared<TimerReceiver>(customTimerEventSubInfo);
1454     EventFwk::CommonEventManager::SubscribeCommonEvent(customTimerEventReceiver_);
1455 
1456     intervalTimerId_ = 0L;
1457     updateAtTimerId_ = 0L;
1458     dynamicAlarmTimerId_ = 0L;
1459     limiterTimerId_ = 0L;
1460     limiterTimerReportId_ = 0L;
1461     FormRefreshCountReport();
1462     CreateLimiterTimer();
1463     HILOG_INFO("end");
1464 }
1465 
1466 /**
1467  * @brief Receiver Constructor.
1468  * @param subscriberInfo Subscriber info.
1469  */
TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)1470 FormTimerMgr::TimerReceiver::TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
1471     : EventFwk::CommonEventSubscriber(subscriberInfo)
1472 {}
1473 /**
1474  * @brief Receive common event.
1475  * @param eventData Common event data.
1476  */
OnReceiveEvent(const EventFwk::CommonEventData &eventData)1477 void FormTimerMgr::TimerReceiver::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
1478 {
1479     AAFwk::Want want = eventData.GetWant();
1480     std::string action = want.GetAction();
1481 
1482     HILOG_INFO("action:%{public}s", action.c_str());
1483 
1484     if (action == FMS_TIME_SPEED) {
1485         // Time speed must between 1 and 1000.
1486         auto timeSpeed = std::clamp(eventData.GetCode(), Constants::MIN_TIME_SPEED, Constants::MAX_TIME_SPEED);
1487         FormTimerMgr::GetInstance().SetTimeSpeed(timeSpeed);
1488     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED
1489         || action == EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED) {
1490         FormTimerMgr::GetInstance().HandleSystemTimeChanged();
1491     } else if (action == Constants::ACTION_UPDATEATTIMER) {
1492         int type = want.GetIntParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_STATIC_UPDATE);
1493         if (type == Constants::TYPE_RESET_LIMIT) {
1494             FormTimerMgr::GetInstance().HandleResetLimiter();
1495         } else if (type == Constants::TYPE_STATIC_UPDATE) {
1496             long updateTime = want.GetLongParam(Constants::KEY_WAKEUP_TIME, -1);
1497             if (updateTime < 0) {
1498                 HILOG_ERROR("invalid updateTime:%{public}ld", updateTime);
1499                 return;
1500             }
1501             FormTimerMgr::GetInstance().OnUpdateAtTrigger(updateTime);
1502         } else if (type == Constants::TYPE_DYNAMIC_UPDATE) {
1503             int updateTimeLeft = want.GetIntParam(Constants::KEY_WAKEUP_TIME_LEFT, -1);
1504             int updateTimeRight = want.GetIntParam(Constants::KEY_WAKEUP_TIME_RIGHT, -1);
1505             int64_t updateTime = static_cast<int64_t>(updateTimeLeft);
1506             updateTime = updateTime << SHIFT_BIT_LENGTH;
1507             updateTime |= updateTimeRight;
1508             if (updateTime <= 0) {
1509                 HILOG_ERROR("invalid updateTime:%{public}" PRId64 "", updateTime);
1510                 return;
1511             }
1512             FormTimerMgr::GetInstance().OnDynamicTimeTrigger(updateTime);
1513         } else {
1514             HILOG_ERROR("invalid type when action is update at timer");
1515         }
1516     } else {
1517         HILOG_ERROR("invalid action");
1518     }
1519 }
1520 /**
1521  * @brief check if user is active or not.
1522  *
1523  * @param userId User ID.
1524  * @return true:active, false:inactive
1525  */
IsActiveUser(int32_t userId)1526 bool FormTimerMgr::IsActiveUser(int32_t userId)
1527 {
1528     std::vector<int32_t> activeList;
1529     auto errCode = DelayedSingleton<OsAccountManagerWrapper>::GetInstance()->QueryActiveOsAccountIds(activeList);
1530     auto iter = std::find(activeList.begin(), activeList.end(), userId);
1531     if (iter != activeList.end() && errCode == ERR_OK) {
1532         return true;
1533     }
1534     return false;
1535 }
1536 }  // namespace AppExecFwk
1537 }  // namespace OHOS
1538