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 "ability_context.h"
21 #include "appexecfwk_errors.h"
22 #include "common_event_manager.h"
23 #include "common_event_support.h"
24 #include "context/context.h"
25 #include "form_constants.h"
26 #include "form_provider_mgr.h"
27 #include "form_refresh_limiter.h"
28 #include "form_timer_option.h"
29 #include "form_util.h"
30 #include "hilog_wrapper.h"
31 #include "os_account_manager.h"
32 #include "want.h"
33
34 namespace OHOS {
35 namespace AppExecFwk {
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 std::string FMS_TIME_SPEED = "fms.time_speed";
41
FormTimerMgr()42 FormTimerMgr::FormTimerMgr()
43 {
44 Init();
45 }
~FormTimerMgr()46 FormTimerMgr::~FormTimerMgr()
47 {
48 ClearIntervalTimer();
49 }
50 /**
51 * @brief Add form timer by timer task.
52 * @param task The form timer task.
53 * @return Returns true on success, false on failure.
54 */
AddFormTimer(const FormTimer & task)55 bool FormTimerMgr::AddFormTimer(const FormTimer &task)
56 {
57 HILOG_INFO("%{public}s formId:%{public}s userId:%{public}d", __func__,
58 std::to_string(task.formId).c_str(), task.userId);
59 if (task.isUpdateAt) {
60 if (task.hour >= Constants::MIN_TIME && task.hour <= Constants::MAX_HOUR &&
61 task.min >= Constants::MIN_TIME && task.min <= Constants::MAX_MINUTE) {
62 return AddUpdateAtTimer(task);
63 } else {
64 HILOG_ERROR("%{public}s failed, update at time is invalid", __func__);
65 return false;
66 }
67 } else {
68 if (task.period >= (Constants::MIN_PERIOD / timeSpeed_) && // Min period is 30 minutes
69 task.period <= (Constants::MAX_PERIOD / timeSpeed_) && // Max period is 1 week
70 task.period % (Constants::MIN_PERIOD / timeSpeed_) == 0) {
71 return AddIntervalTimer(task);
72 } else {
73 HILOG_ERROR("%{public}s failed, interval time is invalid", __func__);
74 return false;
75 }
76 }
77 }
78 /**
79 * @brief Add duration form timer.
80 * @param formId The Id of the form.
81 * @param updateDuration Update duration
82 * @param userId User ID.
83 * @return Returns true on success, false on failure.
84 */
AddFormTimer(const int64_t formId,const long updateDuration,const int32_t userId)85 bool FormTimerMgr::AddFormTimer(const int64_t formId, const long updateDuration, const int32_t userId)
86 {
87 auto duration = updateDuration / timeSpeed_;
88 HILOG_INFO("%{public}s formId:%{public}s duration:%{public}s", __func__,
89 std::to_string(formId).c_str(), std::to_string(duration).c_str());
90 FormTimer timerTask(formId, duration, userId);
91 return AddFormTimer(timerTask);
92 }
93 /**
94 * @brief Add scheduled form timer.
95 * @param formId The Id of the form.
96 * @param updateAtHour Hour.
97 * @param updateAtMin Min.
98 * @param userId User ID.
99 * @return Returns true on success, false on failure.
100 */
AddFormTimer(const int64_t formId,const long updateAtHour,const long updateAtMin,const int32_t userId)101 bool FormTimerMgr::AddFormTimer(const int64_t formId, const long updateAtHour,
102 const long updateAtMin, const int32_t userId)
103 {
104 HILOG_INFO("%{public}s formId:%{public}s time:%{public}s-%{public}s", __func__,
105 std::to_string(formId).c_str(), std::to_string(updateAtHour).c_str(), std::to_string(updateAtMin).c_str());
106 FormTimer timerTask(formId, updateAtHour, updateAtMin, userId);
107 return AddFormTimer(timerTask);
108 }
109 /**
110 * @brief Remove form timer by form id.
111 * @param formId The Id of the form.
112 * @return Returns true on success, false on failure.
113 */
RemoveFormTimer(const int64_t formId)114 bool FormTimerMgr::RemoveFormTimer(const int64_t formId)
115 {
116 HILOG_INFO("%{public}s, task: %{public}" PRId64 "", __func__, formId);
117
118 if (!DeleteIntervalTimer(formId)) {
119 if (!DeleteUpdateAtTimer(formId)) {
120 HILOG_ERROR("%{public}s, failed to DeleteUpdateAtTimer", __func__);
121 return false;
122 }
123 }
124
125 if (!DeleteDynamicItem(formId)) {
126 HILOG_ERROR("%{public}s, failed to DeleteDynamicItem", __func__);
127 return false;
128 }
129 refreshLimiter_.DeleteItem(formId);
130
131 return true;
132 }
133 /**
134 * @brief Update form timer.
135 * @param formId The Id of the form.
136 * @param type Timer type.
137 * @param timerCfg Timer config.
138 * @return Returns true on success, false on failure.
139 */
UpdateFormTimer(const int64_t formId,const UpdateType & type,const FormTimerCfg & timerCfg)140 bool FormTimerMgr::UpdateFormTimer(const int64_t formId, const UpdateType &type, const FormTimerCfg &timerCfg)
141 {
142 if (!timerCfg.enableUpdate) {
143 HILOG_WARN("%{public}s, enableUpdate is false", __func__);
144 return false;
145 }
146
147 switch (type) {
148 case UpdateType::TYPE_INTERVAL_CHANGE: {
149 return UpdateIntervalValue(formId, timerCfg);
150 }
151 case UpdateType::TYPE_ATTIME_CHANGE: {
152 return UpdateAtTimerValue(formId, timerCfg);
153 }
154 case UpdateType::TYPE_INTERVAL_TO_ATTIME: {
155 return IntervalToAtTimer(formId, timerCfg);
156 }
157 case UpdateType::TYPE_ATTIME_TO_INTERVAL: {
158 return AtTimerToIntervalTimer(formId, timerCfg);
159 }
160 default: {
161 HILOG_ERROR("%{public}s failed, invalid UpdateType", __func__);
162 return false;
163 }
164 }
165 }
166 /**
167 * @brief Update Interval timer task value.
168 * @param formId The Id of the form.
169 * @param timerCfg task value.
170 * @return Returns true on success, false on failure.
171 */
UpdateIntervalValue(const int64_t formId,const FormTimerCfg & timerCfg)172 bool FormTimerMgr::UpdateIntervalValue(const int64_t formId, const FormTimerCfg &timerCfg)
173 {
174 if (timerCfg.updateDuration < Constants::MIN_PERIOD || timerCfg.updateDuration > Constants::MAX_PERIOD
175 || (timerCfg.updateDuration % Constants::MIN_PERIOD) != 0) {
176 HILOG_ERROR("%{public}s failed, invalid param", __func__);
177 return false;
178 }
179
180 std::lock_guard<std::mutex> lock(intervalMutex_);
181 auto intervalTask = intervalTimerTasks_.find(formId);
182 if (intervalTask != intervalTimerTasks_.end()) {
183 intervalTask->second.period = timerCfg.updateDuration;
184 return true;
185 } else {
186 HILOG_ERROR("%{public}s failed, the interval timer is not exist", __func__);
187 return false;
188 }
189 }
190 /**
191 * @brief Update update at timer task value.
192 * @param formId The Id of the form.
193 * @param timerCfg task value.
194 * @return Returns true on success, false on failure.
195 */
UpdateAtTimerValue(const int64_t formId,const FormTimerCfg & timerCfg)196 bool FormTimerMgr::UpdateAtTimerValue(const int64_t formId, const FormTimerCfg &timerCfg)
197 {
198 if (timerCfg.updateAtHour < Constants::MIN_TIME || timerCfg.updateAtHour > Constants::MAX_HOUR
199 || timerCfg.updateAtMin < Constants::MIN_TIME || timerCfg.updateAtMin > Constants::MAX_MINUTE) {
200 HILOG_ERROR("%{public}s failed, time is invalid", __func__);
201 return false;
202 }
203 {
204 std::lock_guard<std::mutex> lock(updateAtMutex_);
205 std::list<UpdateAtItem>::iterator itItem;
206 UpdateAtItem changedItem;
207 for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
208 if (itItem->refreshTask.formId == formId) {
209 changedItem = *itItem;
210 updateAtTimerTasks_.erase(itItem);
211 break;
212 }
213 }
214
215 if (changedItem.refreshTask.formId == 0) {
216 HILOG_ERROR("%{public}s failed, the update at timer is not exist", __func__);
217 return false;
218 }
219 changedItem.refreshTask.hour = timerCfg.updateAtHour;
220 changedItem.refreshTask.min = timerCfg.updateAtMin;
221 changedItem.updateAtTime = changedItem.refreshTask.hour * Constants::MIN_PER_HOUR + changedItem.refreshTask.min;
222 AddUpdateAtItem(changedItem);
223 }
224
225 if (!UpdateAtTimerAlarm()) {
226 HILOG_ERROR("%{public}s, failed to update attimer alarm.", __func__);
227 return false;
228 }
229 return true;
230 }
231 /**
232 * @brief Interval timer task to update at timer task.
233 * @param formId The Id of the form.
234 * @param timerCfg task value.
235 * @return Returns true on success, false on failure.
236 */
IntervalToAtTimer(const int64_t formId,const FormTimerCfg & timerCfg)237 bool FormTimerMgr::IntervalToAtTimer(const int64_t formId, const FormTimerCfg &timerCfg)
238 {
239 if (timerCfg.updateAtHour < Constants::MIN_TIME || timerCfg.updateAtHour > Constants::MAX_HOUR
240 || timerCfg.updateAtMin < Constants::MIN_TIME || timerCfg.updateAtMin > Constants::MAX_MINUTE) {
241 HILOG_ERROR("%{public}s failed, time is invalid", __func__);
242 return false;
243 }
244
245 std::lock_guard<std::mutex> lock(intervalMutex_);
246 FormTimer timerTask;
247 auto intervalTask = intervalTimerTasks_.find(formId);
248 if (intervalTask != intervalTimerTasks_.end()) {
249 timerTask = intervalTask->second;
250 intervalTimerTasks_.erase(intervalTask);
251
252 timerTask.isUpdateAt = true;
253 timerTask.hour = timerCfg.updateAtHour;
254 timerTask.min = timerCfg.updateAtMin;
255 if (!AddUpdateAtTimer(timerTask)) {
256 HILOG_ERROR("%{public}s, failed to add update at timer", __func__);
257 return false;
258 }
259 return true;
260 } else {
261 HILOG_ERROR("%{public}s failed, the interval timer is not exist", __func__);
262 return false;
263 }
264 }
265 /**
266 * @brief Update at timer task to interval timer task.
267 * @param formId The Id of the form.
268 * @param timerCfg task value.
269 * @return Returns true on success, false on failure.
270 */
AtTimerToIntervalTimer(const int64_t formId,const FormTimerCfg & timerCfg)271 bool FormTimerMgr::AtTimerToIntervalTimer(const int64_t formId, const FormTimerCfg &timerCfg)
272 {
273 if (timerCfg.updateDuration < Constants::MIN_PERIOD || timerCfg.updateDuration > Constants::MAX_PERIOD
274 || (timerCfg.updateDuration % Constants::MIN_PERIOD) != 0) {
275 HILOG_ERROR("%{public}s failed, time is invalid", __func__);
276 return false;
277 }
278
279 UpdateAtItem targetItem;
280 {
281 std::lock_guard<std::mutex> lock(updateAtMutex_);
282 std::list<UpdateAtItem>::iterator itItem;
283 for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
284 if (itItem->refreshTask.formId == formId) {
285 targetItem = *itItem;
286 updateAtTimerTasks_.erase(itItem);
287 break;
288 }
289 }
290 }
291
292 if (!UpdateAtTimerAlarm()) {
293 HILOG_ERROR("%{public}s, failed to update attimer alarm.", __func__);
294 return false;
295 }
296
297 if (targetItem.refreshTask.formId == 0) {
298 HILOG_ERROR("%{public}s failed, the update at timer is not exist", __func__);
299 return false;
300 }
301 targetItem.refreshTask.isUpdateAt = false;
302 targetItem.refreshTask.period = timerCfg.updateDuration;
303 targetItem.refreshTask.refreshTime = INT64_MAX;
304 if (!AddIntervalTimer(targetItem.refreshTask)) {
305 HILOG_ERROR("%{public}s, failed to add interval timer", __func__);
306 return false;
307 }
308 return true;
309 }
310 /**
311 * @brief Is limiter enable refresh.
312 * @param formId The Id of the form.
313 * @return Returns true on success, false on failure.
314 */
IsLimiterEnableRefresh(const int64_t formId)315 bool FormTimerMgr::IsLimiterEnableRefresh(const int64_t formId)
316 {
317 return refreshLimiter_.IsEnableRefresh(formId);
318 }
319 /**
320 * @brief Increase refresh count.
321 * @param formId The Id of the form.
322 */
IncreaseRefreshCount(const int64_t formId)323 void FormTimerMgr::IncreaseRefreshCount(const int64_t formId)
324 {
325 refreshLimiter_.Increase(formId);
326 }
327 /**
328 * @brief Set next refresh time.
329 * @param formId The Id of the form.
330 * @param nextGapTime Next gap time(ms).
331 * @param userId User ID.
332 * @return Returns true on success, false on failure.
333 */
SetNextRefreshTime(const int64_t formId,const long nextGapTime,const int32_t userId)334 bool FormTimerMgr::SetNextRefreshTime(const int64_t formId, const long nextGapTime, const int32_t userId)
335 {
336 if (nextGapTime < Constants::MIN_NEXT_TIME) {
337 HILOG_ERROR("%{public}s failed, nextGapTime is invalid, nextGapTime:%{public}ld", __func__, nextGapTime);
338 return false;
339 }
340 auto timeSinceEpoch = std::chrono::steady_clock::now().time_since_epoch();
341 int64_t timeInSec = std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
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 std::lock_guard<std::mutex> lock(refreshMutex_);
346 bool isExist = false;
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 std::sort(dynamicRefreshTasks_.begin(), dynamicRefreshTasks_.end(), 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 auto iter = intervalTimerTasks_.find(formId);
380 if (iter != intervalTimerTasks_.end()) {
381 iter->second.isEnable = flag;
382 HILOG_INFO("%{public}s, formId:%{public}" PRId64 ", isEnable:%{public}d", __func__, formId, flag ? 1 : 0);
383 return;
384 }
385 }
386
387 /**
388 * @brief Get refresh count.
389 * @param formId The Id of the form.
390 * @return Returns refresh count.
391 */
GetRefreshCount(const int64_t formId) const392 int FormTimerMgr::GetRefreshCount(const int64_t formId) const
393 {
394 return refreshLimiter_.GetRefreshCount(formId);
395 }
396 /**
397 * @brief Mark remind.
398 * @param formId The Id of the form.
399 * @return true or false.
400 */
MarkRemind(const int64_t formId)401 void FormTimerMgr::MarkRemind(const int64_t formId)
402 {
403 refreshLimiter_.MarkRemind(formId);
404 }
405 /**
406 * @brief Add update at timer.
407 * @param task Update time task.
408 * @return Returns true on success, false on failure.
409 */
AddUpdateAtTimer(const FormTimer & task)410 bool FormTimerMgr::AddUpdateAtTimer(const FormTimer &task)
411 {
412 HILOG_INFO("%{public}s start", __func__);
413 {
414 std::lock_guard<std::mutex> lock(updateAtMutex_);
415 for (auto &updateAtTimer : updateAtTimerTasks_) {
416 if (updateAtTimer.refreshTask.formId == task.formId) {
417 HILOG_WARN(
418 "%{public}s, already exist formTimer, formId:%{public}" PRId64 " task", __func__, task.formId);
419 return true;
420 }
421 }
422
423 UpdateAtItem atItem;
424 atItem.refreshTask = task;
425 atItem.updateAtTime = task.hour * Constants::MIN_PER_HOUR + task.min;
426
427 AddUpdateAtItem(atItem);
428 }
429 if (!UpdateLimiterAlarm()) {
430 HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
431 return false;
432 }
433
434 if (!UpdateAtTimerAlarm()) {
435 HILOG_ERROR("%{public}s, failed to update attimer alarm.", __func__);
436 return false;
437 }
438
439 return refreshLimiter_.AddItem(task.formId);
440 }
441 /**
442 * @brief Add update interval timer task.
443 * @param task Update interval timer task.
444 * @return Returns true on success, false on failure.
445 */
AddIntervalTimer(const FormTimer & task)446 bool FormTimerMgr::AddIntervalTimer(const FormTimer &task)
447 {
448 HILOG_INFO("%{public}s start", __func__);
449 {
450 std::lock_guard<std::mutex> lock(intervalMutex_);
451 EnsureInitIntervalTimer();
452 if (intervalTimerTasks_.find(task.formId) != intervalTimerTasks_.end()) {
453 HILOG_WARN("%{public}s, already exist formTimer, formId:%{public}" PRId64 " task", __func__, task.formId);
454 return true;
455 }
456 intervalTimerTasks_.emplace(task.formId, task);
457 }
458 if (!UpdateLimiterAlarm()) {
459 HILOG_ERROR("%{public}s, failed to UpdateLimiterAlarm", __func__);
460 return false;
461 }
462 return refreshLimiter_.AddItem(task.formId);
463 }
464 /**
465 * @brief Add update at timer item.
466 * @param task Update at timer item.
467 */
AddUpdateAtItem(const UpdateAtItem & atItem)468 void FormTimerMgr::AddUpdateAtItem(const UpdateAtItem &atItem)
469 {
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 if (!updateAtTimerTasks_.empty()) {
503 atTimerWakeUpTime_ = LONG_MAX;
504 UpdateAtTimerAlarm();
505 }
506 UpdateLimiterAlarm();
507 HILOG_INFO("%{public}s end", __func__);
508 return true;
509 }
510 /**
511 * @brief Reset form limiter.
512 * @return Returns true on success, false on failure.
513 */
HandleResetLimiter()514 bool FormTimerMgr::HandleResetLimiter()
515 {
516 HILOG_INFO("%{public}s start", __func__);
517
518 std::vector<FormTimer> remindTasks;
519 bool bGetTasks = GetRemindTasks(remindTasks);
520 if (bGetTasks) {
521 HILOG_INFO("%{public}s failed, remind when reset limiter", __func__);
522 for (auto &task : remindTasks) {
523 ExecTimerTask(task);
524 }
525 }
526
527 HILOG_INFO("%{public}s end", __func__);
528 return true;
529 }
530 /**
531 * @brief Update attime trigger.
532 * @param updateTime Update time.
533 * @return Returns true on success, false on failure.
534 */
OnUpdateAtTrigger(long updateTime)535 bool FormTimerMgr::OnUpdateAtTrigger(long updateTime)
536 {
537 HILOG_INFO("%{public}s start, updateTime:%{public}ld", __func__, updateTime);
538 std::vector<UpdateAtItem> updateList;
539 {
540 std::lock_guard<std::mutex> lock(updateAtMutex_);
541 std::list<UpdateAtItem>::iterator itItem;
542 for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
543 if (itItem->updateAtTime == updateTime && itItem->refreshTask.isEnable) {
544 updateList.emplace_back(*itItem);
545 }
546 }
547 }
548
549 if (!UpdateAtTimerAlarm()) {
550 HILOG_ERROR("%{public}s, failed to update attimer alarm.", __func__);
551 return false;
552 }
553
554 if (!updateList.empty()) {
555 HILOG_INFO("%{public}s, update at timer triggered, trigged time: %{public}ld", __func__, updateTime);
556 for (auto &item : updateList) {
557 ExecTimerTask(item.refreshTask);
558 }
559 }
560
561 HILOG_INFO("%{public}s end", __func__);
562 return true;
563 }
564 /**
565 * @brief Dynamic time trigger.
566 * @param updateTime Update time.
567 * @return Returns true on success, false on failure.
568 */
OnDynamicTimeTrigger(int64_t updateTime)569 bool FormTimerMgr::OnDynamicTimeTrigger(int64_t updateTime)
570 {
571 HILOG_INFO("%{public}s start, updateTime:%{public}" PRId64 "", __func__, updateTime);
572 std::vector<FormTimer> updateList;
573 {
574 std::lock_guard<std::mutex> lock(dynamicMutex_);
575 auto timeSinceEpoch = std::chrono::steady_clock::now().time_since_epoch();
576 auto timeInSec = std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
577 int64_t markedTime = timeInSec + Constants::ABS_REFRESH_MS;
578 std::vector<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 std::sort(dynamicRefreshTasks_.begin(), dynamicRefreshTasks_.end(), 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, trigged 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::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 ? 1 : 0);
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(const int64_t formId,FormTimer & formTimer)657 bool FormTimerMgr::GetIntervalTimer(const int64_t formId, FormTimer &formTimer)
658 {
659 HILOG_INFO("%{public}s start", __func__);
660 std::lock_guard<std::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(const int64_t formId,UpdateAtItem & updateAtItem)675 bool FormTimerMgr::GetUpdateAtTimer(const int64_t formId, UpdateAtItem &updateAtItem)
676 {
677 HILOG_INFO("%{public}s start", __func__);
678 {
679 std::lock_guard<std::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(const int64_t formId,DynamicRefreshItem & dynamicItem)698 bool FormTimerMgr::GetDynamicItem(const int64_t formId, DynamicRefreshItem &dynamicItem)
699 {
700 HILOG_INFO("%{public}s start", __func__);
701 std::lock_guard<std::mutex> lock(dynamicMutex_);
702 std::vector<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(const int64_t formId)731 bool FormTimerMgr::DeleteIntervalTimer(const int64_t formId)
732 {
733 HILOG_INFO("%{public}s start", __func__);
734 bool isExist = false;
735 std::lock_guard<std::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(const int64_t formId)753 bool FormTimerMgr::DeleteUpdateAtTimer(const int64_t formId)
754 {
755 HILOG_INFO("%{public}s start", __func__);
756 {
757 std::lock_guard<std::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 attimer 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(const int64_t formId)778 bool FormTimerMgr::DeleteDynamicItem(const int64_t formId)
779 {
780 HILOG_INFO("%{public}s start", __func__);
781 std::lock_guard<std::mutex> lock(dynamicMutex_);
782 std::vector<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 }
792 std::sort(dynamicRefreshTasks_.begin(), dynamicRefreshTasks_.end(), CompareDynamicRefreshItem);
793
794 if (!UpdateDynamicAlarm()) {
795 HILOG_ERROR("%{public}s, failed to UpdateDynamicAlarm", __func__);
796 return false;
797 }
798 HILOG_INFO("%{public}s end", __func__);
799 return true;
800 }
801 /**
802 * @brief interval timer task timeout.
803 */
OnIntervalTimeOut()804 void FormTimerMgr::OnIntervalTimeOut()
805 {
806 HILOG_INFO("%{public}s start", __func__);
807 std::lock_guard<std::mutex> lock(intervalMutex_);
808 std::vector<FormTimer> updateList;
809 int64_t currentTime = FormUtil::GetCurrentNanosecond() / Constants::TIME_1000000;
810 for (auto &intervalPair : intervalTimerTasks_) {
811 FormTimer &intervalTask = intervalPair.second;
812 if ((intervalTask.refreshTime == INT64_MAX || (currentTime - intervalTask.refreshTime) >= intervalTask.period ||
813 std::abs((currentTime - intervalTask.refreshTime) - intervalTask.period) < Constants::ABS_TIME) &&
814 intervalTask.isEnable && refreshLimiter_.IsEnableRefresh(intervalTask.formId)) {
815 intervalTask.refreshTime = currentTime;
816 updateList.emplace_back(intervalTask);
817 }
818 }
819
820 if (!updateList.empty()) {
821 for (auto &task : updateList) {
822 ExecTimerTask(task);
823 }
824 }
825 HILOG_INFO("%{public}s end", __func__);
826 }
827
828 /**
829 * @brief Update at timer task alarm.
830 * @return Returns true on success, false on failure.
831 */
UpdateAtTimerAlarm()832 bool FormTimerMgr::UpdateAtTimerAlarm()
833 {
834 HILOG_INFO("%{public}s start", __func__);
835 struct tm tmAtTime = {0};
836 auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
837 struct tm* ptm = localtime_r(&tt, &tmAtTime);
838 if (ptm == nullptr) {
839 HILOG_ERROR("%{public}s failed, localtime error", __func__);
840 return false;
841 }
842
843 long nowAtTime = tmAtTime.tm_hour * Constants::MIN_PER_HOUR + tmAtTime.tm_min;
844 int64_t currentTime = FormUtil::GetCurrentMillisecond();
845 UpdateAtItem findedItem;
846 bool bFinded = FindNextAtTimerItem(nowAtTime, findedItem);
847 if (!bFinded) {
848 if (!updateAtTimerTasks_.empty()) {
849 HILOG_WARN("%{public}s, updateAtTimerTasks_ is not empty", __func__);
850 return true;
851 }
852 ClearUpdateAtTimerResource();
853 atTimerWakeUpTime_ = LONG_MAX;
854 HILOG_INFO("%{public}s, no update at task in system now.", __func__);
855 return true;
856 }
857
858 long nextWakeUpTime = findedItem.updateAtTime;
859 tmAtTime.tm_sec = 0;
860 tmAtTime.tm_hour = findedItem.refreshTask.hour;
861 tmAtTime.tm_min = findedItem.refreshTask.min;
862 int64_t selectTime = FormUtil::GetMillisecondFromTm(tmAtTime);
863 if (selectTime < currentTime) {
864 selectTime += Constants::MS_PER_DAY;
865 nextWakeUpTime += (Constants::HOUR_PER_DAY * Constants::MIN_PER_HOUR);
866 }
867 HILOG_INFO("%{public}s, selectTime: %{public}" PRId64 ", currentTime: %{public}" PRId64 ".",
868 __func__, selectTime, currentTime);
869
870 if (nextWakeUpTime == atTimerWakeUpTime_) {
871 HILOG_WARN("%{public}s end, wakeUpTime not change, no need update alarm.", __func__);
872 return true;
873 }
874
875 auto timerOption = std::make_shared<FormTimerOption>();
876 timerOption->SetType(((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
877 | ((unsigned int)(timerOption->TIMER_TYPE_WAKEUP)));
878 timerOption->SetRepeat(false);
879 timerOption->SetInterval(0);
880 int32_t userId = findedItem.refreshTask.userId;
881 std::shared_ptr<WantAgent> wantAgent = GetUpdateAtWantAgent(findedItem.updateAtTime, userId);
882 if (wantAgent == nullptr) {
883 HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
884 return false;
885 }
886 timerOption->SetWantAgent(wantAgent);
887
888 atTimerWakeUpTime_ = nextWakeUpTime;
889 if (currentUpdateAtWantAgent != nullptr) {
890 ClearUpdateAtTimerResource();
891 }
892 auto timeSinceEpoch = std::chrono::steady_clock::now().time_since_epoch();
893 int64_t timeInSec = std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch).count();
894 int64_t nextTime = timeInSec + (selectTime - currentTime);
895 HILOG_INFO("%{public}s, nextTime: %{public}" PRId64 ".", __func__, nextTime);
896
897 currentUpdateAtWantAgent = wantAgent;
898 updateAtTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
899 bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(updateAtTimerId_,
900 static_cast<uint64_t>(nextTime));
901 if (!bRet) {
902 HILOG_ERROR("%{public}s failed, init update at timer task error", __func__);
903 return false;
904 }
905
906 HILOG_INFO("%{public}s end", __func__);
907 return true;
908 }
909
910 /**
911 * @brief Get WantAgent.
912 * @param updateAtTime The next update time.
913 * @return Returns WantAgent.
914 */
GetUpdateAtWantAgent(long updateAtTime,int32_t userId)915 std::shared_ptr<WantAgent> FormTimerMgr::GetUpdateAtWantAgent(long updateAtTime, int32_t userId)
916 {
917 std::shared_ptr<Want> want = std::make_shared<Want>();
918 ElementName element("", "", "");
919 want->SetElement(element);
920 want->SetAction(Constants::ACTION_UPDATEATTIMER);
921 want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_STATIC_UPDATE);
922 want->SetParam(Constants::KEY_WAKEUP_TIME, updateAtTime);
923
924 std::vector<std::shared_ptr<AAFwk::Want>> wants;
925 wants.emplace_back(want);
926 WantAgentInfo wantAgentInfo(REQUEST_UPDATE_AT_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
927 WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
928 return WantAgentHelper::GetWantAgent(wantAgentInfo, userId);
929 }
930
931 /**
932 * @brief Clear update at timer resource.
933 */
ClearUpdateAtTimerResource()934 void FormTimerMgr::ClearUpdateAtTimerResource()
935 {
936 HILOG_INFO("%{public}s start", __func__);
937 if (updateAtTimerId_ != 0L) {
938 HILOG_INFO("%{public}s clear update at timer start", __func__);
939 MiscServices::TimeServiceClient::GetInstance()->StopTimer(updateAtTimerId_);
940 MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(updateAtTimerId_);
941 HILOG_INFO("%{public}s clear update at timer end", __func__);
942 updateAtTimerId_ = 0L;
943 }
944 if (currentUpdateAtWantAgent != nullptr) {
945 WantAgentHelper::Cancel(currentUpdateAtWantAgent);
946 currentUpdateAtWantAgent = nullptr;
947 }
948 HILOG_INFO("%{public}s end", __func__);
949 }
950
951 /**
952 * @brief Update limiter task alarm.
953 * @return Returns true on success, false on failure.
954 */
UpdateLimiterAlarm()955 bool FormTimerMgr::UpdateLimiterAlarm()
956 {
957 HILOG_INFO("%{public}s start", __func__);
958 if (limiterTimerId_ != 0L) {
959 HILOG_INFO("%{public}s clear limiter timer start", __func__);
960 MiscServices::TimeServiceClient::GetInstance()->StopTimer(limiterTimerId_);
961 MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(limiterTimerId_);
962 HILOG_INFO("%{public}s clear limiter timer end", __func__);
963 limiterTimerId_ = 0L;
964 }
965
966 // make limiter wakeup time
967 struct tm tmAtTime = {0};
968 auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
969 struct tm* ptm = localtime_r(&tt, &tmAtTime);
970 if (ptm == nullptr) {
971 HILOG_ERROR("%{public}s failed, localtime error", __func__);
972 return false;
973 }
974 tmAtTime.tm_sec = Constants::MAX_SECOND; // max value can be 61
975 tmAtTime.tm_hour = Constants::MAX_HOUR;
976 tmAtTime.tm_min = Constants::MAX_MINUTE;
977 int64_t limiterWakeUpTime = FormUtil::GetMillisecondFromTm(tmAtTime);
978
979 auto timerOption = std::make_shared<FormTimerOption>();
980 timerOption->SetType(timerOption->TIMER_TYPE_WAKEUP);
981 timerOption->SetRepeat(false);
982 timerOption->SetInterval(0);
983 std::shared_ptr<WantAgent> wantAgent = GetLimiterWantAgent();
984 if (!wantAgent) {
985 HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
986 return false;
987 }
988 timerOption->SetWantAgent(wantAgent);
989
990 if (currentLimiterWantAgent != nullptr) {
991 ClearLimiterTimerResource();
992 }
993 currentLimiterWantAgent = wantAgent;
994
995 limiterTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
996 bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(limiterTimerId_,
997 static_cast<uint64_t>(limiterWakeUpTime));
998 if (!bRet) {
999 HILOG_ERROR("%{public}s failed, init limiter timer task error", __func__);
1000 return false;
1001 }
1002 HILOG_INFO("%{public}s end", __func__);
1003 return true;
1004 }
1005 /**
1006 * @brief Clear limiter timer resource.
1007 */
ClearLimiterTimerResource()1008 void FormTimerMgr::ClearLimiterTimerResource()
1009 {
1010 HILOG_INFO("%{public}s start", __func__);
1011 if (limiterTimerId_ != 0L) {
1012 HILOG_INFO("%{public}s clear limiter timer start", __func__);
1013 MiscServices::TimeServiceClient::GetInstance()->StopTimer(limiterTimerId_);
1014 MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(limiterTimerId_);
1015 HILOG_INFO("%{public}s clear limiter timer end", __func__);
1016 limiterTimerId_ = 0L;
1017 }
1018 if (currentLimiterWantAgent != nullptr) {
1019 WantAgentHelper::Cancel(currentLimiterWantAgent);
1020 currentLimiterWantAgent = nullptr;
1021 }
1022 HILOG_INFO("%{public}s end", __func__);
1023 }
1024
1025 /**
1026 * @brief Get WantAgent.
1027 * @return Returns WantAgent.
1028 */
GetLimiterWantAgent()1029 std::shared_ptr<WantAgent> FormTimerMgr::GetLimiterWantAgent()
1030 {
1031 std::shared_ptr<Want> want = std::make_shared<Want>();
1032 ElementName element("", "", "");
1033 want->SetElement(element);
1034 want->SetAction(Constants::ACTION_UPDATEATTIMER);
1035 want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_RESET_LIMIT);
1036
1037 std::vector<std::shared_ptr<AAFwk::Want>> wants;
1038 wants.emplace_back(want);
1039 WantAgentInfo wantAgentInfo(REQUEST_LIMITER_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1040 WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
1041 return WantAgentHelper::GetWantAgent(wantAgentInfo);
1042 }
1043
1044 /**
1045 * @brief Update dynamic refresh task alarm.
1046 * @return Returns true on success, false on failure.
1047 */
UpdateDynamicAlarm()1048 bool FormTimerMgr::UpdateDynamicAlarm()
1049 {
1050 HILOG_INFO("%{public}s start", __func__);
1051 if (dynamicRefreshTasks_.empty()) {
1052 ClearDynamicResource();
1053 dynamicWakeUpTime_ = INT64_MAX;
1054 return true;
1055 }
1056
1057 bool needUpdate = false;
1058 DynamicRefreshItem firstTask = dynamicRefreshTasks_.at(0);
1059 if (dynamicWakeUpTime_ != firstTask.settedTime) {
1060 dynamicWakeUpTime_ = firstTask.settedTime;
1061 needUpdate = true;
1062 }
1063
1064 if (!needUpdate) {
1065 HILOG_ERROR("%{public}s failed, no need to UpdateDynamicAlarm.", __func__);
1066 return true;
1067 }
1068
1069 auto timerOption = std::make_shared<FormTimerOption>();
1070 timerOption->SetType(((unsigned int)(timerOption->TIMER_TYPE_REALTIME))
1071 | ((unsigned int)(timerOption->TIMER_TYPE_WAKEUP)));
1072 timerOption->SetRepeat(false);
1073 timerOption->SetInterval(0);
1074 std::shared_ptr<WantAgent> wantAgent = GetDynamicWantAgent(dynamicWakeUpTime_, firstTask.userId);
1075 if (!wantAgent) {
1076 HILOG_ERROR("%{public}s, failed to create wantAgent.", __func__);
1077 return false;
1078 }
1079 timerOption->SetWantAgent(wantAgent);
1080
1081 if (currentDynamicWantAgent != nullptr) {
1082 ClearDynamicResource();
1083 }
1084 currentDynamicWantAgent = wantAgent;
1085
1086 dynamicAlarmTimerId_ = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(timerOption);
1087 bool bRet = MiscServices::TimeServiceClient::GetInstance()->StartTimer(dynamicAlarmTimerId_,
1088 static_cast<uint64_t>(dynamicWakeUpTime_));
1089 if (!bRet) {
1090 HILOG_ERROR("%{public}s failed, init dynamic timer task error", __func__);
1091 }
1092 HILOG_INFO("%{public}s end, dynamicWakeUpTime_ : %{public}" PRId64 ".", __func__, dynamicWakeUpTime_);
1093 return true;
1094 }
1095 /**
1096 * @brief Get WantAgent.
1097 * @param nextTime The next update time.
1098 * @return Returns WantAgent.
1099 */
GetDynamicWantAgent(int64_t nextTime,int32_t userId)1100 std::shared_ptr<WantAgent> FormTimerMgr::GetDynamicWantAgent(int64_t nextTime, int32_t userId)
1101 {
1102 std::shared_ptr<Want> want = std::make_shared<Want>();
1103 ElementName element("", "", "");
1104 want->SetElement(element);
1105 want->SetAction(Constants::ACTION_UPDATEATTIMER);
1106 want->SetParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_DYNAMIC_UPDATE);
1107 int nextTimeRight = static_cast<int>(nextTime);
1108 int nextTimLeft = static_cast<int>(nextTime >> SHIFT_BIT_LENGTH);
1109
1110 want->SetParam(Constants::KEY_WAKEUP_TIME_LEFT, nextTimLeft);
1111 want->SetParam(Constants::KEY_WAKEUP_TIME_RIGHT, nextTimeRight);
1112 std::vector<std::shared_ptr<AAFwk::Want>> wants;
1113 wants.emplace_back(want);
1114 WantAgentInfo wantAgentInfo(REQUEST_DYNAMIC_CODE, WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1115 WantAgentConstant::Flags::UPDATE_PRESENT_FLAG, wants, nullptr);
1116 return WantAgentHelper::GetWantAgent(wantAgentInfo, userId);
1117 }
1118
1119 /**
1120 * @brief Clear dynamic refresh resource.
1121 */
ClearDynamicResource()1122 void FormTimerMgr::ClearDynamicResource()
1123 {
1124 HILOG_INFO("%{public}s start", __func__);
1125 if (dynamicAlarmTimerId_ != 0L) {
1126 HILOG_INFO("%{public}s clear dynamic timer start", __func__);
1127 MiscServices::TimeServiceClient::GetInstance()->StopTimer(dynamicAlarmTimerId_);
1128 MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(dynamicAlarmTimerId_);
1129 HILOG_INFO("%{public}s clear dynamic timer end", __func__);
1130 dynamicAlarmTimerId_ = 0L;
1131 }
1132
1133 if (currentDynamicWantAgent != nullptr) {
1134 WantAgentHelper::Cancel(currentDynamicWantAgent);
1135 currentDynamicWantAgent = nullptr;
1136 }
1137 HILOG_INFO("%{public}s end", __func__);
1138 }
1139 /**
1140 * @brief Fint next at timer item.
1141 * @param nowTime Update time.
1142 * @param updateAtItem Next at timer item.
1143 * @return Returns true on success, false on failure.
1144 */
FindNextAtTimerItem(const long nowTime,UpdateAtItem & updateAtItem)1145 bool FormTimerMgr::FindNextAtTimerItem(const long nowTime, UpdateAtItem &updateAtItem)
1146 {
1147 HILOG_INFO("%{public}s start", __func__);
1148 if (updateAtTimerTasks_.empty()) {
1149 HILOG_WARN("%{public}s, updateAtTimerTasks_ is empty", __func__);
1150 return false;
1151 }
1152
1153 std::lock_guard<std::mutex> lock(updateAtMutex_);
1154 std::list<UpdateAtItem>::iterator itItem;
1155 for (itItem = updateAtTimerTasks_.begin(); itItem != updateAtTimerTasks_.end(); itItem++) {
1156 if (itItem->updateAtTime > nowTime) {
1157 updateAtItem = *itItem;
1158 break;
1159 }
1160 }
1161
1162 if (itItem == updateAtTimerTasks_.end()) {
1163 updateAtItem = updateAtTimerTasks_.front();
1164 }
1165 HILOG_INFO("%{public}s end", __func__);
1166 return true;
1167 }
1168
1169 /**
1170 * @brief Ensure init interval timer resource.
1171 */
EnsureInitIntervalTimer()1172 void FormTimerMgr::EnsureInitIntervalTimer()
1173 {
1174 HILOG_INFO("%{public}s, init base timer task", __func__);
1175 if (intervalTimer_ != nullptr) {
1176 return;
1177 }
1178
1179 intervalTimer_ = std::make_shared<Utils::Timer>("interval timer");
1180 auto timeCallback = []() { FormTimerMgr::GetInstance().OnIntervalTimeOut(); };
1181 intervalTimer_->Register(timeCallback, Constants::MIN_PERIOD / timeSpeed_);
1182 intervalTimer_->Setup();
1183
1184 HILOG_INFO("%{public}s end", __func__);
1185 }
1186 /**
1187 * @brief Clear interval timer resource.
1188 */
ClearIntervalTimer()1189 void FormTimerMgr::ClearIntervalTimer()
1190 {
1191 HILOG_INFO("%{public}s start", __func__);
1192 if (intervalTimer_ != nullptr) {
1193 intervalTimer_->Shutdown();
1194 intervalTimer_.reset();
1195 }
1196 HILOG_INFO("%{public}s end", __func__);
1197 }
1198 /**
1199 * @brief Creat thread pool for timer task.
1200 */
1201
CreatTaskThreadExecutor()1202 void FormTimerMgr::CreatTaskThreadExecutor()
1203 {
1204 HILOG_INFO("%{public}s start", __func__);
1205 if (taskExecutor_ == nullptr) {
1206 taskExecutor_ = std::make_unique<ThreadPool>("timer task thread");
1207 taskExecutor_->Start(Constants::WORK_POOL_SIZE);
1208 }
1209 HILOG_INFO("%{public}s end", __func__);
1210 return;
1211 }
1212
1213 /**
1214 * @brief Execute Form timer task.
1215 * @param timerTask Form timer task.
1216 */
ExecTimerTask(const FormTimer & timerTask)1217 void FormTimerMgr::ExecTimerTask(const FormTimer &timerTask)
1218 {
1219 HILOG_INFO("%{public}s start", __func__);
1220 CreatTaskThreadExecutor();
1221 if (taskExecutor_ != nullptr) {
1222 HILOG_INFO("%{public}s run", __func__);
1223 AAFwk::Want want;
1224 if (timerTask.isCountTimer) {
1225 want.SetParam(Constants::KEY_IS_TIMER, true);
1226 }
1227 // multi user
1228 if (IsActiveUser(timerTask.userId)) {
1229 HILOG_INFO("timerTask.userId is current user");
1230 want.SetParam(Constants::PARAM_FORM_USER_ID, timerTask.userId);
1231 }
1232 HILOG_INFO("%{public}s, userId:%{public}d", __func__, timerTask.userId);
1233
1234 auto task = std::bind(&FormProviderMgr::RefreshForm, &FormProviderMgr::GetInstance(), timerTask.formId, want,
1235 false);
1236 taskExecutor_->AddTask(task);
1237 }
1238 HILOG_INFO("%{public}s end", __func__);
1239 }
1240
1241 /**
1242 * @brief Init.
1243 */
Init()1244 void FormTimerMgr::Init()
1245 {
1246 HILOG_INFO("%{public}s start", __func__);
1247 timerReceiver_ = nullptr;
1248 EventFwk::MatchingSkills matchingSkills;
1249 matchingSkills.AddEvent(Constants::ACTION_UPDATEATTIMER);
1250 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
1251 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED);
1252 matchingSkills.AddEvent(FMS_TIME_SPEED);
1253
1254 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
1255 timerReceiver_ = std::make_shared<TimerReceiver>(subscribeInfo);
1256 EventFwk::CommonEventManager::SubscribeCommonEvent(timerReceiver_);
1257
1258 intervalTimer_ = nullptr;
1259 updateAtTimerId_ = 0L;
1260 dynamicAlarmTimerId_ = 0L;
1261 limiterTimerId_ = 0L;
1262 taskExecutor_ = nullptr;
1263
1264 HILOG_INFO("%{public}s end", __func__);
1265 }
1266
1267 /**
1268 * @brief Receiver Constructor.
1269 * @param subscriberInfo Subscriber info.
1270 */
TimerReceiver(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)1271 FormTimerMgr::TimerReceiver::TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
1272 : EventFwk::CommonEventSubscriber(subscriberInfo)
1273 {}
1274 /**
1275 * @brief Receive common event.
1276 * @param eventData Common event data.
1277 */
OnReceiveEvent(const EventFwk::CommonEventData & eventData)1278 void FormTimerMgr::TimerReceiver::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
1279 {
1280 AAFwk::Want want = eventData.GetWant();
1281 std::string action = want.GetAction();
1282
1283 HILOG_INFO("%{public}s, action:%{public}s.", __func__, action.c_str());
1284
1285 if (action == FMS_TIME_SPEED) {
1286 // Time speed must between 1 and 1000.
1287 auto timeSpeed = std::clamp(eventData.GetCode(), Constants::MIN_TIME_SPEED, Constants::MAX_TIME_SPEED);
1288 FormTimerMgr::GetInstance().SetTimeSpeed(timeSpeed);
1289 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED
1290 || action == EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED) {
1291 FormTimerMgr::GetInstance().HandleSystemTimeChanged();
1292 } else if (action == Constants::ACTION_UPDATEATTIMER) {
1293 int type = want.GetIntParam(Constants::KEY_ACTION_TYPE, Constants::TYPE_STATIC_UPDATE);
1294 if (type == Constants::TYPE_RESET_LIMIT) {
1295 FormTimerMgr::GetInstance().HandleResetLimiter();
1296 } else if (type == Constants::TYPE_STATIC_UPDATE) {
1297 long updateTime = want.GetLongParam(Constants::KEY_WAKEUP_TIME, -1);
1298 if (updateTime < 0) {
1299 HILOG_ERROR("%{public}s failed, invalid updateTime:%{public}ld.", __func__, updateTime);
1300 return;
1301 }
1302 FormTimerMgr::GetInstance().OnUpdateAtTrigger(updateTime);
1303 } else if (type == Constants::TYPE_DYNAMIC_UPDATE) {
1304 int updateTimeLeft = want.GetIntParam(Constants::KEY_WAKEUP_TIME_LEFT, -1);
1305 int updateTimeRight = want.GetIntParam(Constants::KEY_WAKEUP_TIME_RIGHT, -1);
1306 int64_t updateTime = static_cast<int64_t>(updateTimeLeft);
1307 updateTime = updateTime << SHIFT_BIT_LENGTH;
1308 updateTime |= updateTimeRight;
1309 if (updateTime <= 0) {
1310 HILOG_ERROR("%{public}s failed, invalid updateTime:%{public}" PRId64 "", __func__, updateTime);
1311 return;
1312 }
1313 FormTimerMgr::GetInstance().OnDynamicTimeTrigger(updateTime);
1314 } else {
1315 HILOG_ERROR("%{public}s failed, invalid type when action is update at timer.", __func__);
1316 }
1317 } else {
1318 HILOG_ERROR("%{public}s failed, invalid action.", __func__);
1319 }
1320 }
1321 /**
1322 * @brief check if user is active or not.
1323 *
1324 * @param userId User ID.
1325 * @return true:active, false:inactive
1326 */
IsActiveUser(const int32_t userId)1327 bool FormTimerMgr::IsActiveUser(const int32_t userId)
1328 {
1329 std::vector<int32_t> activeList;
1330 auto refCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeList);
1331 auto iter = std::find(activeList.begin(), activeList.end(), userId);
1332 if (iter != activeList.end() && refCode == ERR_OK) {
1333 return true;
1334 }
1335 return false;
1336 }
1337 } // namespace AppExecFwk
1338 } // namespace OHOS
1339