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