1cf69771bSopenharmony_ci/*
2cf69771bSopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd.
3cf69771bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cf69771bSopenharmony_ci * you may not use this file except in compliance with the License.
5cf69771bSopenharmony_ci * You may obtain a copy of the License at
6cf69771bSopenharmony_ci *
7cf69771bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cf69771bSopenharmony_ci *
9cf69771bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cf69771bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cf69771bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cf69771bSopenharmony_ci * See the License for the specific language governing permissions and
13cf69771bSopenharmony_ci * limitations under the License.
14cf69771bSopenharmony_ci */
15cf69771bSopenharmony_ci
16cf69771bSopenharmony_ci#include "timer_info.h"
17cf69771bSopenharmony_ci
18cf69771bSopenharmony_ci#include <cinttypes>
19cf69771bSopenharmony_ci
20cf69771bSopenharmony_ci#include "time_hilog.h"
21cf69771bSopenharmony_ci
22cf69771bSopenharmony_cinamespace OHOS {
23cf69771bSopenharmony_cinamespace MiscServices {
24cf69771bSopenharmony_cibool TimerInfo::operator==(const TimerInfo &other) const
25cf69771bSopenharmony_ci{
26cf69771bSopenharmony_ci    return this->id == other.id;
27cf69771bSopenharmony_ci}
28cf69771bSopenharmony_ci
29cf69771bSopenharmony_cibool TimerInfo::Matches(const std::string &packageName) const
30cf69771bSopenharmony_ci{
31cf69771bSopenharmony_ci    return false;
32cf69771bSopenharmony_ci}
33cf69771bSopenharmony_ci
34cf69771bSopenharmony_ciTimerInfo::TimerInfo(uint64_t _id, int _type,
35cf69771bSopenharmony_ci                     std::chrono::milliseconds _when,
36cf69771bSopenharmony_ci                     std::chrono::steady_clock::time_point _whenElapsed,
37cf69771bSopenharmony_ci                     std::chrono::milliseconds _windowLength,
38cf69771bSopenharmony_ci                     std::chrono::steady_clock::time_point _maxWhen,
39cf69771bSopenharmony_ci                     std::chrono::milliseconds _interval,
40cf69771bSopenharmony_ci                     std::function<int32_t (const uint64_t)> _callback,
41cf69771bSopenharmony_ci                     std::shared_ptr<OHOS::AbilityRuntime::WantAgent::WantAgent> _wantAgent,
42cf69771bSopenharmony_ci                     uint32_t _flags,
43cf69771bSopenharmony_ci                     int _uid,
44cf69771bSopenharmony_ci                     int _pid,
45cf69771bSopenharmony_ci                     const std::string &_bundleName)
46cf69771bSopenharmony_ci    : id {_id},
47cf69771bSopenharmony_ci      type {_type},
48cf69771bSopenharmony_ci      origWhen {_when},
49cf69771bSopenharmony_ci      wakeup {_type == ITimerManager::ELAPSED_REALTIME_WAKEUP || _type == ITimerManager::RTC_WAKEUP},
50cf69771bSopenharmony_ci      callback {std::move(_callback)},
51cf69771bSopenharmony_ci      wantAgent {_wantAgent},
52cf69771bSopenharmony_ci      flags {_flags},
53cf69771bSopenharmony_ci      uid {_uid},
54cf69771bSopenharmony_ci      pid {_pid},
55cf69771bSopenharmony_ci      when {_when},
56cf69771bSopenharmony_ci      windowLength {_windowLength},
57cf69771bSopenharmony_ci      whenElapsed {_whenElapsed},
58cf69771bSopenharmony_ci      maxWhenElapsed {_maxWhen},
59cf69771bSopenharmony_ci      repeatInterval {_interval},
60cf69771bSopenharmony_ci      bundleName {_bundleName}
61cf69771bSopenharmony_ci{
62cf69771bSopenharmony_ci    originWhenElapsed = _whenElapsed;
63cf69771bSopenharmony_ci    originMaxWhenElapsed = _maxWhen;
64cf69771bSopenharmony_ci}
65cf69771bSopenharmony_ci
66cf69771bSopenharmony_ci/* Please make sure that the first param is current boottime */
67cf69771bSopenharmony_cibool TimerInfo::UpdateWhenElapsedFromNow(std::chrono::steady_clock::time_point now, std::chrono::nanoseconds offset)
68cf69771bSopenharmony_ci{
69cf69771bSopenharmony_ci    TIME_HILOGD(TIME_MODULE_SERVICE, "Update whenElapsed, id=%{public}" PRId64 "", id);
70cf69771bSopenharmony_ci    auto oldWhenElapsed = whenElapsed;
71cf69771bSopenharmony_ci    whenElapsed = now + offset;
72cf69771bSopenharmony_ci    auto oldMaxWhenElapsed = maxWhenElapsed;
73cf69771bSopenharmony_ci    maxWhenElapsed = whenElapsed + windowLength;
74cf69771bSopenharmony_ci    std::chrono::milliseconds currentTime;
75cf69771bSopenharmony_ci    if (type == ITimerManager::RTC || type == ITimerManager::RTC_WAKEUP) {
76cf69771bSopenharmony_ci        currentTime =
77cf69771bSopenharmony_ci            std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
78cf69771bSopenharmony_ci    } else {
79cf69771bSopenharmony_ci        currentTime = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
80cf69771bSopenharmony_ci    }
81cf69771bSopenharmony_ci    auto offsetMill = std::chrono::duration_cast<std::chrono::milliseconds>(offset);
82cf69771bSopenharmony_ci    when = currentTime + offsetMill;
83cf69771bSopenharmony_ci    return (oldWhenElapsed != whenElapsed) || (oldMaxWhenElapsed != maxWhenElapsed);
84cf69771bSopenharmony_ci}
85cf69771bSopenharmony_ci
86cf69771bSopenharmony_cibool TimerInfo::AdjustTimer(const std::chrono::steady_clock::time_point &now, const uint32_t interval)
87cf69771bSopenharmony_ci{
88cf69771bSopenharmony_ci    auto oldWhenElapsed = whenElapsed;
89cf69771bSopenharmony_ci    auto oldMaxWhenElapsed = maxWhenElapsed;
90cf69771bSopenharmony_ci    std::chrono::duration<int, std::ratio<1, HALF_SECEND>> halfIntervalSec(interval);
91cf69771bSopenharmony_ci    std::chrono::duration<int, std::ratio<1, 1>> intervalSec(interval);
92cf69771bSopenharmony_ci    auto oldTimeSec = std::chrono::duration_cast<std::chrono::seconds>(whenElapsed.time_since_epoch());
93cf69771bSopenharmony_ci    auto timeSec = ((oldTimeSec + halfIntervalSec) / intervalSec) * intervalSec;
94cf69771bSopenharmony_ci    whenElapsed = std::chrono::steady_clock::time_point(timeSec);
95cf69771bSopenharmony_ci    if (windowLength == std::chrono::milliseconds::zero()) {
96cf69771bSopenharmony_ci        maxWhenElapsed = whenElapsed;
97cf69771bSopenharmony_ci    } else {
98cf69771bSopenharmony_ci        auto oldMaxTimeSec = std::chrono::duration_cast<std::chrono::seconds>(maxWhenElapsed.time_since_epoch());
99cf69771bSopenharmony_ci        auto maxTimeSec = ((oldMaxTimeSec + halfIntervalSec) / intervalSec) * intervalSec;
100cf69771bSopenharmony_ci        maxWhenElapsed = std::chrono::steady_clock::time_point(maxTimeSec);
101cf69771bSopenharmony_ci    }
102cf69771bSopenharmony_ci    if (whenElapsed < now) {
103cf69771bSopenharmony_ci        whenElapsed += std::chrono::duration_cast<std::chrono::milliseconds>(intervalSec);
104cf69771bSopenharmony_ci    }
105cf69771bSopenharmony_ci    if (maxWhenElapsed < now) {
106cf69771bSopenharmony_ci        maxWhenElapsed += std::chrono::duration_cast<std::chrono::milliseconds>(intervalSec);
107cf69771bSopenharmony_ci    }
108cf69771bSopenharmony_ci    auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(
109cf69771bSopenharmony_ci        whenElapsed.time_since_epoch() - oldWhenElapsed.time_since_epoch());
110cf69771bSopenharmony_ci    when = when + delta;
111cf69771bSopenharmony_ci    return (oldWhenElapsed != whenElapsed) || (oldMaxWhenElapsed != maxWhenElapsed);
112cf69771bSopenharmony_ci}
113cf69771bSopenharmony_ci
114cf69771bSopenharmony_cibool TimerInfo::RestoreAdjustTimer()
115cf69771bSopenharmony_ci{
116cf69771bSopenharmony_ci    auto oldWhenElapsed = whenElapsed;
117cf69771bSopenharmony_ci    auto oldMaxWhenElapsed = maxWhenElapsed;
118cf69771bSopenharmony_ci    whenElapsed = originWhenElapsed;
119cf69771bSopenharmony_ci    maxWhenElapsed = originMaxWhenElapsed;
120cf69771bSopenharmony_ci    auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(
121cf69771bSopenharmony_ci        whenElapsed.time_since_epoch() - oldWhenElapsed.time_since_epoch());
122cf69771bSopenharmony_ci    when = when + delta;
123cf69771bSopenharmony_ci    return (oldWhenElapsed != whenElapsed) || (oldMaxWhenElapsed != maxWhenElapsed);
124cf69771bSopenharmony_ci}
125cf69771bSopenharmony_ci} // MiscServices
126cf69771bSopenharmony_ci} // OHOS