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 "batch.h"
17
18 namespace OHOS {
19 namespace MiscServices {
20 const auto TYPE_NONWAKEUP_MASK = 0x1;
21
Batch()22 Batch::Batch()
23 : start_ {std::chrono::steady_clock::time_point::min()},
24 end_ {std::chrono::steady_clock::time_point::max()},
25 flags_ {0}
26 {
27 }
28
Batch(const TimerInfo & seed)29 Batch::Batch(const TimerInfo &seed)
30 : start_ {seed.whenElapsed},
31 end_ {seed.maxWhenElapsed},
32 flags_ {seed.flags},
33 alarms_ {std::make_shared<TimerInfo>(seed)}
34 {
35 }
36
Size() const37 size_t Batch::Size() const
38 {
39 return alarms_.size();
40 }
41
Get(size_t index) const42 std::shared_ptr<TimerInfo> Batch::Get(size_t index) const
43 {
44 return (index >= alarms_.size()) ? nullptr : alarms_.at(index);
45 }
46
CanHold(std::chrono::steady_clock::time_point whenElapsed,std::chrono::steady_clock::time_point maxWhen) const47 bool Batch::CanHold(std::chrono::steady_clock::time_point whenElapsed,
48 std::chrono::steady_clock::time_point maxWhen) const
49 {
50 return (end_ > whenElapsed) && (start_ <= maxWhen);
51 }
52
Add(const std::shared_ptr<TimerInfo> & alarm)53 bool Batch::Add(const std::shared_ptr<TimerInfo> &alarm)
54 {
55 bool new_start = false;
56 auto it = std::upper_bound(alarms_.begin(),
57 alarms_.end(),
58 alarm,
59 [](const std::shared_ptr<TimerInfo> &first, const std::shared_ptr<TimerInfo> &second) {
60 return first->whenElapsed < second->whenElapsed;
61 });
62 alarms_.insert(it, alarm); // 根据Alarm.when_elapsed从小到大排列
63
64 if (alarm->whenElapsed > start_) {
65 start_ = alarm->whenElapsed;
66 new_start = true;
67 }
68
69 if (alarm->maxWhenElapsed < end_) {
70 end_ = alarm->maxWhenElapsed;
71 }
72
73 flags_ |= alarm->flags;
74 return new_start;
75 }
76
Remove(const TimerInfo & alarm)77 bool Batch::Remove(const TimerInfo &alarm)
78 {
79 return Remove([alarm] (const TimerInfo &a) { return a == alarm; });
80 }
81
Remove(std::function<bool (const TimerInfo &)> predicate)82 bool Batch::Remove(std::function<bool (const TimerInfo &)> predicate)
83 {
84 TIME_HILOGD(TIME_MODULE_SERVICE, "start");
85 bool didRemove = false;
86 auto newStart = std::chrono::steady_clock::time_point::min();
87 auto newEnd = std::chrono::steady_clock::time_point::max();
88 uint32_t newFlags = 0;
89 for (auto it = alarms_.begin(); it != alarms_.end();) {
90 auto alarm = *it;
91 TIME_HILOGD(TIME_MODULE_SERVICE, "looper");
92 if (predicate(*alarm)) {
93 TIME_HILOGD(TIME_MODULE_SERVICE, "erase");
94 it = alarms_.erase(it);
95 didRemove = true;
96 } else {
97 if (alarm->whenElapsed > newStart) {
98 newStart = alarm->whenElapsed;
99 }
100 if (alarm->maxWhenElapsed < newEnd) {
101 newEnd = alarm->maxWhenElapsed;
102 }
103 newFlags |= alarm->flags;
104 ++it;
105 }
106 }
107 TIME_HILOGD(TIME_MODULE_SERVICE, "end");
108 if (didRemove) {
109 start_ = newStart;
110 end_ = newEnd;
111 flags_ = newFlags;
112 }
113 return didRemove;
114 }
115
HasPackage(const std::string & package_name)116 bool Batch::HasPackage(const std::string &package_name)
117 {
118 return std::find_if(alarms_.begin(),
119 alarms_.end(),
120 [package_name] (const std::shared_ptr<TimerInfo> &alarm) {
121 return alarm->Matches(package_name);
122 }) != alarms_.end();
123 }
124
HasWakeups() const125 bool Batch::HasWakeups() const
126 {
127 return std::any_of(alarms_.begin(), alarms_.end(),
128 [] (const std::shared_ptr<TimerInfo> &item) {
129 return (static_cast<uint32_t>(item->type) & TYPE_NONWAKEUP_MASK) == 0;
130 });
131 }
132
GetStart() const133 std::chrono::steady_clock::time_point Batch::GetStart() const
134 {
135 return start_;
136 }
137
GetEnd() const138 std::chrono::steady_clock::time_point Batch::GetEnd() const
139 {
140 return end_;
141 }
142
GetFlags() const143 uint32_t Batch::GetFlags() const
144 {
145 return flags_;
146 }
147 } // MiscServices
148 } // OHOS