1cf69771bSopenharmony_ci/* 2cf69771bSopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 3cf69771bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4cf69771bSopenharmony_ci * you may not use this file except in compliance with the License. 5cf69771bSopenharmony_ci * You may obtain a copy of the License at 6cf69771bSopenharmony_ci * 7cf69771bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8cf69771bSopenharmony_ci * 9cf69771bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10cf69771bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11cf69771bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cf69771bSopenharmony_ci * See the License for the specific language governing permissions and 13cf69771bSopenharmony_ci * limitations under the License. 14cf69771bSopenharmony_ci */ 15cf69771bSopenharmony_ci#include "time_tick_notify.h" 16cf69771bSopenharmony_ci 17cf69771bSopenharmony_ci#include <chrono> 18cf69771bSopenharmony_ci#include <cinttypes> 19cf69771bSopenharmony_ci#include <ctime> 20cf69771bSopenharmony_ci#include <thread> 21cf69771bSopenharmony_ci 22cf69771bSopenharmony_ci#include "common_timer_errors.h" 23cf69771bSopenharmony_ci#include "matching_skills.h" 24cf69771bSopenharmony_ci#include "time_common.h" 25cf69771bSopenharmony_ci#include "time_service_notify.h" 26cf69771bSopenharmony_ci#include "time_system_ability.h" 27cf69771bSopenharmony_ci#include "timer_manager_interface.h" 28cf69771bSopenharmony_ci 29cf69771bSopenharmony_ciusing namespace std::chrono; 30cf69771bSopenharmony_ci 31cf69771bSopenharmony_cinamespace OHOS { 32cf69771bSopenharmony_cinamespace MiscServices { 33cf69771bSopenharmony_cinamespace { 34cf69771bSopenharmony_ciconstexpr uint64_t MINUTE_TO_MILLISECOND = 60000; 35cf69771bSopenharmony_ciconstexpr uint64_t MICRO_TO_MILLISECOND = 1000; 36cf69771bSopenharmony_ciconstexpr uint64_t MILLISECOND_TO_SECOND = 1000; 37cf69771bSopenharmony_ci} // namespace 38cf69771bSopenharmony_ci 39cf69771bSopenharmony_ciTimeTickNotify &TimeTickNotify::GetInstance() 40cf69771bSopenharmony_ci{ 41cf69771bSopenharmony_ci static TimeTickNotify instance; 42cf69771bSopenharmony_ci return instance; 43cf69771bSopenharmony_ci} 44cf69771bSopenharmony_ci 45cf69771bSopenharmony_ciTimeTickNotify::TimeTickNotify() : timer_("TickTimer"){}; 46cf69771bSopenharmony_ciTimeTickNotify::~TimeTickNotify() = default; 47cf69771bSopenharmony_ci 48cf69771bSopenharmony_civoid TimeTickNotify::Init() 49cf69771bSopenharmony_ci{ 50cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify start."); 51cf69771bSopenharmony_ci uint32_t ret = timer_.Setup(); 52cf69771bSopenharmony_ci if (ret != Utils::TIMER_ERR_OK) { 53cf69771bSopenharmony_ci TIME_HILOGE(TIME_MODULE_SERVICE, "Timer Setup failed: %{public}d", ret); 54cf69771bSopenharmony_ci return; 55cf69771bSopenharmony_ci } 56cf69771bSopenharmony_ci auto callback = [this]() { this->Callback(); }; 57cf69771bSopenharmony_ci uint64_t nextTriggerTime = RefreshNextTriggerTime(); 58cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify triggertime: %{public}" PRId64 "", nextTriggerTime); 59cf69771bSopenharmony_ci std::lock_guard<std::mutex> lock(timeridMutex_); 60cf69771bSopenharmony_ci timerId_ = timer_.Register(callback, nextTriggerTime); 61cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "Tick timer ID: %{public}d", timerId_); 62cf69771bSopenharmony_ci} 63cf69771bSopenharmony_ci 64cf69771bSopenharmony_civoid TimeTickNotify::Callback() 65cf69771bSopenharmony_ci{ 66cf69771bSopenharmony_ci std::lock_guard<std::mutex> lock(timeridMutex_); 67cf69771bSopenharmony_ci timer_.Unregister(timerId_); 68cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "Unregister id: %{public}d", timerId_); 69cf69771bSopenharmony_ci uint64_t nextTriggerTime = RefreshNextTriggerTime(); 70cf69771bSopenharmony_ci auto callback = [this]() { this->Callback(); }; 71cf69771bSopenharmony_ci timerId_ = timer_.Register(callback, nextTriggerTime, true); 72cf69771bSopenharmony_ci if (nextTriggerTime > (MINUTE_TO_MILLISECOND - MILLISECOND_TO_SECOND)) { 73cf69771bSopenharmony_ci auto currentTime = steady_clock::now().time_since_epoch().count(); 74cf69771bSopenharmony_ci TimeServiceNotify::GetInstance().PublishTimeTickEvents(currentTime); 75cf69771bSopenharmony_ci } 76cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "id: %{public}d triggertime: %{public}" PRId64 "", timerId_, nextTriggerTime); 77cf69771bSopenharmony_ci} 78cf69771bSopenharmony_ci 79cf69771bSopenharmony_civoid TimeTickNotify::PowerCallback() 80cf69771bSopenharmony_ci{ 81cf69771bSopenharmony_ci std::lock_guard<std::mutex> lock(timeridMutex_); 82cf69771bSopenharmony_ci timer_.Unregister(timerId_); 83cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "Unregister id: %{public}d", timerId_); 84cf69771bSopenharmony_ci uint64_t nextTriggerTime = RefreshNextTriggerTime(); 85cf69771bSopenharmony_ci auto callback = [this]() { this->Callback(); }; 86cf69771bSopenharmony_ci timerId_ = timer_.Register(callback, nextTriggerTime, true); 87cf69771bSopenharmony_ci TIME_HILOGI(TIME_MODULE_SERVICE, "id: %{public}d triggertime: %{public}" PRId64 "", timerId_, nextTriggerTime); 88cf69771bSopenharmony_ci} 89cf69771bSopenharmony_ci 90cf69771bSopenharmony_ciuint64_t TimeTickNotify::RefreshNextTriggerTime() 91cf69771bSopenharmony_ci{ 92cf69771bSopenharmony_ci auto UTCTimeMicro = static_cast<uint64_t>(duration_cast<microseconds>(system_clock::now() 93cf69771bSopenharmony_ci .time_since_epoch()).count()); 94cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "Time micro: %{public}" PRIu64 "", UTCTimeMicro); 95cf69771bSopenharmony_ci uint64_t timeMilliseconds = (UTCTimeMicro / MICRO_TO_MILLISECOND) % MINUTE_TO_MILLISECOND; 96cf69771bSopenharmony_ci uint64_t nextTriggerTime = MINUTE_TO_MILLISECOND - timeMilliseconds; 97cf69771bSopenharmony_ci return nextTriggerTime; 98cf69771bSopenharmony_ci} 99cf69771bSopenharmony_ci 100cf69771bSopenharmony_civoid TimeTickNotify::Stop() 101cf69771bSopenharmony_ci{ 102cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "start."); 103cf69771bSopenharmony_ci timer_.Shutdown(); 104cf69771bSopenharmony_ci TIME_HILOGD(TIME_MODULE_SERVICE, "end."); 105cf69771bSopenharmony_ci} 106cf69771bSopenharmony_ci} // namespace MiscServices 107cf69771bSopenharmony_ci} // namespace OHOS