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