#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/field_trial_params.h"
#include "base/run_loop.h"
#include "base/task/common/task_annotator.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.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_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_queue_type.h"
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/test/web_scheduling_test_helper.h"
TaskQueue;
UnorderedElementsAre;
namespace blink {
namespace scheduler {
namespace frame_scheduler_impl_unittest {
FeatureHandle;
PrioritisationType;
Return;
namespace {
constexpr base::TimeDelta kDefaultThrottledWakeUpInterval = …;
constexpr base::TimeDelta kIntensiveThrottledWakeUpInterval = …;
constexpr auto kShortDelay = …;
std::unique_ptr<PageSchedulerImpl> CreatePageScheduler(
PageScheduler::Delegate* page_scheduler_delegate,
MainThreadSchedulerImpl* scheduler,
AgentGroupScheduler& agent_group_scheduler) { … }
std::unique_ptr<FrameSchedulerImpl> CreateFrameScheduler(
PageSchedulerImpl* page_scheduler,
FrameScheduler::Delegate* delegate,
bool is_in_embedded_frame_tree,
FrameScheduler::FrameType frame_type) { … }
void RecordRunTime(std::vector<base::TimeTicks>* run_times) { … }
class TestObject { … };
}
constexpr TaskType kAllFrameTaskTypes[] = …;
static_assert …;
void AppendToVectorTestTask(Vector<String>* vector, String value) { … }
class FrameSchedulerDelegateForTesting : public FrameScheduler::Delegate { … };
MATCHER(BlockingDetailsHasCCNS, "Blocking details has CCNS.") { … }
MATCHER_P(BlockingDetailsHasWebSocket,
handle,
"BlockingDetails has WebSocket.") { … }
MATCHER(BlockingDetailsIsEmpty, "BlockingDetails is empty.") { … }
class FrameSchedulerImplTest : public testing::Test { … };
class FrameSchedulerImplStopInBackgroundDisabledTest
: public FrameSchedulerImplTest,
public ::testing::WithParamInterface<TaskType> { … };
namespace {
class MockLifecycleObserver { … };
void IncrementCounter(int* counter) { … }
void RunTaskOfLength(base::test::TaskEnvironment* task_environment,
base::TimeDelta length) { … }
class FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase
: public FrameSchedulerImplTest { … };
struct IntensiveWakeUpThrottlingTestParam { … };
class FrameSchedulerImplTestWithIntensiveWakeUpThrottling
: public FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase,
public ::testing::WithParamInterface<IntensiveWakeUpThrottlingTestParam> { … };
class FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride
: public FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase { … };
}
TEST_F(FrameSchedulerImplTest, PageVisible) { … }
TEST_F(FrameSchedulerImplTest, PageHidden_ExplicitInit) { … }
TEST_F(FrameSchedulerImplTest, PageHidden_LazyInit) { … }
TEST_F(FrameSchedulerImplTest, PageHiddenThenVisible_ExplicitInit) { … }
TEST_F(FrameSchedulerImplTest,
FrameHiddenThenVisible_CrossOrigin_ExplicitInit) { … }
TEST_F(FrameSchedulerImplTest, FrameHidden_CrossOrigin_LazyInit) { … }
TEST_F(FrameSchedulerImplTest, FrameHidden_SameOrigin_ExplicitInit) { … }
TEST_F(FrameSchedulerImplTest, FrameHidden_SameOrigin_LazyInit) { … }
TEST_F(FrameSchedulerImplTest, FrameVisible_CrossOrigin_ExplicitInit) { … }
TEST_F(FrameSchedulerImplTest, FrameVisible_CrossOrigin_LazyInit) { … }
TEST_F(FrameSchedulerImplTest, PauseAndResume) { … }
TEST_F(FrameSchedulerImplTest, PauseAndResumeForCooperativeScheduling) { … }
namespace {
void RePostTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::TimeDelta delay,
int* num_remaining_tasks) { … }
}
TEST_P(FrameSchedulerImplStopInBackgroundDisabledTest,
DISABLED_ThrottledTaskExecution) { … }
INSTANTIATE_TEST_SUITE_P(…);
TEST_F(FrameSchedulerImplTest, FreezeForegroundOnlyTasks) { … }
TEST_F(FrameSchedulerImplTest, PageFreezeAndUnfreeze) { … }
TEST_F(FrameSchedulerImplTest, PageFreezeAndPageVisible) { … }
TEST_F(FrameSchedulerImplTest, PagePostsCpuTasks) { … }
TEST_F(FrameSchedulerImplTest, FramePostsCpuTasksThroughReloadRenavigate) { … }
class FrameSchedulerImplTestWithUnfreezableLoading
: public FrameSchedulerImplTest { … };
TEST_F(FrameSchedulerImplTestWithUnfreezableLoading,
LoadingTasksKeepRunningWhenFrozen) { … }
TEST_F(FrameSchedulerImplTest, LifecycleObserver) { … }
TEST_F(FrameSchedulerImplTest, DefaultSchedulingLifecycleState) { … }
TEST_F(FrameSchedulerImplTest, SubesourceLoadingPaused) { … }
TEST_F(FrameSchedulerImplTest, LogIpcsPostedToFramesInBackForwardCache) { … }
TEST_F(FrameSchedulerImplTest,
LogIpcsFromMultipleThreadsPostedToFramesInBackForwardCache) { … }
TEST_F(FrameSchedulerImplTest, HighestPriorityInputBlockingTaskQueue) { … }
TEST_F(FrameSchedulerImplTest, RenderBlockingRenderBlockingLoading) { … }
TEST_F(FrameSchedulerImplTest, TaskTypeToTaskQueueMapping) { … }
TEST_F(FrameSchedulerImplTest, ThrottledTaskTypes) { … }
class FrameSchedulerImplDatabaseAccessWithoutHighPriority
: public FrameSchedulerImplTest { … };
TEST_F(FrameSchedulerImplDatabaseAccessWithoutHighPriority, QueueTraits) { … }
class FrameSchedulerImplDatabaseAccessWithHighPriority
: public FrameSchedulerImplTest { … };
TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, QueueTraits) { … }
TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, RunOrder) { … }
TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority,
NormalPriorityInBackground) { … }
TEST_F(FrameSchedulerImplTest, ContentCaptureHasIdleTaskQueue) { … }
TEST_F(FrameSchedulerImplTest, ComputePriorityForDetachedFrame) { … }
class FrameSchedulerImplLowPriorityAsyncScriptExecutionTest
: public FrameSchedulerImplTest,
public testing::WithParamInterface<std::string> { … };
INSTANTIATE_TEST_SUITE_P(…);
TEST_P(FrameSchedulerImplLowPriorityAsyncScriptExecutionTest,
LowPriorityScriptExecutionHasBestEffortPriority) { … }
TEST_F(FrameSchedulerImplTest, BackForwardCacheOptOut) { … }
TEST_F(FrameSchedulerImplTest, BackForwardCacheOptOut_FrameNavigated) { … }
TEST_F(FrameSchedulerImplTest, FeatureUpload) { … }
TEST_F(FrameSchedulerImplTest, FeatureUpload_FrameDestruction) { … }
TEST_F(FrameSchedulerImplTest, TasksRunAfterDetach) { … }
TEST_F(FrameSchedulerImplTest, DetachedWebSchedulingTaskQueue) { … }
class WebSchedulingTaskQueueTest : public FrameSchedulerImplTest,
public WebSchedulingTestHelper::Delegate { … };
TEST_F(WebSchedulingTaskQueueTest, TasksRunInPriorityOrder) { … }
TEST_F(WebSchedulingTaskQueueTest, DynamicTaskPriorityOrder) { … }
TEST_F(WebSchedulingTaskQueueTest, DynamicTaskPriorityOrderDelayedTasks) { … }
TEST_F(WebSchedulingTaskQueueTest, TasksAndContinuations) { … }
TEST_F(WebSchedulingTaskQueueTest, DynamicPriorityContinuations) { … }
TEST_F(WebSchedulingTaskQueueTest, WebScheduingAndNonWebScheduingTasks) { … }
TEST_F(FrameSchedulerImplTest, ThrottledJSTimerTasksRunTime) { … }
namespace {
class MockMainThreadScheduler : public MainThreadSchedulerImpl { … };
}
TEST_F(FrameSchedulerImplTest, ReportFMPAndFCPForMainFrames) { … }
TEST_F(FrameSchedulerImplTest, DontReportFMPAndFCPForSubframes) { … }
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
TaskExecutionSameOriginFrame) { … }
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
TaskExecutionCrossOriginFrame) { … }
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
ManySameOriginFrames) { … }
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
TaskExecutionPageLoadingWhenHidden) { … }
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
AggressiveThrottlingOptOut) { … }
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
FrameChangesOriginType) { … }
INSTANTIATE_TEST_SUITE_P(…);
TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride,
PolicyForceEnable) { … }
TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride,
PolicyForceDisable) { … }
class FrameSchedulerImplTestQuickIntensiveWakeUpThrottlingEnabled
: public FrameSchedulerImplTest { … };
TEST_F(FrameSchedulerImplTestQuickIntensiveWakeUpThrottlingEnabled,
LoadingPageGracePeriod) { … }
TEST_F(FrameSchedulerImplTestQuickIntensiveWakeUpThrottlingEnabled,
LoadedPageGracePeriod) { … }
TEST_F(FrameSchedulerImplTest, ImmediateWebSchedulingTasksAreNotThrottled) { … }
TEST_F(FrameSchedulerImplTest, PostMessageForwardingHasVeryHighPriority) { … }
class FrameSchedulerImplThrottleUnimportantFrameTimersEnabledTest
: public FrameSchedulerImplTest { … };
TEST_F(FrameSchedulerImplThrottleUnimportantFrameTimersEnabledTest,
VisibleSizeChange_CrossOrigin_ExplicitInit) { … }
TEST_F(FrameSchedulerImplThrottleUnimportantFrameTimersEnabledTest,
UserActivationChange_CrossOrigin_ExplicitInit) { … }
TEST_F(FrameSchedulerImplThrottleUnimportantFrameTimersEnabledTest,
UnimportantFrameThrottling) { … }
TEST_F(FrameSchedulerImplThrottleUnimportantFrameTimersEnabledTest,
HiddenCrossOriginFrameThrottling) { … }
TEST_F(FrameSchedulerImplThrottleUnimportantFrameTimersEnabledTest,
BackgroundPageTimerThrottling) { … }
TEST_F(FrameSchedulerImplThrottleUnimportantFrameTimersEnabledTest,
LargeCrossOriginFrameNoThrottling) { … }
TEST_F(FrameSchedulerImplThrottleUnimportantFrameTimersEnabledTest,
UserActivatedCrossOriginFrameNoThrottling) { … }
class FrameSchedulerImplNoThrottlingVisibleAgentTest
: public FrameSchedulerImplTest,
public testing::WithParamInterface<bool> { … };
class FrameSchedulerImplNoThrottlingVisibleAgentAndThrottleUnimportantTest
: public FrameSchedulerImplNoThrottlingVisibleAgentTest { … };
TEST_P(FrameSchedulerImplNoThrottlingVisibleAgentTest, FrameVisibilityChange) { … }
TEST_P(FrameSchedulerImplNoThrottlingVisibleAgentTest, PageVisibilityChange) { … }
TEST_P(FrameSchedulerImplNoThrottlingVisibleAgentTest,
SameAgentFramePageVisibilityChange) { … }
TEST_P(FrameSchedulerImplNoThrottlingVisibleAgentTest, VisibleFrameDeletion) { … }
TEST_P(FrameSchedulerImplNoThrottlingVisibleAgentTest,
VisibleFrameOnHiddenPageDeletion) { … }
TEST_P(FrameSchedulerImplNoThrottlingVisibleAgentTest,
PageSchedulerWithSameAgentFrameDeleted) { … }
TEST_P(FrameSchedulerImplNoThrottlingVisibleAgentTest, AgentChange) { … }
TEST_P(FrameSchedulerImplNoThrottlingVisibleAgentTest,
SameOriginWithNearestMainFrame) { … }
TEST_P(FrameSchedulerImplNoThrottlingVisibleAgentAndThrottleUnimportantTest,
SameAgentWithVisibleFrameIs32msThrottled) { … }
INSTANTIATE_TEST_SUITE_P(…);
INSTANTIATE_TEST_SUITE_P(…);
TEST_F(FrameSchedulerImplTest, DeleteSoonUsesBackupTaskRunner) { … }
TEST_F(FrameSchedulerImplTest, DeleteSoonAfterShutdown) { … }
}
}
}