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