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
16 #include "timer_info.h"
17
18 #include <cinttypes>
19
20 namespace OHOS {
21 namespace MiscServices {
22 static constexpr uint32_t HALF_SECEND = 2;
operator ==(const TimerInfo & other) const23 bool TimerInfo::operator==(const TimerInfo &other) const
24 {
25 return this->id == other.id;
26 }
27
Matches(const std::string & packageName) const28 bool TimerInfo::Matches(const std::string &packageName) const
29 {
30 return false;
31 }
32
TimerInfo(std::string _name,uint64_t _id,int _type,std::chrono::milliseconds _when,std::chrono::steady_clock::time_point _whenElapsed,std::chrono::milliseconds _windowLength,std::chrono::steady_clock::time_point _maxWhen,std::chrono::milliseconds _interval,std::function<int32_t (const uint64_t)> _callback,std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> _wantAgent,uint32_t _flags,bool _autoRestore,int _uid,int _pid,const std::string & _bundleName)33 TimerInfo::TimerInfo(std::string _name, uint64_t _id, int _type,
34 std::chrono::milliseconds _when,
35 std::chrono::steady_clock::time_point _whenElapsed,
36 std::chrono::milliseconds _windowLength,
37 std::chrono::steady_clock::time_point _maxWhen,
38 std::chrono::milliseconds _interval,
39 std::function<int32_t (const uint64_t)> _callback,
40 std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> _wantAgent,
41 uint32_t _flags,
42 bool _autoRestore,
43 int _uid,
44 int _pid,
45 const std::string &_bundleName)
46 : name {_name},
47 id {_id},
48 type {_type},
49 origWhen {_when},
50 wakeup {_type == ITimerManager::ELAPSED_REALTIME_WAKEUP || _type == ITimerManager::RTC_WAKEUP},
51 autoRestore {_autoRestore},
52 callback {std::move(_callback)},
53 wantAgent {_wantAgent},
54 flags {_flags},
55 uid {_uid},
56 pid {_pid},
57 when {_when},
58 windowLength {_windowLength},
59 whenElapsed {_whenElapsed},
60 maxWhenElapsed {_maxWhen},
61 repeatInterval {_interval},
62 bundleName {_bundleName}
63 {
64 originWhenElapsed = _whenElapsed;
65 originMaxWhenElapsed = _maxWhen;
66 originProxyWhenElapsed = _whenElapsed;
67 originProxyMaxWhenElapsed = _maxWhen;
68 }
69
70 /* Please make sure that the first param is current boottime */
UpdateWhenElapsedFromNow(std::chrono::steady_clock::time_point now,std::chrono::nanoseconds offset)71 bool TimerInfo::UpdateWhenElapsedFromNow(std::chrono::steady_clock::time_point now, std::chrono::nanoseconds offset)
72 {
73 TIME_HILOGD(TIME_MODULE_SERVICE, "Update whenElapsed, id=%{public}" PRId64 "", id);
74 auto oldWhenElapsed = whenElapsed;
75 whenElapsed = now + offset;
76 auto oldMaxWhenElapsed = maxWhenElapsed;
77 maxWhenElapsed = whenElapsed + windowLength;
78 std::chrono::milliseconds currentTime;
79 if (type == ITimerManager::RTC || type == ITimerManager::RTC_WAKEUP) {
80 currentTime =
81 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
82 } else {
83 currentTime = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
84 }
85 auto offsetMill = std::chrono::duration_cast<std::chrono::milliseconds>(offset);
86 when = currentTime + offsetMill;
87 return (oldWhenElapsed != whenElapsed) || (oldMaxWhenElapsed != maxWhenElapsed);
88 }
89
AdjustTimer(const std::chrono::steady_clock::time_point & now,const uint32_t interval,const uint32_t delta)90 bool TimerInfo::AdjustTimer(const std::chrono::steady_clock::time_point &now,
91 const uint32_t interval, const uint32_t delta)
92 {
93 auto oldWhenElapsed = whenElapsed;
94 auto oldMaxWhenElapsed = maxWhenElapsed;
95 std::chrono::duration<int, std::ratio<1, HALF_SECEND>> halfIntervalSec(interval);
96 std::chrono::duration<int, std::ratio<1, 1>> intervalSec(interval);
97 std::chrono::duration<int, std::ratio<1, 1>> deltaSec(delta);
98 auto oldTimeSec = std::chrono::duration_cast<std::chrono::seconds>(whenElapsed.time_since_epoch());
99 auto timeSec = ((oldTimeSec + halfIntervalSec) / intervalSec) * intervalSec + deltaSec;
100 whenElapsed = std::chrono::steady_clock::time_point(timeSec);
101 if (windowLength == std::chrono::milliseconds::zero()) {
102 maxWhenElapsed = whenElapsed;
103 } else {
104 auto oldMaxTimeSec = std::chrono::duration_cast<std::chrono::seconds>(maxWhenElapsed.time_since_epoch());
105 auto maxTimeSec = ((oldMaxTimeSec + halfIntervalSec) / intervalSec) * intervalSec + deltaSec;
106 maxWhenElapsed = std::chrono::steady_clock::time_point(maxTimeSec);
107 }
108 if (whenElapsed < now) {
109 whenElapsed += std::chrono::duration_cast<std::chrono::milliseconds>(intervalSec);
110 }
111 if (maxWhenElapsed < now) {
112 maxWhenElapsed += std::chrono::duration_cast<std::chrono::milliseconds>(intervalSec);
113 }
114 auto elapsedDelta = std::chrono::duration_cast<std::chrono::milliseconds>(
115 whenElapsed.time_since_epoch() - oldWhenElapsed.time_since_epoch());
116 when = when + elapsedDelta;
117 return (oldWhenElapsed != whenElapsed) || (oldMaxWhenElapsed != maxWhenElapsed);
118 }
119
RestoreAdjustTimer()120 bool TimerInfo::RestoreAdjustTimer()
121 {
122 auto oldWhenElapsed = whenElapsed;
123 auto oldMaxWhenElapsed = maxWhenElapsed;
124 whenElapsed = originWhenElapsed;
125 maxWhenElapsed = originMaxWhenElapsed;
126 auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(
127 whenElapsed.time_since_epoch() - oldWhenElapsed.time_since_epoch());
128 when = when + delta;
129 return (oldWhenElapsed != whenElapsed) || (oldMaxWhenElapsed != maxWhenElapsed);
130 }
131 } // MiscServices
132 } // OHOS