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_event_manager.h"
23 #include "common_event_support.h"
24 #include "common_timer_errors.h"
25 #include "matching_skills.h"
26 #include "power_subscriber.h"
27 #include "time_common.h"
28 #include "time_service_notify.h"
29 #include "time_system_ability.h"
30 #include "timer_manager_interface.h"
31
32 using namespace std::chrono;
33
34 namespace OHOS {
35 namespace MiscServices {
36 using namespace OHOS::EventFwk;
37 namespace {
38 constexpr uint64_t MINUTE_TO_MILLISECOND = 60000;
39 constexpr uint64_t MICRO_TO_MILESECOND = 1000;
40 } // namespace
41
GetInstance()42 TimeTickNotify &TimeTickNotify::GetInstance()
43 {
44 static TimeTickNotify instance;
45 return instance;
46 }
47
TimeTickNotify()48 TimeTickNotify::TimeTickNotify() : timer_("TickTimer"){};
~TimeTickNotify()49 TimeTickNotify::~TimeTickNotify(){};
50
Init()51 void TimeTickNotify::Init()
52 {
53 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify start.");
54 MatchingSkills matchingSkills;
55 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_ON);
56 CommonEventSubscribeInfo subscriberInfo(matchingSkills);
57 std::shared_ptr<PowerSubscriber> subscriberPtr = std::make_shared<PowerSubscriber>(subscriberInfo);
58 bool subscribeResult = CommonEventManager::SubscribeCommonEvent(subscriberPtr);
59 if (!subscribeResult) {
60 TIME_HILOGE(TIME_MODULE_SERVICE, "SubscribeCommonEvent failed");
61 }
62 uint32_t ret = timer_.Setup();
63 if (ret != Utils::TIMER_ERR_OK) {
64 TIME_HILOGE(TIME_MODULE_SERVICE, "Timer Setup failed: %{public}d", ret);
65 return;
66 }
67 auto callback = [this]() { this->Callback(); };
68 RefreshNextTriggerTime();
69 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify triggertime: %{public}" PRId64 "", nextTriggerTime_);
70 timerId_ = timer_.Register(callback, nextTriggerTime_);
71 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick timer ID: %{public}d", timerId_);
72 }
73
Callback()74 void TimeTickNotify::Callback()
75 {
76 auto currentTime = steady_clock::now().time_since_epoch().count();
77 DelayedSingleton<TimeServiceNotify>::GetInstance()->PublishTimeTickEvents(currentTime);
78 timer_.Unregister(timerId_);
79 RefreshNextTriggerTime();
80 auto callback = [this]() { this->Callback(); };
81 timerId_ = timer_.Register(callback, nextTriggerTime_);
82 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify triggertime: %{public}" PRId64 "", nextTriggerTime_);
83 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick timer ID: %{public}d", timerId_);
84 }
85
PowerCallback()86 void TimeTickNotify::PowerCallback()
87 {
88 timer_.Unregister(timerId_);
89 RefreshNextTriggerTime();
90 auto callback = [this]() { this->Callback(); };
91 timerId_ = timer_.Register(callback, nextTriggerTime_);
92 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick notify triggertime: %{public}" PRId64 "", nextTriggerTime_);
93 TIME_HILOGD(TIME_MODULE_SERVICE, "Tick timer ID: %{public}d", timerId_);
94 }
RefreshNextTriggerTime()95 void TimeTickNotify::RefreshNextTriggerTime()
96 {
97 time_t t = time(nullptr);
98 struct tm *tblock = localtime(&t);
99 if (tblock == nullptr) {
100 return;
101 }
102 TIME_HILOGD(TIME_MODULE_SERVICE, "Time now: %{public}s", asctime(tblock));
103 auto UTCTimeMicro = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
104 auto timeMilliseconds = GetMillisecondsFromUTC(UTCTimeMicro);
105 nextTriggerTime_ = MINUTE_TO_MILLISECOND - timeMilliseconds;
106 }
107
Stop()108 void TimeTickNotify::Stop()
109 {
110 TIME_HILOGD(TIME_MODULE_SERVICE, "start.");
111 timer_.Shutdown();
112 TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
113 }
114
GetMillisecondsFromUTC(uint64_t UTCtimeMicro)115 uint64_t TimeTickNotify::GetMillisecondsFromUTC(uint64_t UTCtimeMicro)
116 {
117 TIME_HILOGD(TIME_MODULE_SERVICE, "Time micro: %{public}" PRId64 "", UTCtimeMicro);
118 auto milliseconds = (UTCtimeMicro / MICRO_TO_MILESECOND) % MINUTE_TO_MILLISECOND;
119 TIME_HILOGD(TIME_MODULE_SERVICE, "Time milli: %{public}" PRId64 "", milliseconds);
120 return milliseconds;
121 }
122 } // namespace MiscServices
123 } // namespace OHOS