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