blob: 1db2064ea9189fce8529ec0d0dc704e8f281954f [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/btm/persistent_repeating_timer.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
namespace content {
PersistentRepeatingTimer::Storage::~Storage() = default;
PersistentRepeatingTimer::PersistentRepeatingTimer(
std::unique_ptr<Storage> time_storage,
base::TimeDelta delay,
base::RepeatingClosure task)
: storage_(std::move(time_storage)), delay_(delay), user_task_(task) {}
PersistentRepeatingTimer::~PersistentRepeatingTimer() = default;
void PersistentRepeatingTimer::Start() {
if (timer_.IsRunning()) {
return; // Already started.
}
storage_->GetLastFired(
base::BindOnce(&PersistentRepeatingTimer::StartWithLastFired,
weak_factory_.GetWeakPtr()));
}
void PersistentRepeatingTimer::StartWithLastFired(
std::optional<base::Time> last_fired) {
if (timer_.IsRunning()) {
return; // Already started.
}
const base::TimeDelta time_since_update =
base::Time::Now() - last_fired.value_or(base::Time());
if (time_since_update >= delay_) {
OnTimerFired();
} else {
timer_.Start(FROM_HERE, delay_ - time_since_update,
base::BindRepeating(&PersistentRepeatingTimer::OnTimerFired,
base::Unretained(this)));
}
DCHECK(timer_.IsRunning());
}
void PersistentRepeatingTimer::OnTimerFired() {
DCHECK(!timer_.IsRunning());
const base::Time now = base::Time::Now();
storage_->SetLastFired(now);
user_task_.Run();
StartWithLastFired(now);
}
} // namespace content