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
29 using namespace std::chrono;
30
31 namespace OHOS {
32 namespace MiscServices {
33 namespace {
34 constexpr uint64_t MINUTE_TO_MILLISECOND = 60000;
35 constexpr uint64_t MICRO_TO_MILLISECOND = 1000;
36 constexpr uint64_t MILLISECOND_TO_SECOND = 1000;
37 } // namespace
38
GetInstance()39 TimeTickNotify &TimeTickNotify::GetInstance()
40 {
41 static TimeTickNotify instance;
42 return instance;
43 }
44
TimeTickNotify()45 TimeTickNotify::TimeTickNotify() : timer_("TickTimer"){};
46 TimeTickNotify::~TimeTickNotify() = default;
47
Init()48 void 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
Callback()64 void 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
PowerCallback()79 void 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
RefreshNextTriggerTime()90 uint64_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
Stop()100 void 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