1/* 2 * Copyright (C) 2021 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#include "time_tick_notify.h" 16 17#include <chrono> 18#include <cinttypes> 19#include <ctime> 20#include <thread> 21 22#include "common_timer_errors.h" 23#include "matching_skills.h" 24#include "time_common.h" 25#include "time_service_notify.h" 26#include "time_system_ability.h" 27#include "timer_manager_interface.h" 28 29using namespace std::chrono; 30 31namespace OHOS { 32namespace MiscServices { 33namespace { 34constexpr uint64_t MINUTE_TO_MILLISECOND = 60000; 35constexpr uint64_t MICRO_TO_MILLISECOND = 1000; 36constexpr uint64_t MILLISECOND_TO_SECOND = 1000; 37} // namespace 38 39TimeTickNotify &TimeTickNotify::GetInstance() 40{ 41 static TimeTickNotify instance; 42 return instance; 43} 44 45TimeTickNotify::TimeTickNotify() : timer_("TickTimer"){}; 46TimeTickNotify::~TimeTickNotify() = default; 47 48void TimeTickNotify::Init() 49{ 50 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify start."); 51 uint32_t ret = timer_.Setup(); 52 if (ret != Utils::TIMER_ERR_OK) { 53 TIME_HILOGE(TIME_MODULE_SERVICE, "Timer Setup failed: %{public}d", ret); 54 return; 55 } 56 auto callback = [this]() { this->Callback(); }; 57 uint64_t nextTriggerTime = RefreshNextTriggerTime(); 58 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify triggertime: %{public}" PRId64 "", nextTriggerTime); 59 std::lock_guard<std::mutex> lock(timeridMutex_); 60 timerId_ = timer_.Register(callback, nextTriggerTime); 61 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick timer ID: %{public}d", timerId_); 62} 63 64void TimeTickNotify::Callback() 65{ 66 std::lock_guard<std::mutex> lock(timeridMutex_); 67 timer_.Unregister(timerId_); 68 TIME_HILOGD(TIME_MODULE_SERVICE, "Unregister id: %{public}d", timerId_); 69 uint64_t nextTriggerTime = RefreshNextTriggerTime(); 70 auto callback = [this]() { this->Callback(); }; 71 timerId_ = timer_.Register(callback, nextTriggerTime, true); 72 if (nextTriggerTime > (MINUTE_TO_MILLISECOND - MILLISECOND_TO_SECOND)) { 73 auto currentTime = steady_clock::now().time_since_epoch().count(); 74 TimeServiceNotify::GetInstance().PublishTimeTickEvents(currentTime); 75 } 76 TIME_HILOGI(TIME_MODULE_SERVICE, "id: %{public}d triggertime: %{public}" PRId64 "", timerId_, nextTriggerTime); 77} 78 79void TimeTickNotify::PowerCallback() 80{ 81 std::lock_guard<std::mutex> lock(timeridMutex_); 82 timer_.Unregister(timerId_); 83 TIME_HILOGD(TIME_MODULE_SERVICE, "Unregister id: %{public}d", timerId_); 84 uint64_t nextTriggerTime = RefreshNextTriggerTime(); 85 auto callback = [this]() { this->Callback(); }; 86 timerId_ = timer_.Register(callback, nextTriggerTime, true); 87 TIME_HILOGI(TIME_MODULE_SERVICE, "id: %{public}d triggertime: %{public}" PRId64 "", timerId_, nextTriggerTime); 88} 89 90uint64_t TimeTickNotify::RefreshNextTriggerTime() 91{ 92 auto UTCTimeMicro = static_cast<uint64_t>(duration_cast<microseconds>(system_clock::now() 93 .time_since_epoch()).count()); 94 TIME_HILOGD(TIME_MODULE_SERVICE, "Time micro: %{public}" PRIu64 "", UTCTimeMicro); 95 uint64_t timeMilliseconds = (UTCTimeMicro / MICRO_TO_MILLISECOND) % MINUTE_TO_MILLISECOND; 96 uint64_t nextTriggerTime = MINUTE_TO_MILLISECOND - timeMilliseconds; 97 return nextTriggerTime; 98} 99 100void TimeTickNotify::Stop() 101{ 102 TIME_HILOGD(TIME_MODULE_SERVICE, "start."); 103 timer_.Shutdown(); 104 TIME_HILOGD(TIME_MODULE_SERVICE, "end."); 105} 106} // namespace MiscServices 107} // namespace OHOS