1 /*
2  * Copyright (c) 2024 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 
16 #include "alarm_timer_utils.h"
17 
18 #include <cinttypes>
19 
20 #include "constant.h"
21 #include "time_service_client.h"
22 #include "time_utils.h"
23 #include "update_log.h"
24 
25 namespace OHOS {
26 namespace UpdateEngine {
OnTrigger()27 void AlarmTimerUtils::TimerTaskInfo::OnTrigger()
28 {
29     ENGINE_LOGI("timed task had been triggered");
30     if (callBack_ != nullptr) {
31         callBack_();
32     }
33 }
34 
SetType(const int & type)35 void AlarmTimerUtils::TimerTaskInfo::SetType(const int &type)
36 {
37     this->type = type;
38 }
39 
SetRepeat(bool repeat)40 void AlarmTimerUtils::TimerTaskInfo::SetRepeat(bool repeat)
41 {
42     this->repeat = repeat;
43 }
44 
SetInterval(const uint64_t & interval)45 void AlarmTimerUtils::TimerTaskInfo::SetInterval(const uint64_t &interval)
46 {
47     this->interval = interval;
48 }
49 
SetWantAgent(std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> wantAgent)50 void AlarmTimerUtils::TimerTaskInfo::SetWantAgent(std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> wantAgent)
51 {
52     this->wantAgent = wantAgent;
53 }
54 
SetCallbackInfo(const std::function<void ()> & callBack)55 void AlarmTimerUtils::TimerTaskInfo::SetCallbackInfo(const std::function<void()> &callBack)
56 {
57     this->callBack_ = callBack;
58 }
59 
RegisterAlarm(int64_t time,const AlarmTimerCallback & callback)60 uint64_t AlarmTimerUtils::RegisterAlarm(int64_t time, const AlarmTimerCallback &callback)
61 {
62     auto timerInfo = std::make_shared<TimerTaskInfo>();
63     uint8_t timerType =
64         static_cast<uint8_t>(timerInfo->TIMER_TYPE_EXACT) | static_cast<uint8_t>(timerInfo->TIMER_TYPE_WAKEUP);
65     timerInfo->SetType(static_cast<int>(timerType));
66     timerInfo->SetRepeat(false);
67     timerInfo->SetCallbackInfo(callback);
68 
69     int64_t currentTime = TimeUtils::GetTimestamp();
70     if (currentTime >= time) {
71         ENGINE_LOGE("register time is outdated, register time %{public}" PRIu64 "", time);
72         return 0;
73     }
74     int64_t tiggerTimeMs = time * Constant::MILLESECONDS;
75     uint64_t timerId = RegisterTimer(tiggerTimeMs, timerInfo);
76     return timerId;
77 }
78 
RegisterRepeatAlarm(int64_t time,int64_t repeatTime,const AlarmTimerCallback & callback)79 uint64_t AlarmTimerUtils::RegisterRepeatAlarm(int64_t time, int64_t repeatTime, const AlarmTimerCallback &callback)
80 {
81     ENGINE_LOGI("register repeat timer, start time %{public}" PRId64 ", repeat %{public}" PRId64 "", time, repeatTime);
82     auto timerInfo = std::make_shared<TimerTaskInfo>();
83     uint8_t timerType = static_cast<uint8_t>(timerInfo->TIMER_TYPE_REALTIME);
84     timerInfo->SetType(static_cast<int>(timerType));
85     timerInfo->SetRepeat(true);
86     int64_t repeatTimeMs = repeatTime * Constant::MILLESECONDS;
87     timerInfo->SetInterval(repeatTimeMs);
88     timerInfo->SetCallbackInfo(callback);
89     uint64_t timerId = RegisterTimer(time, timerInfo);
90     return timerId;
91 }
92 
RegisterTimer(int64_t time,const std::shared_ptr<MiscServices::ITimerInfo> & timerInfo)93 uint64_t AlarmTimerUtils::RegisterTimer(int64_t time, const std::shared_ptr<MiscServices::ITimerInfo> &timerInfo)
94 {
95     sptr<MiscServices::TimeServiceClient> systemTimer = MiscServices::TimeServiceClient::GetInstance();
96     uint64_t timerId = systemTimer->CreateTimer(timerInfo);
97     if (timerId == 0) {
98         ENGINE_LOGE("CreateTimer failed, register tim %{public}" PRId64 "", time);
99         return 0;
100     }
101     // 将秒时间戳改为毫秒时间戳, alarm定时器不支持秒为单位的时间戳
102     if (!systemTimer->StartTimer(timerId, static_cast<uint64_t>(time))) {
103         ENGINE_LOGE("StartTimer failed, register time %{public}" PRId64"", time);
104         return 0;
105     }
106     ENGINE_LOGI("register timer success, register time %{public}" PRId64 ", timerId %{public}" PRIu64 "",
107         time, timerId);
108     return timerId;
109 }
110 
UnregisterAlarm(uint64_t timerId)111 void AlarmTimerUtils::UnregisterAlarm(uint64_t timerId)
112 {
113     ENGINE_LOGI("UnregisterAlarm, timerId %{public}" PRIu64 "", timerId);
114     sptr<MiscServices::TimeServiceClient> systemTimer = MiscServices::TimeServiceClient::GetInstance();
115     if (systemTimer != nullptr) {
116         systemTimer->DestroyTimer(timerId);
117     }
118 }
119 
GetSystemBootTime()120 uint64_t AlarmTimerUtils::GetSystemBootTime()
121 {
122     int64_t currentBootTime = 0;
123     int32_t ret = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs(currentBootTime);
124     if (ret != 0) {
125         ENGINE_LOGE("failed to get boot time");
126         return 0;
127     }
128     uint64_t bootTime = static_cast<uint64_t>(currentBootTime);
129     ENGINE_LOGI("GetSystemBootTime bootTime : %{public}" PRIu64 "", bootTime);
130     return bootTime;
131 }
132 } // namespace UpdateEngine
133 } // namespace OHOS
134