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