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