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