blob: 4ec868274b7aa90f962031ae0c2f102d61c964f2 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_RECLAIMABLE_CODEC_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_RECLAIMABLE_CODEC_H_
#include "base/feature_list.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/timer.h"
#include <memory>
namespace base {
class TickClock;
} // namespace base
namespace blink {
class DOMException;
extern const MODULES_EXPORT base::Feature kReclaimInactiveWebCodecs;
extern const MODULES_EXPORT base::Feature kOnlyReclaimBackgroundWebCodecs;
class MODULES_EXPORT ReclaimableCodec : public GarbageCollectedMixin {
public:
explicit ReclaimableCodec(ExecutionContext*);
// GarbageCollectedMixin override.
void Trace(Visitor*) const override;
bool IsReclamationTimerActiveForTesting() {
return activity_timer_.IsActive();
}
bool is_backgrounded_for_testing() { return is_backgrounded_; }
void SimulateCodecReclaimedForTesting();
void SimulateActivityTimerFiredForTesting();
void SimulateLifecycleStateForTesting(scheduler::SchedulingLifecycleState);
void set_tick_clock_for_testing(const base::TickClock* clock) {
tick_clock_ = clock;
}
// Use 1.5 minutes since some RDP clients are only ticking at 1 FPM.
static constexpr base::TimeDelta kInactivityReclamationThreshold =
base::Seconds(90);
static constexpr base::TimeDelta kTimerPeriod =
kInactivityReclamationThreshold / 2;
// Notified when throttling state is changed. May be called consecutively
// with the same value.
void OnLifecycleStateChanged(scheduler::SchedulingLifecycleState);
protected:
// Pushes back the time at which |this| can be reclaimed due to inactivity.
// Starts a inactivity reclamation timer, if it isn't already running.
void MarkCodecActive();
// Called when a codec should no longer be reclaimed, such as when it is not
// holding on to any resources.
//
// Calling MarkCodecActive() will automatically unpause reclamation.
void PauseCodecReclamation();
virtual void OnCodecReclaimed(DOMException*) = 0;
private:
void ActivityTimerFired(TimerBase*);
void StartTimer();
void PauseCodecReclamationInternal();
// This is used to make sure that there are two consecutive ticks of the
// timer, before we reclaim for inactivity. This prevents immediately
// reclaiming otherwise active codecs, right after a page suspended/resumed.
bool last_tick_was_inactive_ = false;
const base::TickClock* tick_clock_;
base::TimeTicks last_activity_;
HeapTaskRunnerTimer<ReclaimableCodec> activity_timer_;
// True iff document.visibilityState of the associated page is "hidden".
// This includes being in bg of tab strip, minimized, or (depending on OS)
// covered by other windows.
bool is_backgrounded_ = false;
// True if PauseCodecReclamation() has been called more recently than
// MarkCodecActive(), or if the codec is already reclaimed.
bool is_reclamation_paused_ = true;
// Handle to unhook from FrameOrWorkerScheduler upon destruction.
std::unique_ptr<FrameOrWorkerScheduler::LifecycleObserverHandle>
observer_handle_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_AUDIO_DATA_H_