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