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     bool didRemove = false;
85     auto newStart = std::chrono::steady_clock::time_point::min();
86     auto newEnd = std::chrono::steady_clock::time_point::max();
87     uint32_t newFlags = 0;
88     for (auto it = alarms_.begin(); it != alarms_.end();) {
89         auto alarm = *it;
90         if (predicate(*alarm)) {
91             it = alarms_.erase(it);
92             didRemove = true;
93         } else {
94             if (alarm->whenElapsed > newStart) {
95                 newStart = alarm->whenElapsed;
96             }
97             if (alarm->maxWhenElapsed < newEnd) {
98                 newEnd = alarm->maxWhenElapsed;
99             }
100             newFlags |= alarm->flags;
101             ++it;
102         }
103     }
104     if (didRemove) {
105         start_ = newStart;
106         end_ = newEnd;
107         flags_ = newFlags;
108     }
109     return didRemove;
110 }
111 
HasPackage(const std::string & package_name)112 bool Batch::HasPackage(const std::string &package_name)
113 {
114     return std::find_if(alarms_.begin(),
115         alarms_.end(),
116         [package_name] (const std::shared_ptr<TimerInfo> &alarm) {
117             return alarm->Matches(package_name);
118         }) != alarms_.end();
119 }
120 
HasWakeups() const121 bool Batch::HasWakeups() const
122 {
123     return std::any_of(alarms_.begin(), alarms_.end(),
124         [] (const std::shared_ptr<TimerInfo> &item) {
125             return (static_cast<uint32_t>(item->type) & TYPE_NONWAKEUP_MASK) == 0;
126         });
127 }
128 
GetStart() const129 std::chrono::steady_clock::time_point Batch::GetStart() const
130 {
131     return start_;
132 }
133 
GetEnd() const134 std::chrono::steady_clock::time_point Batch::GetEnd() const
135 {
136     return end_;
137 }
138 
GetFlags() const139 uint32_t Batch::GetFlags() const
140 {
141     return flags_;
142 }
143 } // MiscServices
144 } // OHOS