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