#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
#include <memory>
#include <optional>
#include "base/check_op.h"
#include "base/containers/contains.h"
#include "base/debug/stack_trace.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/memory/post_delayed_memory_reduction_task.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_visibility_state.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/policy_updater.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
namespace blink {
namespace scheduler {
namespace {
FrameScheduler;
constexpr double kDefaultBackgroundBudgetAsCPUFraction = …;
constexpr double kDefaultMaxBackgroundBudgetLevelInSeconds = …;
constexpr double kDefaultInitialBackgroundBudgetInSeconds = …;
constexpr double kDefaultMaxBackgroundThrottlingDelayInSeconds = …;
constexpr base::TimeDelta kThrottlingDelayAfterBackgrounding = …;
constexpr base::TimeDelta kDefaultDelayForBackgroundTabFreezing = …;
constexpr base::TimeDelta kThrottledWakeUpDuration = …;
constexpr base::TimeDelta
kTimeToInhibitIntensiveThrottlingOnTitleOrFaviconUpdate = …;
constexpr base::TimeDelta kDefaultDelayForTrackingIPCsPostedToCachedFrames = …;
struct BackgroundThrottlingSettings { … };
double GetDoubleParameterFromMap(const base::FieldTrialParams& settings,
const std::string& setting_name,
double default_value) { … }
std::optional<base::TimeDelta> DoubleToOptionalTime(double value) { … }
BackgroundThrottlingSettings GetBackgroundThrottlingSettings() { … }
base::TimeDelta GetDelayForBackgroundTabFreezing() { … }
base::TimeDelta GetTimeToDelayIPCTrackingWhileStoredInBackForwardCache() { … }
}
constexpr base::TimeDelta PageSchedulerImpl::kDefaultThrottledWakeUpInterval;
constexpr base::TimeDelta PageSchedulerImpl::kIntensiveThrottledWakeUpInterval;
PageSchedulerImpl::PageSchedulerImpl(
PageScheduler::Delegate* delegate,
AgentGroupSchedulerImpl& agent_group_scheduler)
: … { … }
PageSchedulerImpl::~PageSchedulerImpl() { … }
constexpr base::TimeDelta PageSchedulerImpl::kRecentAudioDelay;
void PageSchedulerImpl::SetPageVisible(bool page_visible) { … }
void PageSchedulerImpl::SetPageFrozen(bool frozen) { … }
void PageSchedulerImpl::SetPageFrozenImpl(
bool frozen,
PolicyUpdater& policy_updater,
base::MemoryReductionTaskContext called_from) { … }
void PageSchedulerImpl::SetPageBackForwardCached(
bool is_in_back_forward_cache) { … }
void PageSchedulerImpl::SetUpIPCTaskDetection() { … }
bool PageSchedulerImpl::IsMainFrameLocal() const { … }
bool PageSchedulerImpl::IsLoading() const { … }
bool PageSchedulerImpl::IsOrdinary() const { … }
void PageSchedulerImpl::SetIsMainFrameLocal(bool is_local) { … }
void PageSchedulerImpl::RegisterFrameSchedulerImpl(
FrameSchedulerImpl* frame_scheduler) { … }
std::unique_ptr<blink::FrameScheduler> PageSchedulerImpl::CreateFrameScheduler(
FrameScheduler::Delegate* delegate,
bool is_in_embedded_frame_tree,
FrameScheduler::FrameType frame_type) { … }
void PageSchedulerImpl::Unregister(FrameSchedulerImpl* frame_scheduler) { … }
void PageSchedulerImpl::AudioStateChanged(bool is_audio_playing) { … }
void PageSchedulerImpl::OnAudioSilent() { … }
bool PageSchedulerImpl::IsExemptFromBudgetBasedThrottling() const { … }
bool PageSchedulerImpl::OptedOutFromAggressiveThrottlingForTest() const { … }
bool PageSchedulerImpl::OptedOutFromAggressiveThrottling() const { … }
bool PageSchedulerImpl::RequestBeginMainFrameNotExpected(bool new_state) { … }
scoped_refptr<WidgetScheduler> PageSchedulerImpl::CreateWidgetScheduler() { … }
bool PageSchedulerImpl::IsAudioPlaying() const { … }
bool PageSchedulerImpl::IsPageVisible() const { … }
bool PageSchedulerImpl::IsFrozen() const { … }
bool PageSchedulerImpl::IsCPUTimeThrottled() const { … }
void PageSchedulerImpl::OnThrottlingStatusUpdated() { … }
void PageSchedulerImpl::OnVirtualTimeEnabled() { … }
void PageSchedulerImpl::OnTraceLogEnabled() { … }
bool PageSchedulerImpl::IsWaitingForMainFrameContentfulPaint() const { … }
bool PageSchedulerImpl::IsWaitingForMainFrameMeaningfulPaint() const { … }
bool PageSchedulerImpl::IsMainFrameLoading() const { … }
void PageSchedulerImpl::WriteIntoTrace(perfetto::TracedValue context,
base::TimeTicks now) const { … }
void PageSchedulerImpl::AddQueueToWakeUpBudgetPool(
MainThreadTaskQueue* task_queue,
WakeUpBudgetPool* wake_up_budget_pool,
base::LazyNow* lazy_now) { … }
void PageSchedulerImpl::RemoveQueueFromWakeUpBudgetPool(
MainThreadTaskQueue* task_queue,
base::LazyNow* lazy_now) { … }
WakeUpBudgetPool* PageSchedulerImpl::GetWakeUpBudgetPool(
MainThreadTaskQueue* task_queue,
FrameOriginType frame_origin_type,
ThrottlingType throttling_type) { … }
CPUTimeBudgetPool* PageSchedulerImpl::background_cpu_time_budget_pool() { … }
void PageSchedulerImpl::MaybeInitializeBackgroundCPUTimeBudgetPool(
base::LazyNow* lazy_now) { … }
void PageSchedulerImpl::MaybeInitializeWakeUpBudgetPools(
base::LazyNow* lazy_now) { … }
void PageSchedulerImpl::UpdatePolicyOnVisibilityChange(
PolicyUpdater& policy_updater) { … }
void PageSchedulerImpl::DoThrottleCPUTime() { … }
void PageSchedulerImpl::DoIntensivelyThrottleWakeUps() { … }
void PageSchedulerImpl::UpdateCPUTimeBudgetPool(base::LazyNow* lazy_now) { … }
void PageSchedulerImpl::OnTitleOrFaviconUpdated() { … }
void PageSchedulerImpl::ResetHadRecentTitleOrFaviconUpdate() { … }
base::TimeDelta PageSchedulerImpl::GetIntensiveWakeUpThrottlingInterval(
bool is_same_origin) const { … }
void PageSchedulerImpl::UpdateWakeUpBudgetPools(base::LazyNow* lazy_now) { … }
void PageSchedulerImpl::UpdatePolicy() { … }
size_t PageSchedulerImpl::FrameCount() const { … }
MainThreadSchedulerImpl* PageSchedulerImpl::GetMainThreadScheduler() const { … }
AgentGroupSchedulerImpl& PageSchedulerImpl::GetAgentGroupScheduler() { … }
VirtualTimeController* PageSchedulerImpl::GetVirtualTimeController() { … }
bool PageSchedulerImpl::IsBackgrounded() const { … }
FrameSchedulerImpl* PageSchedulerImpl::SelectFrameForUkmAttribution() { … }
bool PageSchedulerImpl::HasWakeUpBudgetPools() const { … }
void PageSchedulerImpl::UpdateFrozenState(
PolicyUpdater& policy_updater,
base::MemoryReductionTaskContext called_from) { … }
void PageSchedulerImpl::UpdateFrozenState(PolicyUpdater& policy_updater) { … }
std::array<WakeUpBudgetPool*, PageSchedulerImpl::kNumWakeUpBudgetPools>
PageSchedulerImpl::AllWakeUpBudgetPools() { … }
}
}