* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "batch.h"
namespace OHOS {
namespace MiscServices {
constexpr auto TYPE_NONWAKEUP_MASK = 0x1;
Batch::Batch()
: start_ {std::chrono::steady_clock::time_point::min()},
end_ {std::chrono::steady_clock::time_point::max()},
flags_ {0}
{
}
Batch::Batch(const TimerInfo &seed)
: start_ {seed.whenElapsed},
end_ {seed.maxWhenElapsed},
flags_ {seed.flags},
alarms_ {std::make_shared<TimerInfo>(seed)}
{
}
size_t Batch::Size() const
{
return alarms_.size();
}
std::shared_ptr<TimerInfo> Batch::Get(size_t index) const
{
return (index >= alarms_.size()) ? nullptr : alarms_.at(index);
}
bool Batch::CanHold(std::chrono::steady_clock::time_point whenElapsed,
std::chrono::steady_clock::time_point maxWhen) const
{
return (end_ > whenElapsed) && (start_ <= maxWhen);
}
bool Batch::Add(const std::shared_ptr<TimerInfo> &alarm)
{
bool new_start = false;
auto it = std::upper_bound(alarms_.begin(),
alarms_.end(),
alarm,
[](const std::shared_ptr<TimerInfo> &first, const std::shared_ptr<TimerInfo> &second) {
return first->whenElapsed < second->whenElapsed;
});
alarms_.insert(it, alarm);
if (alarm->whenElapsed > start_) {
start_ = alarm->whenElapsed;
new_start = true;
}
if (alarm->maxWhenElapsed < end_) {
end_ = alarm->maxWhenElapsed;
}
flags_ |= alarm->flags;
return new_start;
}
bool Batch::Remove(const TimerInfo &alarm)
{
return Remove([alarm] (const TimerInfo &a) { return a == alarm; });
}
bool Batch::Remove(std::function<bool (const TimerInfo &)> predicate)
{
bool didRemove = false;
auto newStart = std::chrono::steady_clock::time_point::min();
auto newEnd = std::chrono::steady_clock::time_point::max();
uint32_t newFlags = 0;
for (auto it = alarms_.begin(); it != alarms_.end();) {
auto alarm = *it;
if (predicate(*alarm)) {
it = alarms_.erase(it);
didRemove = true;
} else {
if (alarm->whenElapsed > newStart) {
newStart = alarm->whenElapsed;
}
if (alarm->maxWhenElapsed < newEnd) {
newEnd = alarm->maxWhenElapsed;
}
newFlags |= alarm->flags;
++it;
}
}
if (didRemove) {
start_ = newStart;
end_ = newEnd;
flags_ = newFlags;
}
return didRemove;
}
bool Batch::HasPackage(const std::string &package_name)
{
return std::find_if(alarms_.begin(),
alarms_.end(),
[package_name] (const std::shared_ptr<TimerInfo> &alarm) {
return alarm->Matches(package_name);
}) != alarms_.end();
}
bool Batch::HasWakeups() const
{
return std::any_of(alarms_.begin(), alarms_.end(),
[] (const std::shared_ptr<TimerInfo> &item) {
return (static_cast<uint32_t>(item->type) & TYPE_NONWAKEUP_MASK) == 0;
});
}
std::chrono::steady_clock::time_point Batch::GetStart() const
{
return start_;
}
std::chrono::steady_clock::time_point Batch::GetEnd() const
{
return end_;
}
uint32_t Batch::GetFlags() const
{
return flags_;
}
}
}