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 "time_system_ability.h"
18
19 using namespace std::chrono;
20
21 namespace OHOS {
22 namespace MiscServices {
23 namespace {
24 constexpr uint64_t MINUTE_TO_MILLISECOND = 60000;
25 constexpr uint64_t SECOND_TO_MILLISECOND = 1000;
26 constexpr int64_t SECOND_TO_NANO = 1000000000;
27 } // namespace
28
GetInstance()29 TimeTickNotify &TimeTickNotify::GetInstance()
30 {
31 static TimeTickNotify instance;
32 return instance;
33 }
34
35 TimeTickNotify::TimeTickNotify() = default;
36 TimeTickNotify::~TimeTickNotify() = default;
37
Init()38 void TimeTickNotify::Init()
39 {
40 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify start");
41 TimerPara timerPara{};
42 timerPara.timerType = static_cast<int>(ITimerManager::TimerType::RTC);
43 timerPara.windowLength = 0;
44 timerPara.interval = 0;
45 timerPara.flag = 0;
46 auto callback = [this](uint64_t id) -> int32_t {
47 this->Callback();
48 return E_TIME_OK;
49 };
50 std::lock_guard<std::mutex> lock(timeridMutex_);
51 TimeSystemAbility::GetInstance()->CreateTimer(timerPara, callback, timerId_);
52 auto trigger = RefreshNextTriggerTime();
53 TimeSystemAbility::GetInstance()->StartTimer(timerId_, trigger.first);
54 TIME_HILOGI(TIME_MODULE_SERVICE, "Tick timer timerId: %{public}" PRIu64 "", timerId_);
55 }
56
Callback()57 void TimeTickNotify::Callback()
58 {
59 std::lock_guard<std::mutex> lock(timeridMutex_);
60 auto trigger = RefreshNextTriggerTime();
61 if (trigger.second) {
62 auto currentTime = steady_clock::now().time_since_epoch().count();
63 if (std::abs(currentTime - lastTriggerTime_) > SECOND_TO_NANO) {
64 TimeServiceNotify::GetInstance().PublishTimeTickEvents(currentTime);
65 lastTriggerTime_ = currentTime;
66 }
67 }
68 TimeSystemAbility::GetInstance()->StartTimer(timerId_, trigger.first);
69 }
70
RefreshNextTriggerTime()71 std::pair<uint64_t, bool> TimeTickNotify::RefreshNextTriggerTime()
72 {
73 int64_t time = 0;
74 TimeUtils::GetWallTimeMs(time);
75 uint64_t currTime = static_cast<uint64_t>(time);
76 uint64_t timeMilliseconds = currTime % MINUTE_TO_MILLISECOND;
77 bool isFirstSecond = timeMilliseconds < SECOND_TO_MILLISECOND;
78 uint64_t nextTriggerTime = ((currTime / MINUTE_TO_MILLISECOND) + 1) * MINUTE_TO_MILLISECOND;
79 return std::make_pair(nextTriggerTime, isFirstSecond);
80 }
81
Stop()82 void TimeTickNotify::Stop()
83 {
84 TIME_HILOGD(TIME_MODULE_SERVICE, "start");
85 TimeSystemAbility::GetInstance()->DestroyTimer(timerId_);
86 TIME_HILOGD(TIME_MODULE_SERVICE, "end");
87 }
88 } // namespace MiscServices
89 } // namespace OHOS