1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
6
7 #include <map>
8 #include <memory>
9 #include <string>
10 #include <vector>
11
12 #include "base/bind.h"
13 #include "base/callback.h"
14 #include "base/location.h"
15 #include "base/metrics/field_trial_param_associator.h"
16 #include "base/metrics/field_trial_params.h"
17 #include "base/run_loop.h"
18 #include "base/task/sequence_manager/test/sequence_manager_for_test.h"
19 #include "base/test/bind.h"
20 #include "base/test/metrics/histogram_tester.h"
21 #include "base/test/scoped_command_line.h"
22 #include "base/test/scoped_feature_list.h"
23 #include "base/test/task_environment.h"
24 #include "base/unguessable_token.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "third_party/blink/public/common/features.h"
28 #include "third_party/blink/public/common/switches.h"
29 #include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
30 #include "third_party/blink/renderer/platform/scheduler/common/features.h"
31 #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h"
32 #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
33 #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
34 #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
35 #include "third_party/blink/renderer/platform/scheduler/main_thread/resource_loading_task_runner_handle_impl.h"
36 #include "third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h"
37 #include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
38 #include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
39 #include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h"
40 #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
41
42 using base::sequence_manager::TaskQueue;
43 using testing::UnorderedElementsAre;
44
45 namespace blink {
46 namespace scheduler {
47 // To avoid symbol collisions in jumbo builds.
48 namespace frame_scheduler_impl_unittest {
49
50 using FeatureHandle = FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle;
51 using PrioritisationType = MainThreadTaskQueue::QueueTraits::PrioritisationType;
52 using testing::Return;
53
54 namespace {
55
56 constexpr base::TimeDelta kDefaultThrottledWakeUpInterval =
57 PageSchedulerImpl::kDefaultThrottledWakeUpInterval;
58 constexpr auto kShortDelay = base::TimeDelta::FromMilliseconds(10);
59
60 // This is a wrapper around MainThreadSchedulerImpl::CreatePageScheduler, that
61 // returns the PageScheduler as a PageSchedulerImpl.
CreatePageScheduler(PageScheduler::Delegate * page_scheduler_delegate,MainThreadSchedulerImpl * scheduler,WebAgentGroupScheduler & agent_group_scheduler)62 std::unique_ptr<PageSchedulerImpl> CreatePageScheduler(
63 PageScheduler::Delegate* page_scheduler_delegate,
64 MainThreadSchedulerImpl* scheduler,
65 WebAgentGroupScheduler& agent_group_scheduler) {
66 std::unique_ptr<PageScheduler> page_scheduler =
67 agent_group_scheduler.AsAgentGroupScheduler().CreatePageScheduler(
68 page_scheduler_delegate);
69 std::unique_ptr<PageSchedulerImpl> page_scheduler_impl(
70 static_cast<PageSchedulerImpl*>(page_scheduler.release()));
71 return page_scheduler_impl;
72 }
73
74 // This is a wrapper around PageSchedulerImpl::CreateFrameScheduler, that
75 // returns the FrameScheduler as a FrameSchedulerImpl.
CreateFrameScheduler(PageSchedulerImpl * page_scheduler,FrameScheduler::Delegate * delegate,blink::BlameContext * blame_context,FrameScheduler::FrameType frame_type)76 std::unique_ptr<FrameSchedulerImpl> CreateFrameScheduler(
77 PageSchedulerImpl* page_scheduler,
78 FrameScheduler::Delegate* delegate,
79 blink::BlameContext* blame_context,
80 FrameScheduler::FrameType frame_type) {
81 auto frame_scheduler =
82 page_scheduler->CreateFrameScheduler(delegate, blame_context, frame_type);
83 std::unique_ptr<FrameSchedulerImpl> frame_scheduler_impl(
84 static_cast<FrameSchedulerImpl*>(frame_scheduler.release()));
85 return frame_scheduler_impl;
86 }
87
RecordRunTime(std::vector<base::TimeTicks> * run_times)88 void RecordRunTime(std::vector<base::TimeTicks>* run_times) {
89 run_times->push_back(base::TimeTicks::Now());
90 }
91
92 } // namespace
93
94 // All TaskTypes that can be passed to
95 // FrameSchedulerImpl::CreateQueueTraitsForTaskType().
96 constexpr TaskType kAllFrameTaskTypes[] = {
97 TaskType::kInternalContentCapture,
98 TaskType::kJavascriptTimerImmediate,
99 TaskType::kJavascriptTimerDelayedLowNesting,
100 TaskType::kJavascriptTimerDelayedHighNesting,
101 TaskType::kInternalLoading,
102 TaskType::kNetworking,
103 TaskType::kNetworkingWithURLLoaderAnnotation,
104 TaskType::kNetworkingUnfreezable,
105 TaskType::kNetworkingControl,
106 TaskType::kDOMManipulation,
107 TaskType::kHistoryTraversal,
108 TaskType::kEmbed,
109 TaskType::kCanvasBlobSerialization,
110 TaskType::kRemoteEvent,
111 TaskType::kWebSocket,
112 TaskType::kMicrotask,
113 TaskType::kUnshippedPortMessage,
114 TaskType::kFileReading,
115 TaskType::kPresentation,
116 TaskType::kSensor,
117 TaskType::kPerformanceTimeline,
118 TaskType::kWebGL,
119 TaskType::kIdleTask,
120 TaskType::kInternalDefault,
121 TaskType::kMiscPlatformAPI,
122 TaskType::kFontLoading,
123 TaskType::kApplicationLifeCycle,
124 TaskType::kBackgroundFetch,
125 TaskType::kPermission,
126 TaskType::kPostedMessage,
127 TaskType::kServiceWorkerClientMessage,
128 TaskType::kWorkerAnimation,
129 TaskType::kUserInteraction,
130 TaskType::kMediaElementEvent,
131 TaskType::kInternalWebCrypto,
132 TaskType::kInternalMedia,
133 TaskType::kInternalMediaRealTime,
134 TaskType::kInternalUserInteraction,
135 TaskType::kInternalIntersectionObserver,
136 TaskType::kInternalFindInPage,
137 TaskType::kInternalContinueScriptLoading,
138 TaskType::kDatabaseAccess,
139 TaskType::kInternalNavigationAssociated,
140 TaskType::kInternalTest,
141 TaskType::kWebLocks,
142 TaskType::kInternalFrameLifecycleControl,
143 TaskType::kInternalTranslation,
144 TaskType::kInternalInspector,
145 TaskType::kInternalNavigationAssociatedUnfreezable,
146 TaskType::kInternalHighPriorityLocalFrame};
147
148 static_assert(
149 static_cast<int>(TaskType::kCount) == 76,
150 "When adding a TaskType, make sure that kAllFrameTaskTypes is updated.");
151
AppendToVectorTestTask(Vector<String> * vector,String value)152 void AppendToVectorTestTask(Vector<String>* vector, String value) {
153 vector->push_back(std::move(value));
154 }
155
156 class FrameSchedulerDelegateForTesting : public FrameScheduler::Delegate {
157 public:
158 FrameSchedulerDelegateForTesting() = default;
159
160 ~FrameSchedulerDelegateForTesting() override = default;
161
GetUkmRecorder()162 ukm::UkmRecorder* GetUkmRecorder() override { return nullptr; }
163
GetUkmSourceId()164 ukm::SourceId GetUkmSourceId() override { return ukm::kInvalidSourceId; }
165
UpdateTaskTime(base::TimeDelta task_time)166 void UpdateTaskTime(base::TimeDelta task_time) override {
167 update_task_time_calls_++;
168 }
169
GetAgentClusterId() const170 const base::UnguessableToken& GetAgentClusterId() const override {
171 return base::UnguessableToken::Null();
172 }
173
174 MOCK_METHOD1(UpdateActiveSchedulerTrackedFeatures, void(uint64_t));
175
176 int update_task_time_calls_ = 0;
177 };
178
179 class FrameSchedulerImplTest : public testing::Test {
180 public:
FrameSchedulerImplTest()181 FrameSchedulerImplTest()
182 : task_environment_(
183 base::test::TaskEnvironment::TimeSource::MOCK_TIME,
184 base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED) {}
185
186 // Constructs a FrameSchedulerImplTest with a list of features to enable and a
187 // list of features to disable.
FrameSchedulerImplTest(std::vector<base::Feature> features_to_enable,std::vector<base::Feature> features_to_disable)188 FrameSchedulerImplTest(std::vector<base::Feature> features_to_enable,
189 std::vector<base::Feature> features_to_disable)
190 : FrameSchedulerImplTest() {
191 feature_list_.InitWithFeatures(features_to_enable, features_to_disable);
192 }
193
194 // Constructs a FrameSchedulerImplTest with a feature to enable, associated
195 // params, and a list of features to disable.
FrameSchedulerImplTest(const base::Feature & feature_to_enable,const base::FieldTrialParams & feature_to_enable_params,const std::vector<base::Feature> & features_to_disable)196 FrameSchedulerImplTest(const base::Feature& feature_to_enable,
197 const base::FieldTrialParams& feature_to_enable_params,
198 const std::vector<base::Feature>& features_to_disable)
199 : FrameSchedulerImplTest() {
200 feature_list_.InitWithFeaturesAndParameters(
201 {{feature_to_enable, feature_to_enable_params}}, features_to_disable);
202 }
203
204 ~FrameSchedulerImplTest() override = default;
205
SetUp()206 void SetUp() override {
207 scheduler_ = std::make_unique<MainThreadSchedulerImpl>(
208 base::sequence_manager::SequenceManagerForTest::Create(
209 nullptr, task_environment_.GetMainThreadTaskRunner(),
210 task_environment_.GetMockTickClock()),
211 base::nullopt);
212 agent_group_scheduler_ = scheduler_->CreateAgentGroupScheduler();
213 page_scheduler_ =
214 CreatePageScheduler(nullptr, scheduler_.get(), *agent_group_scheduler_);
215 frame_scheduler_delegate_ = std::make_unique<
216 testing::StrictMock<FrameSchedulerDelegateForTesting>>();
217 frame_scheduler_ = CreateFrameScheduler(
218 page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
219 FrameScheduler::FrameType::kSubframe);
220 }
221
ResetFrameScheduler(FrameScheduler::FrameType frame_type)222 void ResetFrameScheduler(FrameScheduler::FrameType frame_type) {
223 auto new_delegate_ = std::make_unique<
224 testing::StrictMock<FrameSchedulerDelegateForTesting>>();
225 frame_scheduler_ = CreateFrameScheduler(
226 page_scheduler_.get(), new_delegate_.get(), nullptr, frame_type);
227 frame_scheduler_delegate_ = std::move(new_delegate_);
228 }
229
StorePageInBackForwardCache()230 void StorePageInBackForwardCache() {
231 page_scheduler_->SetPageBackForwardCached(true);
232 }
233
RestorePageFromBackForwardCache()234 void RestorePageFromBackForwardCache() {
235 page_scheduler_->SetPageBackForwardCached(false);
236 }
237
TearDown()238 void TearDown() override {
239 throttleable_task_queue_.reset();
240 frame_scheduler_.reset();
241 page_scheduler_.reset();
242 agent_group_scheduler_.reset();
243 scheduler_->Shutdown();
244 scheduler_.reset();
245 frame_scheduler_delegate_.reset();
246 }
247
248 // Helper for posting several tasks of specific prioritisation types for
249 // testing the relative order of tasks. |task_descriptor| is a string with
250 // space delimited task identifiers. The first letter of each task identifier
251 // specifies the prioritisation type:
252 // - 'R': Regular (normal priority)
253 // - 'V': Internal Script Continuation (very high priority)
254 // - 'B': Best-effort
255 // - 'D': Database
PostTestTasksForPrioritisationType(Vector<String> * run_order,const String & task_descriptor)256 void PostTestTasksForPrioritisationType(Vector<String>* run_order,
257 const String& task_descriptor) {
258 std::istringstream stream(task_descriptor.Utf8());
259 PrioritisationType prioritisation_type;
260 while (!stream.eof()) {
261 std::string task;
262 stream >> task;
263 switch (task[0]) {
264 case 'R':
265 prioritisation_type = PrioritisationType::kRegular;
266 break;
267 case 'V':
268 prioritisation_type = PrioritisationType::kInternalScriptContinuation;
269 break;
270 case 'B':
271 prioritisation_type = PrioritisationType::kBestEffort;
272 break;
273 case 'D':
274 prioritisation_type = PrioritisationType::kExperimentalDatabase;
275 break;
276 default:
277 EXPECT_FALSE(true);
278 return;
279 }
280 auto queue_traits =
281 FrameSchedulerImpl::PausableTaskQueueTraits().SetPrioritisationType(
282 prioritisation_type);
283 GetTaskQueue(queue_traits)
284 ->GetTaskRunnerWithDefaultTaskType()
285 ->PostTask(FROM_HERE,
286 base::BindOnce(&AppendToVectorTestTask, run_order,
287 String::FromUTF8(task)));
288 }
289 }
290
ResetForNavigation(FrameSchedulerImpl * frame_scheduler)291 static void ResetForNavigation(FrameSchedulerImpl* frame_scheduler) {
292 frame_scheduler->ResetForNavigation();
293 }
294
GetTaskTime()295 base::TimeDelta GetTaskTime() { return frame_scheduler_->task_time_; }
296
GetTotalUpdateTaskTimeCalls()297 int GetTotalUpdateTaskTimeCalls() {
298 return frame_scheduler_delegate_->update_task_time_calls_;
299 }
300
ResetTotalUpdateTaskTimeCalls()301 void ResetTotalUpdateTaskTimeCalls() {
302 frame_scheduler_delegate_->update_task_time_calls_ = 0;
303 }
304
305 // Fast-forwards to the next time aligned on |interval|.
FastForwardToAlignedTime(base::TimeDelta interval)306 void FastForwardToAlignedTime(base::TimeDelta interval) {
307 const base::TimeTicks now = base::TimeTicks::Now();
308 const base::TimeTicks aligned =
309 now.SnappedToNextTick(base::TimeTicks(), interval);
310 if (aligned != now)
311 task_environment_.FastForwardBy(aligned - now);
312 }
313
GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(FrameSchedulerImpl * frame_scheduler)314 static uint64_t GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
315 FrameSchedulerImpl* frame_scheduler) {
316 return frame_scheduler
317 ->GetActiveFeaturesTrackedForBackForwardCacheMetricsMask();
318 }
319
320 protected:
throttleable_task_queue()321 scoped_refptr<MainThreadTaskQueue> throttleable_task_queue() {
322 return throttleable_task_queue_;
323 }
324
LazyInitThrottleableTaskQueue()325 void LazyInitThrottleableTaskQueue() {
326 EXPECT_FALSE(throttleable_task_queue());
327 throttleable_task_queue_ = ThrottleableTaskQueue();
328 EXPECT_TRUE(throttleable_task_queue());
329 }
330
GetTaskQueue(MainThreadTaskQueue::QueueTraits queue_traits)331 scoped_refptr<MainThreadTaskQueue> GetTaskQueue(
332 MainThreadTaskQueue::QueueTraits queue_traits) {
333 return frame_scheduler_->FrameTaskQueueControllerForTest()->GetTaskQueue(
334 queue_traits);
335 }
336
ThrottleableTaskQueue()337 scoped_refptr<MainThreadTaskQueue> ThrottleableTaskQueue() {
338 return GetTaskQueue(FrameSchedulerImpl::ThrottleableTaskQueueTraits());
339 }
340
JavaScriptTimerTaskQueue()341 scoped_refptr<MainThreadTaskQueue> JavaScriptTimerTaskQueue() {
342 return GetTaskQueue(
343 FrameSchedulerImpl::ThrottleableTaskQueueTraits().SetPrioritisationType(
344 PrioritisationType::kJavaScriptTimer));
345 }
346
JavaScriptTimerNonThrottleableTaskQueue()347 scoped_refptr<MainThreadTaskQueue> JavaScriptTimerNonThrottleableTaskQueue() {
348 return GetTaskQueue(
349 FrameSchedulerImpl::DeferrableTaskQueueTraits().SetPrioritisationType(
350 PrioritisationType::kJavaScriptTimer));
351 }
352
LoadingTaskQueue()353 scoped_refptr<MainThreadTaskQueue> LoadingTaskQueue() {
354 return GetTaskQueue(FrameSchedulerImpl::LoadingTaskQueueTraits());
355 }
356
LoadingControlTaskQueue()357 scoped_refptr<MainThreadTaskQueue> LoadingControlTaskQueue() {
358 return GetTaskQueue(FrameSchedulerImpl::LoadingControlTaskQueueTraits());
359 }
360
UnfreezableLoadingTaskQueue()361 scoped_refptr<MainThreadTaskQueue> UnfreezableLoadingTaskQueue() {
362 return GetTaskQueue(
363 FrameSchedulerImpl::UnfreezableLoadingTaskQueueTraits());
364 }
365
DeferrableTaskQueue()366 scoped_refptr<MainThreadTaskQueue> DeferrableTaskQueue() {
367 return GetTaskQueue(FrameSchedulerImpl::DeferrableTaskQueueTraits());
368 }
369
PausableTaskQueue()370 scoped_refptr<MainThreadTaskQueue> PausableTaskQueue() {
371 return GetTaskQueue(FrameSchedulerImpl::PausableTaskQueueTraits());
372 }
373
UnpausableTaskQueue()374 scoped_refptr<MainThreadTaskQueue> UnpausableTaskQueue() {
375 return GetTaskQueue(FrameSchedulerImpl::UnpausableTaskQueueTraits());
376 }
377
ForegroundOnlyTaskQueue()378 scoped_refptr<MainThreadTaskQueue> ForegroundOnlyTaskQueue() {
379 return GetTaskQueue(FrameSchedulerImpl::ForegroundOnlyTaskQueueTraits());
380 }
381
GetTaskQueue(TaskType type)382 scoped_refptr<MainThreadTaskQueue> GetTaskQueue(TaskType type) {
383 return frame_scheduler_->GetTaskQueue(type);
384 }
385
386 std::unique_ptr<ResourceLoadingTaskRunnerHandleImpl>
GetResourceLoadingTaskRunnerHandleImpl()387 GetResourceLoadingTaskRunnerHandleImpl() {
388 return frame_scheduler_->CreateResourceLoadingTaskRunnerHandleImpl();
389 }
390
IsThrottled()391 bool IsThrottled() {
392 EXPECT_TRUE(throttleable_task_queue());
393 return scheduler_->task_queue_throttler()->IsThrottled(
394 throttleable_task_queue()->GetTaskQueue());
395 }
396
IsTaskTypeThrottled(TaskType task_type)397 bool IsTaskTypeThrottled(TaskType task_type) {
398 scoped_refptr<MainThreadTaskQueue> task_queue = GetTaskQueue(task_type);
399 return scheduler_->task_queue_throttler()->IsThrottled(
400 task_queue->GetTaskQueue());
401 }
402
CalculateLifecycleState(FrameScheduler::ObserverType type)403 SchedulingLifecycleState CalculateLifecycleState(
404 FrameScheduler::ObserverType type) {
405 return frame_scheduler_->CalculateLifecycleState(type);
406 }
407
DidChangeResourceLoadingPriority(scoped_refptr<MainThreadTaskQueue> task_queue,net::RequestPriority priority)408 void DidChangeResourceLoadingPriority(
409 scoped_refptr<MainThreadTaskQueue> task_queue,
410 net::RequestPriority priority) {
411 frame_scheduler_->DidChangeResourceLoadingPriority(task_queue, priority);
412 }
413
DidCommitProvisionalLoad(FrameScheduler::NavigationType navigation_type)414 void DidCommitProvisionalLoad(
415 FrameScheduler::NavigationType navigation_type) {
416 frame_scheduler_->DidCommitProvisionalLoad(
417 /*is_web_history_inert_commit=*/false, navigation_type);
418 }
419
scoped_feature_list()420 base::test::ScopedFeatureList& scoped_feature_list() { return feature_list_; }
421
422 base::test::ScopedFeatureList feature_list_;
423 base::test::TaskEnvironment task_environment_;
424 std::unique_ptr<MainThreadSchedulerImpl> scheduler_;
425 std::unique_ptr<WebAgentGroupScheduler> agent_group_scheduler_;
426 std::unique_ptr<PageSchedulerImpl> page_scheduler_;
427 std::unique_ptr<FrameSchedulerImpl> frame_scheduler_;
428 std::unique_ptr<testing::StrictMock<FrameSchedulerDelegateForTesting>>
429 frame_scheduler_delegate_;
430 scoped_refptr<MainThreadTaskQueue> throttleable_task_queue_;
431 };
432
433 class FrameSchedulerImplStopNonTimersInBackgroundEnabledTest
434 : public FrameSchedulerImplTest {
435 public:
FrameSchedulerImplStopNonTimersInBackgroundEnabledTest()436 FrameSchedulerImplStopNonTimersInBackgroundEnabledTest()
437 : FrameSchedulerImplTest({blink::features::kStopNonTimersInBackground},
438 {}) {}
439 };
440
441 class FrameSchedulerImplStopNonTimersInBackgroundDisabledTest
442 : public FrameSchedulerImplTest {
443 public:
FrameSchedulerImplStopNonTimersInBackgroundDisabledTest()444 FrameSchedulerImplStopNonTimersInBackgroundDisabledTest()
445 : FrameSchedulerImplTest({},
446 {blink::features::kStopNonTimersInBackground}) {}
447 };
448
449 class FrameSchedulerImplStopInBackgroundDisabledTest
450 : public FrameSchedulerImplTest,
451 public ::testing::WithParamInterface<TaskType> {
452 public:
FrameSchedulerImplStopInBackgroundDisabledTest()453 FrameSchedulerImplStopInBackgroundDisabledTest()
454 : FrameSchedulerImplTest({}, {blink::features::kStopInBackground}) {}
455 };
456
457 namespace {
458
459 class MockLifecycleObserver final : public FrameScheduler::Observer {
460 public:
MockLifecycleObserver()461 MockLifecycleObserver()
462 : not_throttled_count_(0u),
463 hidden_count_(0u),
464 throttled_count_(0u),
465 stopped_count_(0u) {}
466
CheckObserverState(base::Location from,size_t not_throttled_count_expectation,size_t hidden_count_expectation,size_t throttled_count_expectation,size_t stopped_count_expectation)467 inline void CheckObserverState(base::Location from,
468 size_t not_throttled_count_expectation,
469 size_t hidden_count_expectation,
470 size_t throttled_count_expectation,
471 size_t stopped_count_expectation) {
472 EXPECT_EQ(not_throttled_count_expectation, not_throttled_count_)
473 << from.ToString();
474 EXPECT_EQ(hidden_count_expectation, hidden_count_) << from.ToString();
475 EXPECT_EQ(throttled_count_expectation, throttled_count_) << from.ToString();
476 EXPECT_EQ(stopped_count_expectation, stopped_count_) << from.ToString();
477 }
478
OnLifecycleStateChanged(SchedulingLifecycleState state)479 void OnLifecycleStateChanged(SchedulingLifecycleState state) override {
480 switch (state) {
481 case SchedulingLifecycleState::kNotThrottled:
482 not_throttled_count_++;
483 break;
484 case SchedulingLifecycleState::kHidden:
485 hidden_count_++;
486 break;
487 case SchedulingLifecycleState::kThrottled:
488 throttled_count_++;
489 break;
490 case SchedulingLifecycleState::kStopped:
491 stopped_count_++;
492 break;
493 // We should not have another state, and compiler checks it.
494 }
495 }
496
497 private:
498 size_t not_throttled_count_;
499 size_t hidden_count_;
500 size_t throttled_count_;
501 size_t stopped_count_;
502 };
503
IncrementCounter(int * counter)504 void IncrementCounter(int* counter) {
505 ++*counter;
506 }
507
RecordQueueName(String name,Vector<String> * tasks)508 void RecordQueueName(String name, Vector<String>* tasks) {
509 tasks->push_back(std::move(name));
510 }
511
512 // Simulate running a task of a particular length by fast forwarding the task
513 // environment clock, which is used to determine the wall time of a task.
RunTaskOfLength(base::test::TaskEnvironment * task_environment,base::TimeDelta length)514 void RunTaskOfLength(base::test::TaskEnvironment* task_environment,
515 base::TimeDelta length) {
516 task_environment->FastForwardBy(length);
517 }
518
519 class FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase
520 : public FrameSchedulerImplTest {
521 public:
522 using Super = FrameSchedulerImplTest;
523
FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase(bool can_intensively_throttle_low_nesting_level)524 explicit FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase(
525 bool can_intensively_throttle_low_nesting_level)
526 : FrameSchedulerImplTest(
527 features::kIntensiveWakeUpThrottling,
528 // If |can_intensively_throttle_low_nesting_level| is true, set the
529 // feature param to "true". Otherwise, test the default behavior (no
530 // feature params).
531 can_intensively_throttle_low_nesting_level
532 ? base::FieldTrialParams(
533 {{kIntensiveWakeUpThrottling_CanIntensivelyThrottleLowNestingLevel_Name,
534 "true"}})
535 : base::FieldTrialParams(),
536 {features::kStopInBackground}) {}
537
SetUp()538 void SetUp() override {
539 Super::SetUp();
540 ClearIntensiveWakeUpThrottlingPolicyOverrideCacheForTesting();
541 }
542
TearDown()543 void TearDown() override {
544 ClearIntensiveWakeUpThrottlingPolicyOverrideCacheForTesting();
545 Super::TearDown();
546 }
547
548 const int kNumTasks = 5;
549 const base::TimeDelta kGracePeriod =
550 GetIntensiveWakeUpThrottlingGracePeriod();
551 const base::TimeDelta kIntensiveThrottlingDurationBetweenWakeUps =
552 GetIntensiveWakeUpThrottlingDurationBetweenWakeUps();
553 };
554
555 // Test param for FrameSchedulerImplTestWithIntensiveWakeUpThrottling
556 struct IntensiveWakeUpThrottlingTestParam {
557 // TaskType used to obtain TaskRunners from the FrameScheduler.
558 TaskType task_type;
559 // Whether the feature param to allow throttling of timers with a low nesting
560 // level should be set to "true" at the beginning of the test.
561 bool can_intensively_throttle_low_nesting_level;
562 // Whether it is expected that tasks will be intensively throttled.
563 bool is_intensive_throttling_expected;
564 };
565
566 class FrameSchedulerImplTestWithIntensiveWakeUpThrottling
567 : public FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase,
568 public ::testing::WithParamInterface<IntensiveWakeUpThrottlingTestParam> {
569 public:
FrameSchedulerImplTestWithIntensiveWakeUpThrottling()570 FrameSchedulerImplTestWithIntensiveWakeUpThrottling()
571 : FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase(
572 GetParam().can_intensively_throttle_low_nesting_level) {}
573
GetTaskType() const574 TaskType GetTaskType() const { return GetParam().task_type; }
IsIntensiveThrottlingExpected() const575 bool IsIntensiveThrottlingExpected() const {
576 return GetParam().is_intensive_throttling_expected;
577 }
578
GetExpectedWakeUpInterval() const579 base::TimeDelta GetExpectedWakeUpInterval() const {
580 if (IsIntensiveThrottlingExpected())
581 return kIntensiveThrottlingDurationBetweenWakeUps;
582 return kDefaultThrottledWakeUpInterval;
583 }
584 };
585
586 class FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride
587 : public FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase {
588 public:
FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride()589 FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride()
590 : FrameSchedulerImplTestWithIntensiveWakeUpThrottlingBase(
591 /* can_intensively_throttle_low_nesting_level=*/false) {}
592
593 // This should only be called once per test, and prior to the
594 // PageSchedulerImpl logic actually parsing the policy switch.
SetPolicyOverride(bool enabled)595 void SetPolicyOverride(bool enabled) {
596 DCHECK(!scoped_command_line_.GetProcessCommandLine()->HasSwitch(
597 switches::kIntensiveWakeUpThrottlingPolicy));
598 scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII(
599 switches::kIntensiveWakeUpThrottlingPolicy,
600 enabled ? switches::kIntensiveWakeUpThrottlingPolicy_ForceEnable
601 : switches::kIntensiveWakeUpThrottlingPolicy_ForceDisable);
602 }
603
604 private:
605 base::test::ScopedCommandLine scoped_command_line_;
606 };
607
608 } // namespace
609
610 // Throttleable task queue is initialized lazily, so there're two scenarios:
611 // - Task queue created first and throttling decision made later;
612 // - Scheduler receives relevant signals to make a throttling decision but
613 // applies one once task queue gets created.
614 // We test both (ExplicitInit/LazyInit) of them.
615
TEST_F(FrameSchedulerImplTest,PageVisible)616 TEST_F(FrameSchedulerImplTest, PageVisible) {
617 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true);
618 EXPECT_FALSE(throttleable_task_queue());
619 LazyInitThrottleableTaskQueue();
620 EXPECT_FALSE(IsThrottled());
621 }
622
TEST_F(FrameSchedulerImplTest,PageHidden_ExplicitInit)623 TEST_F(FrameSchedulerImplTest, PageHidden_ExplicitInit) {
624 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true);
625 LazyInitThrottleableTaskQueue();
626 EXPECT_FALSE(IsThrottled());
627 page_scheduler_->SetPageVisible(false);
628 EXPECT_TRUE(IsThrottled());
629 }
630
TEST_F(FrameSchedulerImplTest,PageHidden_LazyInit)631 TEST_F(FrameSchedulerImplTest, PageHidden_LazyInit) {
632 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(false);
633 page_scheduler_->SetPageVisible(false);
634 LazyInitThrottleableTaskQueue();
635 EXPECT_TRUE(IsThrottled());
636 }
637
TEST_F(FrameSchedulerImplTest,PageHiddenThenVisible_ExplicitInit)638 TEST_F(FrameSchedulerImplTest, PageHiddenThenVisible_ExplicitInit) {
639 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(false);
640 LazyInitThrottleableTaskQueue();
641 EXPECT_FALSE(IsThrottled());
642 page_scheduler_->SetPageVisible(false);
643 EXPECT_TRUE(IsThrottled());
644 page_scheduler_->SetPageVisible(true);
645 EXPECT_FALSE(IsThrottled());
646 page_scheduler_->SetPageVisible(false);
647 EXPECT_TRUE(IsThrottled());
648 }
649
TEST_F(FrameSchedulerImplTest,FrameHiddenThenVisible_CrossOrigin_ExplicitInit)650 TEST_F(FrameSchedulerImplTest,
651 FrameHiddenThenVisible_CrossOrigin_ExplicitInit) {
652 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true);
653 LazyInitThrottleableTaskQueue();
654 EXPECT_FALSE(IsThrottled());
655 frame_scheduler_->SetFrameVisible(false);
656 frame_scheduler_->SetCrossOriginToMainFrame(true);
657 frame_scheduler_->SetCrossOriginToMainFrame(false);
658 EXPECT_FALSE(IsThrottled());
659 frame_scheduler_->SetCrossOriginToMainFrame(true);
660 EXPECT_TRUE(IsThrottled());
661 frame_scheduler_->SetFrameVisible(true);
662 EXPECT_FALSE(IsThrottled());
663 frame_scheduler_->SetFrameVisible(false);
664 EXPECT_TRUE(IsThrottled());
665 }
666
TEST_F(FrameSchedulerImplTest,FrameHidden_CrossOrigin_LazyInit)667 TEST_F(FrameSchedulerImplTest, FrameHidden_CrossOrigin_LazyInit) {
668 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true);
669 frame_scheduler_->SetFrameVisible(false);
670 frame_scheduler_->SetCrossOriginToMainFrame(true);
671 LazyInitThrottleableTaskQueue();
672 EXPECT_TRUE(IsThrottled());
673 }
674
TEST_F(FrameSchedulerImplTest,FrameHidden_CrossOrigin_NoThrottling_ExplicitInit)675 TEST_F(FrameSchedulerImplTest,
676 FrameHidden_CrossOrigin_NoThrottling_ExplicitInit) {
677 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(false);
678 LazyInitThrottleableTaskQueue();
679 EXPECT_FALSE(IsThrottled());
680 frame_scheduler_->SetFrameVisible(false);
681 frame_scheduler_->SetCrossOriginToMainFrame(true);
682 EXPECT_FALSE(IsThrottled());
683 }
684
TEST_F(FrameSchedulerImplTest,FrameHidden_CrossOrigin_NoThrottling_LazyInit)685 TEST_F(FrameSchedulerImplTest, FrameHidden_CrossOrigin_NoThrottling_LazyInit) {
686 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(false);
687 frame_scheduler_->SetFrameVisible(false);
688 frame_scheduler_->SetCrossOriginToMainFrame(true);
689 LazyInitThrottleableTaskQueue();
690 EXPECT_FALSE(IsThrottled());
691 }
692
TEST_F(FrameSchedulerImplTest,FrameHidden_SameOrigin_ExplicitInit)693 TEST_F(FrameSchedulerImplTest, FrameHidden_SameOrigin_ExplicitInit) {
694 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true);
695 LazyInitThrottleableTaskQueue();
696 EXPECT_FALSE(IsThrottled());
697 frame_scheduler_->SetFrameVisible(false);
698 EXPECT_FALSE(IsThrottled());
699 }
700
TEST_F(FrameSchedulerImplTest,FrameHidden_SameOrigin_LazyInit)701 TEST_F(FrameSchedulerImplTest, FrameHidden_SameOrigin_LazyInit) {
702 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true);
703 frame_scheduler_->SetFrameVisible(false);
704 LazyInitThrottleableTaskQueue();
705 EXPECT_FALSE(IsThrottled());
706 }
707
TEST_F(FrameSchedulerImplTest,FrameVisible_CrossOrigin_ExplicitInit)708 TEST_F(FrameSchedulerImplTest, FrameVisible_CrossOrigin_ExplicitInit) {
709 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true);
710 LazyInitThrottleableTaskQueue();
711 EXPECT_FALSE(IsThrottled());
712 EXPECT_TRUE(throttleable_task_queue());
713 frame_scheduler_->SetFrameVisible(true);
714 EXPECT_FALSE(IsThrottled());
715 frame_scheduler_->SetCrossOriginToMainFrame(true);
716 EXPECT_FALSE(IsThrottled());
717 }
718
TEST_F(FrameSchedulerImplTest,FrameVisible_CrossOrigin_LazyInit)719 TEST_F(FrameSchedulerImplTest, FrameVisible_CrossOrigin_LazyInit) {
720 ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true);
721 frame_scheduler_->SetFrameVisible(true);
722 frame_scheduler_->SetCrossOriginToMainFrame(true);
723 LazyInitThrottleableTaskQueue();
724 EXPECT_FALSE(IsThrottled());
725 }
726
TEST_F(FrameSchedulerImplTest,PauseAndResume)727 TEST_F(FrameSchedulerImplTest, PauseAndResume) {
728 int counter = 0;
729 LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
730 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
731 ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
732 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
733 DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
734 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
735 PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
736 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
737 UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
738 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
739
740 frame_scheduler_->SetPaused(true);
741
742 EXPECT_EQ(0, counter);
743 base::RunLoop().RunUntilIdle();
744 EXPECT_EQ(1, counter);
745
746 frame_scheduler_->SetPaused(false);
747
748 EXPECT_EQ(1, counter);
749 base::RunLoop().RunUntilIdle();
750 EXPECT_EQ(5, counter);
751 }
752
TEST_F(FrameSchedulerImplTest,PauseAndResumeForCooperativeScheduling)753 TEST_F(FrameSchedulerImplTest, PauseAndResumeForCooperativeScheduling) {
754 EXPECT_TRUE(LoadingTaskQueue()->GetTaskQueue()->IsQueueEnabled());
755 EXPECT_TRUE(ThrottleableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
756 EXPECT_TRUE(DeferrableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
757 EXPECT_TRUE(PausableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
758 EXPECT_TRUE(UnpausableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
759
760 frame_scheduler_->SetPreemptedForCooperativeScheduling(
761 FrameOrWorkerScheduler::Preempted(true));
762 EXPECT_FALSE(LoadingTaskQueue()->GetTaskQueue()->IsQueueEnabled());
763 EXPECT_FALSE(ThrottleableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
764 EXPECT_FALSE(DeferrableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
765 EXPECT_FALSE(PausableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
766 EXPECT_FALSE(UnpausableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
767
768 frame_scheduler_->SetPreemptedForCooperativeScheduling(
769 FrameOrWorkerScheduler::Preempted(false));
770 EXPECT_TRUE(LoadingTaskQueue()->GetTaskQueue()->IsQueueEnabled());
771 EXPECT_TRUE(ThrottleableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
772 EXPECT_TRUE(DeferrableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
773 EXPECT_TRUE(PausableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
774 EXPECT_TRUE(UnpausableTaskQueue()->GetTaskQueue()->IsQueueEnabled());
775 }
776
777 namespace {
778
779 // A task that re-posts itself with a delay in order until it has run
780 // |num_remaining_tasks| times.
RePostTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner,base::TimeDelta delay,int * num_remaining_tasks)781 void RePostTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
782 base::TimeDelta delay,
783 int* num_remaining_tasks) {
784 --(*num_remaining_tasks);
785 if (*num_remaining_tasks > 0) {
786 task_runner->PostDelayedTask(
787 FROM_HERE,
788 base::BindOnce(&RePostTask, task_runner, delay,
789 base::Unretained(num_remaining_tasks)),
790 delay);
791 }
792 }
793
794 } // namespace
795
796 // Verify that tasks in a throttled task queue cause 1 wake up per second, when
797 // intensive wake up throttling is disabled. Disable the kStopInBackground
798 // feature because it hides the effect of intensive wake up throttling.
TEST_P(FrameSchedulerImplStopInBackgroundDisabledTest,ThrottledTaskExecution)799 TEST_P(FrameSchedulerImplStopInBackgroundDisabledTest, ThrottledTaskExecution) {
800 constexpr auto kTaskPeriod = base::TimeDelta::FromSeconds(1);
801
802 // This test posts enough tasks to run past the default intensive wake up
803 // throttling grace period. This allows verifying that intensive wake up
804 // throttling is disabled by default.
805 constexpr int kNumTasks =
806 base::TimeDelta::FromSeconds(
807 kIntensiveWakeUpThrottling_GracePeriodSeconds_Default * 2)
808 .IntDiv(kTaskPeriod);
809 // This TaskRunner is throttled.
810 const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
811 frame_scheduler_->GetTaskRunner(GetParam());
812
813 // Hide the page. This enables wake up throttling.
814 EXPECT_TRUE(page_scheduler_->IsPageVisible());
815 page_scheduler_->SetPageVisible(false);
816
817 // Post an initial task.
818 int num_remaining_tasks = kNumTasks;
819 task_runner->PostDelayedTask(
820 FROM_HERE,
821 base::BindOnce(&RePostTask, task_runner, kShortDelay,
822 base::Unretained(&num_remaining_tasks)),
823 kShortDelay);
824
825 // A task should run every second.
826 while (num_remaining_tasks > 0) {
827 int previous_num_remaining_tasks = num_remaining_tasks;
828 task_environment_.FastForwardBy(kTaskPeriod);
829 EXPECT_EQ(previous_num_remaining_tasks - 1, num_remaining_tasks);
830 }
831 }
832
833 INSTANTIATE_TEST_SUITE_P(
834 AllTimerTaskTypes,
835 FrameSchedulerImplStopInBackgroundDisabledTest,
836 testing::Values(TaskType::kJavascriptTimerDelayedLowNesting,
837 TaskType::kJavascriptTimerDelayedHighNesting),
__anonca7fdf3d0402(const testing::TestParamInfo<TaskType>& info) 838 [](const testing::TestParamInfo<TaskType>& info) {
839 return TaskTypeNames::TaskTypeToString(info.param);
840 });
841
TEST_F(FrameSchedulerImplTest,FreezeForegroundOnlyTasks)842 TEST_F(FrameSchedulerImplTest, FreezeForegroundOnlyTasks) {
843 int counter = 0;
844 ForegroundOnlyTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
845 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
846
847 page_scheduler_->SetPageVisible(false);
848
849 EXPECT_EQ(0, counter);
850 base::RunLoop().RunUntilIdle();
851 EXPECT_EQ(0, counter);
852
853 page_scheduler_->SetPageVisible(true);
854
855 EXPECT_EQ(0, counter);
856 base::RunLoop().RunUntilIdle();
857 EXPECT_EQ(1, counter);
858 }
859
TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,PageFreezeAndUnfreezeFlagEnabled)860 TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,
861 PageFreezeAndUnfreezeFlagEnabled) {
862 int counter = 0;
863 LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
864 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
865 ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
866 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
867 DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
868 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
869 PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
870 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
871 UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
872 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
873
874 page_scheduler_->SetPageVisible(false);
875 page_scheduler_->SetPageFrozen(true);
876
877 EXPECT_EQ(0, counter);
878 base::RunLoop().RunUntilIdle();
879 // unpausable tasks continue to run.
880 EXPECT_EQ(1, counter);
881
882 page_scheduler_->SetPageFrozen(false);
883
884 EXPECT_EQ(1, counter);
885 // Same as RunUntilIdle but also advances the clock if necessary.
886 task_environment_.FastForwardUntilNoTasksRemain();
887 EXPECT_EQ(5, counter);
888 }
889
TEST_F(FrameSchedulerImplStopNonTimersInBackgroundDisabledTest,PageFreezeAndUnfreezeFlagDisabled)890 TEST_F(FrameSchedulerImplStopNonTimersInBackgroundDisabledTest,
891 PageFreezeAndUnfreezeFlagDisabled) {
892 int counter = 0;
893 LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
894 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
895 ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
896 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
897 DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
898 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
899 PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
900 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
901 UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
902 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
903
904 page_scheduler_->SetPageVisible(false);
905 page_scheduler_->SetPageFrozen(true);
906
907 EXPECT_EQ(0, counter);
908 base::RunLoop().RunUntilIdle();
909 // throttleable tasks and loading tasks are frozen, others continue to run.
910 EXPECT_EQ(3, counter);
911
912 page_scheduler_->SetPageFrozen(false);
913
914 EXPECT_EQ(3, counter);
915 // Same as RunUntilIdle but also advances the clock if necessary.
916 task_environment_.FastForwardUntilNoTasksRemain();
917 EXPECT_EQ(5, counter);
918 }
919
TEST_F(FrameSchedulerImplTest,PagePostsCpuTasks)920 TEST_F(FrameSchedulerImplTest, PagePostsCpuTasks) {
921 EXPECT_TRUE(GetTaskTime().is_zero());
922 EXPECT_EQ(0, GetTotalUpdateTaskTimeCalls());
923 UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
924 FROM_HERE, base::BindOnce(&RunTaskOfLength, &task_environment_,
925 base::TimeDelta::FromMilliseconds(10)));
926 base::RunLoop().RunUntilIdle();
927 EXPECT_FALSE(GetTaskTime().is_zero());
928 EXPECT_EQ(0, GetTotalUpdateTaskTimeCalls());
929 UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
930 FROM_HERE, base::BindOnce(&RunTaskOfLength, &task_environment_,
931 base::TimeDelta::FromMilliseconds(100)));
932 base::RunLoop().RunUntilIdle();
933 EXPECT_TRUE(GetTaskTime().is_zero());
934 EXPECT_EQ(1, GetTotalUpdateTaskTimeCalls());
935 }
936
TEST_F(FrameSchedulerImplTest,FramePostsCpuTasksThroughReloadRenavigate)937 TEST_F(FrameSchedulerImplTest, FramePostsCpuTasksThroughReloadRenavigate) {
938 const struct {
939 FrameScheduler::FrameType frame_type;
940 FrameScheduler::NavigationType navigation_type;
941 bool expect_task_time_zero;
942 int expected_total_calls;
943 } kTestCases[] = {{FrameScheduler::FrameType::kMainFrame,
944 FrameScheduler::NavigationType::kOther, false, 0},
945 {FrameScheduler::FrameType::kMainFrame,
946 FrameScheduler::NavigationType::kReload, false, 0},
947 {FrameScheduler::FrameType::kMainFrame,
948 FrameScheduler::NavigationType::kSameDocument, true, 1},
949 {FrameScheduler::FrameType::kSubframe,
950 FrameScheduler::NavigationType::kOther, true, 1},
951 {FrameScheduler::FrameType::kSubframe,
952 FrameScheduler::NavigationType::kSameDocument, true, 1}};
953 for (const auto& test_case : kTestCases) {
954 SCOPED_TRACE(String::Format(
955 "FrameType: %d, NavigationType: %d : TaskTime.is_zero %d, CallCount %d",
956 test_case.frame_type, test_case.navigation_type,
957 test_case.expect_task_time_zero, test_case.expected_total_calls));
958 ResetFrameScheduler(test_case.frame_type);
959 EXPECT_TRUE(GetTaskTime().is_zero());
960 EXPECT_EQ(0, GetTotalUpdateTaskTimeCalls());
961
962 // Check the rest of the values after different types of commit.
963 UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
964 FROM_HERE, base::BindOnce(&RunTaskOfLength, &task_environment_,
965 base::TimeDelta::FromMilliseconds(60)));
966 base::RunLoop().RunUntilIdle();
967 EXPECT_FALSE(GetTaskTime().is_zero());
968 EXPECT_EQ(0, GetTotalUpdateTaskTimeCalls());
969
970 DidCommitProvisionalLoad(test_case.navigation_type);
971
972 UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
973 FROM_HERE, base::BindOnce(&RunTaskOfLength, &task_environment_,
974 base::TimeDelta::FromMilliseconds(60)));
975 base::RunLoop().RunUntilIdle();
976 EXPECT_EQ(test_case.expect_task_time_zero, GetTaskTime().is_zero());
977 EXPECT_EQ(test_case.expected_total_calls, GetTotalUpdateTaskTimeCalls());
978 }
979 }
980
TEST_F(FrameSchedulerImplTest,PageFreezeWithKeepActive)981 TEST_F(FrameSchedulerImplTest, PageFreezeWithKeepActive) {
982 Vector<String> tasks;
983 LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
984 FROM_HERE,
985 base::BindOnce(&RecordQueueName,
986 LoadingTaskQueue()->GetTaskQueue()->GetName(), &tasks));
987 ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
988 FROM_HERE,
989 base::BindOnce(&RecordQueueName,
990 ThrottleableTaskQueue()->GetTaskQueue()->GetName(),
991 &tasks));
992 DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
993 FROM_HERE,
994 base::BindOnce(&RecordQueueName,
995 DeferrableTaskQueue()->GetTaskQueue()->GetName(), &tasks));
996 PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
997 FROM_HERE,
998 base::BindOnce(&RecordQueueName,
999 PausableTaskQueue()->GetTaskQueue()->GetName(), &tasks));
1000 UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
1001 FROM_HERE,
1002 base::BindOnce(&RecordQueueName,
1003 UnpausableTaskQueue()->GetTaskQueue()->GetName(), &tasks));
1004
1005 page_scheduler_->SetKeepActive(true); // say we have a Service Worker
1006 page_scheduler_->SetPageVisible(false);
1007 page_scheduler_->SetPageFrozen(true);
1008
1009 EXPECT_THAT(tasks, UnorderedElementsAre());
1010 base::RunLoop().RunUntilIdle();
1011 // Everything runs except throttleable tasks (timers)
1012 EXPECT_THAT(tasks,
1013 UnorderedElementsAre(
1014 String(LoadingTaskQueue()->GetTaskQueue()->GetName()),
1015 String(DeferrableTaskQueue()->GetTaskQueue()->GetName()),
1016 String(PausableTaskQueue()->GetTaskQueue()->GetName()),
1017 String(UnpausableTaskQueue()->GetTaskQueue()->GetName())));
1018
1019 tasks.clear();
1020 LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
1021 FROM_HERE,
1022 base::BindOnce(&RecordQueueName,
1023 LoadingTaskQueue()->GetTaskQueue()->GetName(), &tasks));
1024
1025 EXPECT_THAT(tasks, UnorderedElementsAre());
1026 base::RunLoop().RunUntilIdle();
1027 // loading task runs
1028 EXPECT_THAT(tasks, UnorderedElementsAre(String(
1029 LoadingTaskQueue()->GetTaskQueue()->GetName())));
1030
1031 tasks.clear();
1032 LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
1033 FROM_HERE,
1034 base::BindOnce(&RecordQueueName,
1035 LoadingTaskQueue()->GetTaskQueue()->GetName(), &tasks));
1036 // KeepActive is false when Service Worker stops.
1037 page_scheduler_->SetKeepActive(false);
1038 EXPECT_THAT(tasks, UnorderedElementsAre());
1039 base::RunLoop().RunUntilIdle();
1040 EXPECT_THAT(tasks, UnorderedElementsAre()); // loading task does not run
1041
1042 tasks.clear();
1043 page_scheduler_->SetKeepActive(true);
1044 EXPECT_THAT(tasks, UnorderedElementsAre());
1045 base::RunLoop().RunUntilIdle();
1046 // loading task runs
1047 EXPECT_THAT(tasks, UnorderedElementsAre(String(
1048 LoadingTaskQueue()->GetTaskQueue()->GetName())));
1049 }
1050
TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,PageFreezeAndPageVisible)1051 TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,
1052 PageFreezeAndPageVisible) {
1053 int counter = 0;
1054 LoadingTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
1055 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
1056 ThrottleableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
1057 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
1058 DeferrableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
1059 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
1060 PausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
1061 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
1062 UnpausableTaskQueue()->GetTaskRunnerWithDefaultTaskType()->PostTask(
1063 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
1064
1065 page_scheduler_->SetPageVisible(false);
1066 page_scheduler_->SetPageFrozen(true);
1067
1068 EXPECT_EQ(0, counter);
1069 base::RunLoop().RunUntilIdle();
1070 EXPECT_EQ(1, counter);
1071
1072 // Making the page visible should cause frozen queues to resume.
1073 page_scheduler_->SetPageVisible(true);
1074
1075 EXPECT_EQ(1, counter);
1076 base::RunLoop().RunUntilIdle();
1077 EXPECT_EQ(5, counter);
1078 }
1079
1080 class FrameSchedulerImplTestWithUnfreezableLoading
1081 : public FrameSchedulerImplTest {
1082 public:
FrameSchedulerImplTestWithUnfreezableLoading()1083 FrameSchedulerImplTestWithUnfreezableLoading()
1084 : FrameSchedulerImplTest({blink::features::kLoadingTasksUnfreezable},
1085 {}) {}
1086 };
1087
TEST_F(FrameSchedulerImplTestWithUnfreezableLoading,LoadingTasksKeepRunningWhenFrozen)1088 TEST_F(FrameSchedulerImplTestWithUnfreezableLoading,
1089 LoadingTasksKeepRunningWhenFrozen) {
1090 int counter = 0;
1091 UnfreezableLoadingTaskQueue()->GetTaskQueue()->task_runner()->PostTask(
1092 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
1093 LoadingTaskQueue()->GetTaskQueue()->task_runner()->PostTask(
1094 FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
1095
1096 page_scheduler_->SetPageVisible(false);
1097 page_scheduler_->SetPageFrozen(true);
1098
1099 EXPECT_EQ(0, counter);
1100 base::RunLoop().RunUntilIdle();
1101 // Unfreezable tasks continue to run.
1102 EXPECT_EQ(1, counter);
1103
1104 page_scheduler_->SetPageFrozen(false);
1105
1106 EXPECT_EQ(1, counter);
1107 // Same as RunUntilIdle but also advances the clock if necessary.
1108 task_environment_.FastForwardUntilNoTasksRemain();
1109 // Freezable tasks resume.
1110 EXPECT_EQ(2, counter);
1111 }
1112
1113 // Tests if throttling observer interfaces work.
TEST_F(FrameSchedulerImplTest,LifecycleObserver)1114 TEST_F(FrameSchedulerImplTest, LifecycleObserver) {
1115 std::unique_ptr<MockLifecycleObserver> observer =
1116 std::make_unique<MockLifecycleObserver>();
1117
1118 size_t not_throttled_count = 0u;
1119 size_t hidden_count = 0u;
1120 size_t throttled_count = 0u;
1121 size_t stopped_count = 0u;
1122
1123 observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count,
1124 throttled_count, stopped_count);
1125
1126 auto observer_handle = frame_scheduler_->AddLifecycleObserver(
1127 FrameScheduler::ObserverType::kLoader, observer.get());
1128
1129 // Initial state should be synchronously notified here.
1130 // We assume kNotThrottled is notified as an initial state, but it could
1131 // depend on implementation details and can be changed.
1132 observer->CheckObserverState(FROM_HERE, ++not_throttled_count, hidden_count,
1133 throttled_count, stopped_count);
1134
1135 // Once the page gets to be invisible, it should notify the observer of
1136 // kHidden synchronously.
1137 page_scheduler_->SetPageVisible(false);
1138 observer->CheckObserverState(FROM_HERE, not_throttled_count, ++hidden_count,
1139 throttled_count, stopped_count);
1140
1141 // We do not issue new notifications without actually changing visibility
1142 // state.
1143 page_scheduler_->SetPageVisible(false);
1144 observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count,
1145 throttled_count, stopped_count);
1146
1147 task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(30));
1148
1149 // The frame gets throttled after some time in background.
1150 observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count,
1151 ++throttled_count, stopped_count);
1152
1153 // We shouldn't issue new notifications for kThrottled state as well.
1154 page_scheduler_->SetPageVisible(false);
1155 observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count,
1156 throttled_count, stopped_count);
1157
1158 // Setting background page to STOPPED, notifies observers of kStopped.
1159 page_scheduler_->SetPageFrozen(true);
1160 observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count,
1161 throttled_count, ++stopped_count);
1162
1163 // When page is not in the STOPPED state, then page visibility is used,
1164 // notifying observer of kThrottled.
1165 page_scheduler_->SetPageFrozen(false);
1166 observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count,
1167 ++throttled_count, stopped_count);
1168
1169 // Going back to visible state should notify the observer of kNotThrottled
1170 // synchronously.
1171 page_scheduler_->SetPageVisible(true);
1172 observer->CheckObserverState(FROM_HERE, ++not_throttled_count, hidden_count,
1173 throttled_count, stopped_count);
1174
1175 // Remove from the observer list, and see if any other callback should not be
1176 // invoked when the condition is changed.
1177 observer_handle.reset();
1178 page_scheduler_->SetPageVisible(false);
1179
1180 // Wait 100 secs virtually and run pending tasks just in case.
1181 task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(100));
1182 base::RunLoop().RunUntilIdle();
1183
1184 observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count,
1185 throttled_count, stopped_count);
1186 }
1187
TEST_F(FrameSchedulerImplTest,DefaultSchedulingLifecycleState)1188 TEST_F(FrameSchedulerImplTest, DefaultSchedulingLifecycleState) {
1189 EXPECT_EQ(CalculateLifecycleState(FrameScheduler::ObserverType::kLoader),
1190 SchedulingLifecycleState::kNotThrottled);
1191 EXPECT_EQ(
1192 CalculateLifecycleState(FrameScheduler::ObserverType::kWorkerScheduler),
1193 SchedulingLifecycleState::kNotThrottled);
1194 }
1195
TEST_F(FrameSchedulerImplTest,SubesourceLoadingPaused)1196 TEST_F(FrameSchedulerImplTest, SubesourceLoadingPaused) {
1197 // A loader observer and related counts.
1198 std::unique_ptr<MockLifecycleObserver> loader_observer =
1199 std::make_unique<MockLifecycleObserver>();
1200
1201 size_t loader_throttled_count = 0u;
1202 size_t loader_not_throttled_count = 0u;
1203 size_t loader_hidden_count = 0u;
1204 size_t loader_stopped_count = 0u;
1205
1206 // A worker observer and related counts.
1207 std::unique_ptr<MockLifecycleObserver> worker_observer =
1208 std::make_unique<MockLifecycleObserver>();
1209
1210 size_t worker_throttled_count = 0u;
1211 size_t worker_not_throttled_count = 0u;
1212 size_t worker_hidden_count = 0u;
1213 size_t worker_stopped_count = 0u;
1214
1215 // Both observers should start with no responses.
1216 loader_observer->CheckObserverState(
1217 FROM_HERE, loader_not_throttled_count, loader_hidden_count,
1218 loader_throttled_count, loader_stopped_count);
1219
1220 worker_observer->CheckObserverState(
1221 FROM_HERE, worker_not_throttled_count, worker_hidden_count,
1222 worker_throttled_count, worker_stopped_count);
1223
1224 // Adding the observers should recieve a non-throttled response
1225 auto loader_observer_handle = frame_scheduler_->AddLifecycleObserver(
1226 FrameScheduler::ObserverType::kLoader, loader_observer.get());
1227
1228 auto worker_observer_handle = frame_scheduler_->AddLifecycleObserver(
1229 FrameScheduler::ObserverType::kWorkerScheduler, worker_observer.get());
1230
1231 loader_observer->CheckObserverState(
1232 FROM_HERE, ++loader_not_throttled_count, loader_hidden_count,
1233 loader_throttled_count, loader_stopped_count);
1234
1235 worker_observer->CheckObserverState(
1236 FROM_HERE, ++worker_not_throttled_count, worker_hidden_count,
1237 worker_throttled_count, worker_stopped_count);
1238
1239 {
1240 auto pause_handle_a = frame_scheduler_->GetPauseSubresourceLoadingHandle();
1241
1242 loader_observer->CheckObserverState(
1243 FROM_HERE, loader_not_throttled_count, loader_hidden_count,
1244 loader_throttled_count, ++loader_stopped_count);
1245
1246 worker_observer->CheckObserverState(
1247 FROM_HERE, ++worker_not_throttled_count, worker_hidden_count,
1248 worker_throttled_count, worker_stopped_count);
1249
1250 std::unique_ptr<MockLifecycleObserver> loader_observer_added_after_stopped =
1251 std::make_unique<MockLifecycleObserver>();
1252
1253 auto loader_observer_added_after_stopped_handle =
1254 frame_scheduler_->AddLifecycleObserver(
1255 FrameScheduler::ObserverType::kLoader,
1256 loader_observer_added_after_stopped.get());
1257 // This observer should see stopped when added.
1258 loader_observer_added_after_stopped->CheckObserverState(FROM_HERE, 0, 0, 0,
1259 1u);
1260
1261 // Adding another handle should not create a new state.
1262 auto pause_handle_b = frame_scheduler_->GetPauseSubresourceLoadingHandle();
1263
1264 loader_observer->CheckObserverState(
1265 FROM_HERE, loader_not_throttled_count, loader_hidden_count,
1266 loader_throttled_count, loader_stopped_count);
1267
1268 worker_observer->CheckObserverState(
1269 FROM_HERE, worker_not_throttled_count, worker_hidden_count,
1270 worker_throttled_count, worker_stopped_count);
1271 }
1272
1273 // Removing the handles should return the state to non throttled.
1274 loader_observer->CheckObserverState(
1275 FROM_HERE, ++loader_not_throttled_count, loader_hidden_count,
1276 loader_throttled_count, loader_stopped_count);
1277
1278 worker_observer->CheckObserverState(
1279 FROM_HERE, ++worker_not_throttled_count, worker_hidden_count,
1280 worker_throttled_count, worker_stopped_count);
1281 }
1282
TEST_F(FrameSchedulerImplTest,LogIpcsPostedToFramesInBackForwardCache)1283 TEST_F(FrameSchedulerImplTest, LogIpcsPostedToFramesInBackForwardCache) {
1284 base::HistogramTester histogram_tester;
1285
1286 // Create the task queue implicitly.
1287 const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
1288 frame_scheduler_->GetTaskRunner(TaskType::kInternalTest);
1289
1290 StorePageInBackForwardCache();
1291
1292 // Run the tasks so that they are recorded in the histogram
1293 task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
1294
1295 // Post IPC tasks, accounting for delay for when tracking starts.
1296 {
1297 base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(1);
1298 task_runner->PostTask(FROM_HERE, base::DoNothing());
1299 }
1300 {
1301 base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash_2(2);
1302 task_runner->PostTask(FROM_HERE, base::DoNothing());
1303 }
1304 task_environment_.RunUntilIdle();
1305
1306 // Once the page is restored from the cache, IPCs should no longer be
1307 // recorded.
1308 RestorePageFromBackForwardCache();
1309
1310 // Start posting tasks immediately - will not be recorded
1311 {
1312 base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash_3(3);
1313 task_runner->PostTask(FROM_HERE, base::DoNothing());
1314 }
1315 {
1316 base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash_4(4);
1317 task_runner->PostTask(FROM_HERE, base::DoNothing());
1318 }
1319
1320 EXPECT_THAT(
1321 histogram_tester.GetAllSamples(
1322 "BackForwardCache.Experimental."
1323 "UnexpectedIPCMessagePostedToCachedFrame.MethodHash"),
1324 testing::UnorderedElementsAre(base::Bucket(1, 1), base::Bucket(2, 1)));
1325
1326 // TimeUntilIPCReceived should have values in the 300000 bucket corresponding
1327 // with the hour delay in task_environment_.FastForwardBy.
1328 EXPECT_THAT(
1329 histogram_tester.GetAllSamples(
1330 "BackForwardCache.Experimental."
1331 "UnexpectedIPCMessagePostedToCachedFrame.TimeUntilIPCReceived"),
1332 testing::UnorderedElementsAre(base::Bucket(300000, 2)));
1333 }
1334
TEST_F(FrameSchedulerImplTest,LogIpcsFromMultipleThreadsPostedToFramesInBackForwardCache)1335 TEST_F(FrameSchedulerImplTest,
1336 LogIpcsFromMultipleThreadsPostedToFramesInBackForwardCache) {
1337 base::HistogramTester histogram_tester;
1338
1339 // Create the task queue explicitly to ensure it exists when the page enters
1340 // the back-forward cache, and that the IPC handler is registerd as well.
1341 const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
1342 frame_scheduler_->GetTaskRunner(TaskType::kInternalTest);
1343
1344 StorePageInBackForwardCache();
1345
1346 // Run the tasks so that they are recorded in the histogram
1347 task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
1348
1349 base::ThreadPool::PostTask(
1350 FROM_HERE,
1351 base::BindOnce(
1352 [](scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
1353 base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(1);
1354 task_runner->PostTask(FROM_HERE, base::DoNothing());
1355 },
1356 task_runner));
1357 task_environment_.RunUntilIdle();
1358
1359 base::RepeatingClosure restore_from_cache_callback = base::BindRepeating(
1360 &FrameSchedulerImplTest::RestorePageFromBackForwardCache,
1361 base::Unretained(this));
1362
1363 base::ThreadPool::PostTask(
1364 FROM_HERE,
1365 base::BindOnce(
1366 [](scoped_refptr<base::SingleThreadTaskRunner> task_runner,
1367 base::RepeatingClosure restore_from_cache_callback) {
1368 {
1369 base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(2);
1370 task_runner->PostTask(FROM_HERE, base::DoNothing());
1371 }
1372 {
1373 // Once the page is restored from the cache, ensure that the IPC
1374 // restoring the page from the cache is not recorded as well.
1375 base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(3);
1376 task_runner->PostTask(FROM_HERE, restore_from_cache_callback);
1377 }
1378 {
1379 base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(4);
1380 task_runner->PostTask(FROM_HERE, base::DoNothing());
1381 }
1382 },
1383 task_runner, restore_from_cache_callback));
1384 task_environment_.RunUntilIdle();
1385
1386 // Start posting tasks immediately - will not be recorded
1387 base::ThreadPool::PostTask(
1388 FROM_HERE,
1389 base::BindOnce(
1390 [](scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
1391 base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(5);
1392 task_runner->PostTask(FROM_HERE, base::DoNothing());
1393 },
1394 task_runner));
1395 task_environment_.RunUntilIdle();
1396
1397 base::ThreadPool::PostTask(
1398 FROM_HERE,
1399 base::BindOnce(
1400 [](scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
1401 base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(6);
1402 task_runner->PostTask(FROM_HERE, base::DoNothing());
1403 },
1404 task_runner));
1405 task_environment_.RunUntilIdle();
1406
1407 EXPECT_THAT(
1408 histogram_tester.GetAllSamples(
1409 "BackForwardCache.Experimental."
1410 "UnexpectedIPCMessagePostedToCachedFrame.MethodHash"),
1411 testing::UnorderedElementsAre(base::Bucket(1, 1), base::Bucket(2, 1)));
1412 }
1413
1414 // TODO(farahcharab) Move priority testing to MainThreadTaskQueueTest after
1415 // landing the change that moves priority computation to MainThreadTaskQueue.
1416
1417 class LowPriorityBackgroundPageExperimentTest : public FrameSchedulerImplTest {
1418 public:
LowPriorityBackgroundPageExperimentTest()1419 LowPriorityBackgroundPageExperimentTest()
1420 : FrameSchedulerImplTest({kLowPriorityForBackgroundPages}, {}) {}
1421 };
1422
TEST_F(LowPriorityBackgroundPageExperimentTest,FrameQueuesPriorities)1423 TEST_F(LowPriorityBackgroundPageExperimentTest, FrameQueuesPriorities) {
1424 page_scheduler_->SetPageVisible(false);
1425 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1426 TaskQueue::QueuePriority::kLowPriority);
1427 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1428 TaskQueue::QueuePriority::kLowPriority);
1429 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1430 TaskQueue::QueuePriority::kLowPriority);
1431 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1432 TaskQueue::QueuePriority::kLowPriority);
1433 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1434 TaskQueue::QueuePriority::kLowPriority);
1435 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1436 TaskQueue::QueuePriority::kLowPriority);
1437
1438 page_scheduler_->AudioStateChanged(true);
1439 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1440 TaskQueue::QueuePriority::kNormalPriority);
1441 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1442 TaskQueue::QueuePriority::kHighPriority);
1443 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1444 TaskQueue::QueuePriority::kNormalPriority);
1445 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1446 TaskQueue::QueuePriority::kNormalPriority);
1447 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1448 TaskQueue::QueuePriority::kNormalPriority);
1449 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1450 TaskQueue::QueuePriority::kNormalPriority);
1451
1452 page_scheduler_->AudioStateChanged(false);
1453 page_scheduler_->SetPageVisible(true);
1454 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1455 TaskQueue::QueuePriority::kNormalPriority);
1456 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1457 TaskQueue::QueuePriority::kHighPriority);
1458 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1459 TaskQueue::QueuePriority::kNormalPriority);
1460 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1461 TaskQueue::QueuePriority::kNormalPriority);
1462 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1463 TaskQueue::QueuePriority::kNormalPriority);
1464 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1465 TaskQueue::QueuePriority::kNormalPriority);
1466 }
1467
1468 class BestEffortPriorityBackgroundPageExperimentTest
1469 : public FrameSchedulerImplTest {
1470 public:
BestEffortPriorityBackgroundPageExperimentTest()1471 BestEffortPriorityBackgroundPageExperimentTest()
1472 : FrameSchedulerImplTest({kBestEffortPriorityForBackgroundPages}, {}) {}
1473 };
1474
TEST_F(BestEffortPriorityBackgroundPageExperimentTest,FrameQueuesPriorities)1475 TEST_F(BestEffortPriorityBackgroundPageExperimentTest, FrameQueuesPriorities) {
1476 page_scheduler_->SetPageVisible(false);
1477 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1478 TaskQueue::QueuePriority::kBestEffortPriority);
1479 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1480 TaskQueue::QueuePriority::kBestEffortPriority);
1481 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1482 TaskQueue::QueuePriority::kBestEffortPriority);
1483 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1484 TaskQueue::QueuePriority::kBestEffortPriority);
1485 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1486 TaskQueue::QueuePriority::kBestEffortPriority);
1487 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1488 TaskQueue::QueuePriority::kBestEffortPriority);
1489
1490 page_scheduler_->AudioStateChanged(true);
1491 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1492 TaskQueue::QueuePriority::kNormalPriority);
1493 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1494 TaskQueue::QueuePriority::kHighPriority);
1495 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1496 TaskQueue::QueuePriority::kNormalPriority);
1497 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1498 TaskQueue::QueuePriority::kNormalPriority);
1499 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1500 TaskQueue::QueuePriority::kNormalPriority);
1501 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1502 TaskQueue::QueuePriority::kNormalPriority);
1503
1504 page_scheduler_->AudioStateChanged(false);
1505 page_scheduler_->SetPageVisible(true);
1506 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1507 TaskQueue::QueuePriority::kNormalPriority);
1508 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1509 TaskQueue::QueuePriority::kHighPriority);
1510 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1511 TaskQueue::QueuePriority::kNormalPriority);
1512 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1513 TaskQueue::QueuePriority::kNormalPriority);
1514 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1515 TaskQueue::QueuePriority::kNormalPriority);
1516 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1517 TaskQueue::QueuePriority::kNormalPriority);
1518 }
1519
1520 class LowPriorityHiddenFrameExperimentTest : public FrameSchedulerImplTest {
1521 public:
LowPriorityHiddenFrameExperimentTest()1522 LowPriorityHiddenFrameExperimentTest()
1523 : FrameSchedulerImplTest({kLowPriorityForHiddenFrame},
1524 {kFrameExperimentOnlyWhenLoading}) {}
1525 };
1526
TEST_F(LowPriorityHiddenFrameExperimentTest,FrameQueuesPriorities)1527 TEST_F(LowPriorityHiddenFrameExperimentTest, FrameQueuesPriorities) {
1528 // Hidden Frame Task Queues.
1529 frame_scheduler_->SetFrameVisible(false);
1530 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1531 TaskQueue::QueuePriority::kLowPriority);
1532 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1533 TaskQueue::QueuePriority::kLowPriority);
1534 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1535 TaskQueue::QueuePriority::kLowPriority);
1536 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1537 TaskQueue::QueuePriority::kLowPriority);
1538 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1539 TaskQueue::QueuePriority::kLowPriority);
1540 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1541 TaskQueue::QueuePriority::kLowPriority);
1542
1543 // Visible Frame Task Queues.
1544 frame_scheduler_->SetFrameVisible(true);
1545 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1546 TaskQueue::QueuePriority::kNormalPriority);
1547 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1548 TaskQueue::QueuePriority::kHighPriority);
1549 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1550 TaskQueue::QueuePriority::kNormalPriority);
1551 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1552 TaskQueue::QueuePriority::kNormalPriority);
1553 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1554 TaskQueue::QueuePriority::kNormalPriority);
1555 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1556 TaskQueue::QueuePriority::kNormalPriority);
1557 }
1558
1559 class LowPriorityHiddenFrameDuringLoadingExperimentTest
1560 : public FrameSchedulerImplTest {
1561 public:
LowPriorityHiddenFrameDuringLoadingExperimentTest()1562 LowPriorityHiddenFrameDuringLoadingExperimentTest()
1563 : FrameSchedulerImplTest(
1564 {kLowPriorityForHiddenFrame, kFrameExperimentOnlyWhenLoading},
1565 {}) {}
1566 };
1567
TEST_F(LowPriorityHiddenFrameDuringLoadingExperimentTest,FrameQueuesPriorities)1568 TEST_F(LowPriorityHiddenFrameDuringLoadingExperimentTest,
1569 FrameQueuesPriorities) {
1570 // Main thread scheduler is in the loading use case.
1571 std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
1572 CreateFrameScheduler(page_scheduler_.get(),
1573 frame_scheduler_delegate_.get(), nullptr,
1574 FrameScheduler::FrameType::kMainFrame);
1575 main_frame_scheduler->OnFirstContentfulPaint();
1576 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
1577
1578 // Hidden Frame Task Queues.
1579 frame_scheduler_->SetFrameVisible(false);
1580 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1581 TaskQueue::QueuePriority::kLowPriority);
1582 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1583 TaskQueue::QueuePriority::kLowPriority);
1584 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1585 TaskQueue::QueuePriority::kLowPriority);
1586 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1587 TaskQueue::QueuePriority::kLowPriority);
1588 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1589 TaskQueue::QueuePriority::kLowPriority);
1590 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1591 TaskQueue::QueuePriority::kLowPriority);
1592
1593 // Main thread scheduler is no longer in loading use case.
1594 main_frame_scheduler->OnFirstMeaningfulPaint();
1595 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kNone);
1596 EXPECT_FALSE(page_scheduler_->IsLoading());
1597
1598 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1599 TaskQueue::QueuePriority::kNormalPriority);
1600 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1601 TaskQueue::QueuePriority::kHighPriority);
1602 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1603 TaskQueue::QueuePriority::kNormalPriority);
1604 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1605 TaskQueue::QueuePriority::kNormalPriority);
1606 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1607 TaskQueue::QueuePriority::kNormalPriority);
1608 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1609 TaskQueue::QueuePriority::kNormalPriority);
1610 }
1611
1612 class LowPrioritySubFrameExperimentTest : public FrameSchedulerImplTest {
1613 public:
LowPrioritySubFrameExperimentTest()1614 LowPrioritySubFrameExperimentTest()
1615 : FrameSchedulerImplTest({kLowPriorityForSubFrame},
1616 {kFrameExperimentOnlyWhenLoading}) {}
1617 };
1618
TEST_F(LowPrioritySubFrameExperimentTest,FrameQueuesPriorities)1619 TEST_F(LowPrioritySubFrameExperimentTest, FrameQueuesPriorities) {
1620 // Sub-Frame Task Queues.
1621 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1622 TaskQueue::QueuePriority::kLowPriority);
1623 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1624 TaskQueue::QueuePriority::kLowPriority);
1625 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1626 TaskQueue::QueuePriority::kLowPriority);
1627 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1628 TaskQueue::QueuePriority::kLowPriority);
1629 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1630 TaskQueue::QueuePriority::kLowPriority);
1631 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1632 TaskQueue::QueuePriority::kLowPriority);
1633
1634 frame_scheduler_ =
1635 CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
1636 FrameScheduler::FrameType::kMainFrame);
1637
1638 // Main Frame Task Queues.
1639 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1640 TaskQueue::QueuePriority::kNormalPriority);
1641 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1642 TaskQueue::QueuePriority::kHighPriority);
1643 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1644 TaskQueue::QueuePriority::kNormalPriority);
1645 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1646 TaskQueue::QueuePriority::kNormalPriority);
1647 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1648 TaskQueue::QueuePriority::kNormalPriority);
1649 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1650 TaskQueue::QueuePriority::kNormalPriority);
1651 }
1652
1653 class LowPrioritySubFrameDuringLoadingExperimentTest
1654 : public FrameSchedulerImplTest {
1655 public:
LowPrioritySubFrameDuringLoadingExperimentTest()1656 LowPrioritySubFrameDuringLoadingExperimentTest()
1657 : FrameSchedulerImplTest(
1658 {kLowPriorityForSubFrame, kFrameExperimentOnlyWhenLoading},
1659 {}) {}
1660 };
1661
TEST_F(LowPrioritySubFrameDuringLoadingExperimentTest,FrameQueuesPriorities)1662 TEST_F(LowPrioritySubFrameDuringLoadingExperimentTest, FrameQueuesPriorities) {
1663 // Main thread scheduler is in the loading use case.
1664 std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
1665 CreateFrameScheduler(page_scheduler_.get(),
1666 frame_scheduler_delegate_.get(), nullptr,
1667 FrameScheduler::FrameType::kMainFrame);
1668 main_frame_scheduler->OnFirstContentfulPaint();
1669 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
1670
1671 // Sub-Frame Task Queues.
1672 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1673 TaskQueue::QueuePriority::kLowPriority);
1674 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1675 TaskQueue::QueuePriority::kLowPriority);
1676 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1677 TaskQueue::QueuePriority::kLowPriority);
1678 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1679 TaskQueue::QueuePriority::kLowPriority);
1680 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1681 TaskQueue::QueuePriority::kLowPriority);
1682 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1683 TaskQueue::QueuePriority::kLowPriority);
1684
1685 // Main thread scheduler is no longer in loading use case.
1686 main_frame_scheduler->OnFirstMeaningfulPaint();
1687 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kNone);
1688 EXPECT_FALSE(page_scheduler_->IsLoading());
1689
1690 // Sub-Frame Task Queues.
1691 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1692 TaskQueue::QueuePriority::kNormalPriority);
1693 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1694 TaskQueue::QueuePriority::kHighPriority);
1695 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1696 TaskQueue::QueuePriority::kNormalPriority);
1697 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1698 TaskQueue::QueuePriority::kNormalPriority);
1699 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1700 TaskQueue::QueuePriority::kNormalPriority);
1701 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1702 TaskQueue::QueuePriority::kNormalPriority);
1703 }
1704
1705 class LowPrioritySubFrameThrottleableTaskExperimentTest
1706 : public FrameSchedulerImplTest {
1707 public:
LowPrioritySubFrameThrottleableTaskExperimentTest()1708 LowPrioritySubFrameThrottleableTaskExperimentTest()
1709 : FrameSchedulerImplTest({kLowPriorityForSubFrameThrottleableTask},
1710 {kFrameExperimentOnlyWhenLoading}) {}
1711 };
1712
TEST_F(LowPrioritySubFrameThrottleableTaskExperimentTest,FrameQueuesPriorities)1713 TEST_F(LowPrioritySubFrameThrottleableTaskExperimentTest,
1714 FrameQueuesPriorities) {
1715 // Sub-Frame Task Queues.
1716 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1717 TaskQueue::QueuePriority::kNormalPriority);
1718 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1719 TaskQueue::QueuePriority::kHighPriority);
1720 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1721 TaskQueue::QueuePriority::kNormalPriority);
1722 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1723 TaskQueue::QueuePriority::kLowPriority);
1724 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1725 TaskQueue::QueuePriority::kNormalPriority);
1726 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1727 TaskQueue::QueuePriority::kNormalPriority);
1728
1729 frame_scheduler_ =
1730 CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
1731 FrameScheduler::FrameType::kMainFrame);
1732
1733 // Main Frame Task Queues.
1734 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1735 TaskQueue::QueuePriority::kNormalPriority);
1736 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1737 TaskQueue::QueuePriority::kHighPriority);
1738 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1739 TaskQueue::QueuePriority::kNormalPriority);
1740 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1741 TaskQueue::QueuePriority::kNormalPriority);
1742 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1743 TaskQueue::QueuePriority::kNormalPriority);
1744 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1745 TaskQueue::QueuePriority::kNormalPriority);
1746 }
1747
1748 class LowPrioritySubFrameThrottleableTaskDuringLoadingExperimentTest
1749 : public FrameSchedulerImplTest {
1750 public:
LowPrioritySubFrameThrottleableTaskDuringLoadingExperimentTest()1751 LowPrioritySubFrameThrottleableTaskDuringLoadingExperimentTest()
1752 : FrameSchedulerImplTest({kLowPriorityForSubFrameThrottleableTask,
1753 kFrameExperimentOnlyWhenLoading},
1754 {}) {}
1755 };
1756
TEST_F(LowPrioritySubFrameThrottleableTaskDuringLoadingExperimentTest,FrameQueuesPriorities)1757 TEST_F(LowPrioritySubFrameThrottleableTaskDuringLoadingExperimentTest,
1758 FrameQueuesPriorities) {
1759 // Main thread scheduler is in the loading use case.
1760 std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
1761 CreateFrameScheduler(page_scheduler_.get(),
1762 frame_scheduler_delegate_.get(), nullptr,
1763 FrameScheduler::FrameType::kMainFrame);
1764 main_frame_scheduler->OnFirstContentfulPaint();
1765 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
1766
1767 // Sub-Frame Task Queues.
1768 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1769 TaskQueue::QueuePriority::kNormalPriority);
1770 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1771 TaskQueue::QueuePriority::kHighPriority);
1772 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1773 TaskQueue::QueuePriority::kNormalPriority);
1774 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1775 TaskQueue::QueuePriority::kLowPriority);
1776 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1777 TaskQueue::QueuePriority::kNormalPriority);
1778 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1779 TaskQueue::QueuePriority::kNormalPriority);
1780
1781 // Main thread scheduler is no longer in loading use case.
1782 main_frame_scheduler->OnFirstMeaningfulPaint();
1783 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kNone);
1784 EXPECT_FALSE(page_scheduler_->IsLoading());
1785
1786 // Sub-Frame Task Queues.
1787 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1788 TaskQueue::QueuePriority::kNormalPriority);
1789 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1790 TaskQueue::QueuePriority::kHighPriority);
1791 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1792 TaskQueue::QueuePriority::kNormalPriority);
1793 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1794 TaskQueue::QueuePriority::kNormalPriority);
1795 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1796 TaskQueue::QueuePriority::kNormalPriority);
1797 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1798 TaskQueue::QueuePriority::kNormalPriority);
1799 }
1800
1801 class LowPriorityThrottleableTaskExperimentTest
1802 : public FrameSchedulerImplTest {
1803 public:
LowPriorityThrottleableTaskExperimentTest()1804 LowPriorityThrottleableTaskExperimentTest()
1805 : FrameSchedulerImplTest({kLowPriorityForThrottleableTask},
1806 {kFrameExperimentOnlyWhenLoading}) {}
1807 };
1808
TEST_F(LowPriorityThrottleableTaskExperimentTest,FrameQueuesPriorities)1809 TEST_F(LowPriorityThrottleableTaskExperimentTest, FrameQueuesPriorities) {
1810 // Sub-Frame Task Queues.
1811 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1812 TaskQueue::QueuePriority::kNormalPriority);
1813 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1814 TaskQueue::QueuePriority::kHighPriority);
1815 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1816 TaskQueue::QueuePriority::kNormalPriority);
1817 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1818 TaskQueue::QueuePriority::kLowPriority);
1819 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1820 TaskQueue::QueuePriority::kNormalPriority);
1821 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1822 TaskQueue::QueuePriority::kNormalPriority);
1823
1824 frame_scheduler_ =
1825 CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
1826 FrameScheduler::FrameType::kMainFrame);
1827
1828 // Main Frame Task Queues.
1829 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1830 TaskQueue::QueuePriority::kNormalPriority);
1831 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1832 TaskQueue::QueuePriority::kHighPriority);
1833 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1834 TaskQueue::QueuePriority::kNormalPriority);
1835 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1836 TaskQueue::QueuePriority::kLowPriority);
1837 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1838 TaskQueue::QueuePriority::kNormalPriority);
1839 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1840 TaskQueue::QueuePriority::kNormalPriority);
1841 }
1842
1843 class LowPriorityThrottleableTaskDuringLoadingExperimentTest
1844 : public FrameSchedulerImplTest {
1845 public:
LowPriorityThrottleableTaskDuringLoadingExperimentTest()1846 LowPriorityThrottleableTaskDuringLoadingExperimentTest()
1847 : FrameSchedulerImplTest(
1848 {kLowPriorityForThrottleableTask, kFrameExperimentOnlyWhenLoading},
1849 {}) {}
1850 };
1851
TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,SubFrameQueuesPriorities)1852 TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,
1853 SubFrameQueuesPriorities) {
1854 // Main thread is in the loading use case.
1855 std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
1856 CreateFrameScheduler(page_scheduler_.get(),
1857 frame_scheduler_delegate_.get(), nullptr,
1858 FrameScheduler::FrameType::kMainFrame);
1859 main_frame_scheduler->OnFirstContentfulPaint();
1860 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
1861
1862 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1863 TaskQueue::QueuePriority::kNormalPriority);
1864 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1865 TaskQueue::QueuePriority::kHighPriority);
1866 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1867 TaskQueue::QueuePriority::kNormalPriority);
1868 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1869 TaskQueue::QueuePriority::kLowPriority);
1870 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1871 TaskQueue::QueuePriority::kNormalPriority);
1872 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1873 TaskQueue::QueuePriority::kNormalPriority);
1874
1875 // Main thread is no longer in loading use case.
1876 main_frame_scheduler->OnFirstMeaningfulPaint();
1877 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kNone);
1878
1879 EXPECT_FALSE(page_scheduler_->IsLoading());
1880
1881 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1882 TaskQueue::QueuePriority::kNormalPriority);
1883 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1884 TaskQueue::QueuePriority::kHighPriority);
1885 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1886 TaskQueue::QueuePriority::kNormalPriority);
1887 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1888 TaskQueue::QueuePriority::kNormalPriority);
1889 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1890 TaskQueue::QueuePriority::kNormalPriority);
1891 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1892 TaskQueue::QueuePriority::kNormalPriority);
1893 }
1894
TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,MainFrameQueuesPriorities)1895 TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,
1896 MainFrameQueuesPriorities) {
1897 frame_scheduler_->OnFirstContentfulPaint();
1898 frame_scheduler_->OnFirstMeaningfulPaint();
1899
1900 frame_scheduler_ =
1901 CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
1902 FrameScheduler::FrameType::kMainFrame);
1903
1904 // Main thread is in the loading use case.
1905 frame_scheduler_->OnFirstContentfulPaint();
1906
1907 // Main Frame Task Queues.
1908 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1909 TaskQueue::QueuePriority::kNormalPriority);
1910 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1911 TaskQueue::QueuePriority::kHighPriority);
1912 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1913 TaskQueue::QueuePriority::kNormalPriority);
1914 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1915 TaskQueue::QueuePriority::kLowPriority);
1916 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1917 TaskQueue::QueuePriority::kNormalPriority);
1918 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1919 TaskQueue::QueuePriority::kNormalPriority);
1920
1921 // Main thread is no longer in loading use case.
1922 frame_scheduler_->OnFirstMeaningfulPaint();
1923 EXPECT_FALSE(page_scheduler_->IsLoading());
1924
1925 // Main Frame Task Queues.
1926 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1927 TaskQueue::QueuePriority::kNormalPriority);
1928 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1929 TaskQueue::QueuePriority::kHighPriority);
1930 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1931 TaskQueue::QueuePriority::kNormalPriority);
1932 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1933 TaskQueue::QueuePriority::kNormalPriority);
1934 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1935 TaskQueue::QueuePriority::kNormalPriority);
1936 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1937 TaskQueue::QueuePriority::kNormalPriority);
1938 }
1939
1940 class LowPriorityAdFrameExperimentTest : public FrameSchedulerImplTest {
1941 public:
LowPriorityAdFrameExperimentTest()1942 LowPriorityAdFrameExperimentTest()
1943 : FrameSchedulerImplTest({kLowPriorityForAdFrame},
1944 {kAdFrameExperimentOnlyWhenLoading}) {}
1945 };
1946
TEST_F(LowPriorityAdFrameExperimentTest,FrameQueuesPriorities)1947 TEST_F(LowPriorityAdFrameExperimentTest, FrameQueuesPriorities) {
1948 EXPECT_FALSE(frame_scheduler_->IsAdFrame());
1949
1950 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1951 TaskQueue::QueuePriority::kNormalPriority);
1952 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1953 TaskQueue::QueuePriority::kHighPriority);
1954 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1955 TaskQueue::QueuePriority::kNormalPriority);
1956 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1957 TaskQueue::QueuePriority::kNormalPriority);
1958 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1959 TaskQueue::QueuePriority::kNormalPriority);
1960 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1961 TaskQueue::QueuePriority::kNormalPriority);
1962
1963 frame_scheduler_->SetIsAdFrame();
1964
1965 EXPECT_TRUE(frame_scheduler_->IsAdFrame());
1966
1967 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1968 TaskQueue::QueuePriority::kLowPriority);
1969 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1970 TaskQueue::QueuePriority::kLowPriority);
1971 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1972 TaskQueue::QueuePriority::kLowPriority);
1973 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1974 TaskQueue::QueuePriority::kLowPriority);
1975 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1976 TaskQueue::QueuePriority::kLowPriority);
1977 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
1978 TaskQueue::QueuePriority::kLowPriority);
1979 }
1980
1981 class LowPriorityAdFrameDuringLoadingExperimentTest
1982 : public FrameSchedulerImplTest {
1983 public:
LowPriorityAdFrameDuringLoadingExperimentTest()1984 LowPriorityAdFrameDuringLoadingExperimentTest()
1985 : FrameSchedulerImplTest(
1986 {kLowPriorityForAdFrame, kAdFrameExperimentOnlyWhenLoading},
1987 {}) {}
1988 };
1989
TEST_F(LowPriorityAdFrameDuringLoadingExperimentTest,FrameQueuesPriorities)1990 TEST_F(LowPriorityAdFrameDuringLoadingExperimentTest, FrameQueuesPriorities) {
1991 frame_scheduler_->SetIsAdFrame();
1992
1993 EXPECT_TRUE(frame_scheduler_->IsAdFrame());
1994
1995 // Main thread scheduler is in the loading use case.
1996 std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
1997 CreateFrameScheduler(page_scheduler_.get(),
1998 frame_scheduler_delegate_.get(), nullptr,
1999 FrameScheduler::FrameType::kMainFrame);
2000 main_frame_scheduler->OnFirstContentfulPaint();
2001 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
2002
2003 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2004 TaskQueue::QueuePriority::kLowPriority);
2005 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2006 TaskQueue::QueuePriority::kLowPriority);
2007 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2008 TaskQueue::QueuePriority::kLowPriority);
2009 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2010 TaskQueue::QueuePriority::kLowPriority);
2011 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2012 TaskQueue::QueuePriority::kLowPriority);
2013 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2014 TaskQueue::QueuePriority::kLowPriority);
2015
2016 // Main thread scheduler is no longer in loading use case.
2017 main_frame_scheduler->OnFirstMeaningfulPaint();
2018 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kNone);
2019
2020 EXPECT_FALSE(page_scheduler_->IsLoading());
2021
2022 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2023 TaskQueue::QueuePriority::kNormalPriority);
2024 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2025 TaskQueue::QueuePriority::kHighPriority);
2026 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2027 TaskQueue::QueuePriority::kNormalPriority);
2028 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2029 TaskQueue::QueuePriority::kNormalPriority);
2030 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2031 TaskQueue::QueuePriority::kNormalPriority);
2032 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2033 TaskQueue::QueuePriority::kNormalPriority);
2034 }
2035
2036 class BestEffortPriorityAdFrameExperimentTest : public FrameSchedulerImplTest {
2037 public:
BestEffortPriorityAdFrameExperimentTest()2038 BestEffortPriorityAdFrameExperimentTest()
2039 : FrameSchedulerImplTest({kBestEffortPriorityForAdFrame},
2040 {kAdFrameExperimentOnlyWhenLoading}) {}
2041 };
2042
TEST_F(BestEffortPriorityAdFrameExperimentTest,FrameQueuesPriorities)2043 TEST_F(BestEffortPriorityAdFrameExperimentTest, FrameQueuesPriorities) {
2044 EXPECT_FALSE(frame_scheduler_->IsAdFrame());
2045
2046 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2047 TaskQueue::QueuePriority::kNormalPriority);
2048 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2049 TaskQueue::QueuePriority::kHighPriority);
2050 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2051 TaskQueue::QueuePriority::kNormalPriority);
2052 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2053 TaskQueue::QueuePriority::kNormalPriority);
2054 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2055 TaskQueue::QueuePriority::kNormalPriority);
2056 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2057 TaskQueue::QueuePriority::kNormalPriority);
2058
2059 frame_scheduler_->SetIsAdFrame();
2060
2061 EXPECT_TRUE(frame_scheduler_->IsAdFrame());
2062
2063 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2064 TaskQueue::QueuePriority::kBestEffortPriority);
2065 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2066 TaskQueue::QueuePriority::kBestEffortPriority);
2067 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2068 TaskQueue::QueuePriority::kBestEffortPriority);
2069 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2070 TaskQueue::QueuePriority::kBestEffortPriority);
2071 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2072 TaskQueue::QueuePriority::kBestEffortPriority);
2073 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2074 TaskQueue::QueuePriority::kBestEffortPriority);
2075 }
2076
2077 class BestEffortPriorityAdFrameDuringLoadingExperimentTest
2078 : public FrameSchedulerImplTest {
2079 public:
BestEffortPriorityAdFrameDuringLoadingExperimentTest()2080 BestEffortPriorityAdFrameDuringLoadingExperimentTest()
2081 : FrameSchedulerImplTest(
2082 {kBestEffortPriorityForAdFrame, kAdFrameExperimentOnlyWhenLoading},
2083 {}) {}
2084 };
2085
TEST_F(BestEffortPriorityAdFrameDuringLoadingExperimentTest,FrameQueuesPriorities)2086 TEST_F(BestEffortPriorityAdFrameDuringLoadingExperimentTest,
2087 FrameQueuesPriorities) {
2088 frame_scheduler_->SetIsAdFrame();
2089
2090 EXPECT_TRUE(frame_scheduler_->IsAdFrame());
2091
2092 // Main thread scheduler is in the loading use case.
2093 std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
2094 CreateFrameScheduler(page_scheduler_.get(),
2095 frame_scheduler_delegate_.get(), nullptr,
2096 FrameScheduler::FrameType::kMainFrame);
2097 main_frame_scheduler->OnFirstContentfulPaint();
2098 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
2099
2100 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2101 TaskQueue::QueuePriority::kBestEffortPriority);
2102 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2103 TaskQueue::QueuePriority::kBestEffortPriority);
2104 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2105 TaskQueue::QueuePriority::kBestEffortPriority);
2106 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2107 TaskQueue::QueuePriority::kBestEffortPriority);
2108 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2109 TaskQueue::QueuePriority::kBestEffortPriority);
2110 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2111 TaskQueue::QueuePriority::kBestEffortPriority);
2112
2113 // Main thread scheduler is no longer in loading use case.
2114 main_frame_scheduler->OnFirstMeaningfulPaint();
2115 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kNone);
2116
2117 EXPECT_FALSE(page_scheduler_->IsLoading());
2118
2119 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2120 TaskQueue::QueuePriority::kNormalPriority);
2121 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2122 TaskQueue::QueuePriority::kHighPriority);
2123 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2124 TaskQueue::QueuePriority::kNormalPriority);
2125 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2126 TaskQueue::QueuePriority::kNormalPriority);
2127 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2128 TaskQueue::QueuePriority::kNormalPriority);
2129 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2130 TaskQueue::QueuePriority::kNormalPriority);
2131 }
2132
2133 class ResourceFetchPriorityExperimentTest : public FrameSchedulerImplTest {
2134 public:
ResourceFetchPriorityExperimentTest()2135 ResourceFetchPriorityExperimentTest()
2136 : FrameSchedulerImplTest({kUseResourceFetchPriority}, {}) {
2137 base::FieldTrialParams params{{"HIGHEST", "HIGH"}, {"MEDIUM", "NORMAL"},
2138 {"LOW", "NORMAL"}, {"LOWEST", "LOW"},
2139 {"IDLE", "LOW"}, {"THROTTLED", "LOW"}};
2140
2141 const char kStudyName[] = "ResourceFetchPriorityExperiment";
2142 const char kGroupName[] = "GroupName1";
2143
2144 base::AssociateFieldTrialParams(kStudyName, kGroupName, params);
2145 base::FieldTrialList::CreateFieldTrial(kStudyName, kGroupName);
2146 }
2147 };
2148
TEST_F(ResourceFetchPriorityExperimentTest,DidChangePriority)2149 TEST_F(ResourceFetchPriorityExperimentTest, DidChangePriority) {
2150 std::unique_ptr<ResourceLoadingTaskRunnerHandleImpl> handle =
2151 GetResourceLoadingTaskRunnerHandleImpl();
2152 scoped_refptr<MainThreadTaskQueue> task_queue = handle->task_queue();
2153
2154 TaskQueue::QueuePriority priority =
2155 task_queue->GetTaskQueue()->GetQueuePriority();
2156 EXPECT_EQ(priority, TaskQueue::QueuePriority::kNormalPriority);
2157
2158 DidChangeResourceLoadingPriority(task_queue, net::RequestPriority::LOWEST);
2159 EXPECT_EQ(task_queue->GetTaskQueue()->GetQueuePriority(),
2160 TaskQueue::QueuePriority::kLowPriority);
2161
2162 DidChangeResourceLoadingPriority(task_queue, net::RequestPriority::HIGHEST);
2163 EXPECT_EQ(task_queue->GetTaskQueue()->GetQueuePriority(),
2164 TaskQueue::QueuePriority::kHighPriority);
2165 }
2166
2167 class ResourceFetchPriorityExperimentOnlyWhenLoadingTest
2168 : public FrameSchedulerImplTest {
2169 public:
ResourceFetchPriorityExperimentOnlyWhenLoadingTest()2170 ResourceFetchPriorityExperimentOnlyWhenLoadingTest()
2171 : FrameSchedulerImplTest({kUseResourceFetchPriorityOnlyWhenLoading}, {}) {
2172 base::FieldTrialParams params{{"HIGHEST", "HIGH"}, {"MEDIUM", "NORMAL"},
2173 {"LOW", "NORMAL"}, {"LOWEST", "LOW"},
2174 {"IDLE", "LOW"}, {"THROTTLED", "LOW"}};
2175
2176 const char kStudyName[] = "ResourceFetchPriorityExperiment";
2177 const char kGroupName[] = "GroupName2";
2178
2179 base::AssociateFieldTrialParams(kStudyName, kGroupName, params);
2180 base::FieldTrialList::CreateFieldTrial(kStudyName, kGroupName);
2181 }
2182 };
2183
TEST_F(ResourceFetchPriorityExperimentOnlyWhenLoadingTest,DidChangePriority)2184 TEST_F(ResourceFetchPriorityExperimentOnlyWhenLoadingTest, DidChangePriority) {
2185 std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
2186 CreateFrameScheduler(page_scheduler_.get(),
2187 frame_scheduler_delegate_.get(), nullptr,
2188 FrameScheduler::FrameType::kMainFrame);
2189
2190 std::unique_ptr<ResourceLoadingTaskRunnerHandleImpl> handle =
2191 GetResourceLoadingTaskRunnerHandleImpl();
2192 scoped_refptr<MainThreadTaskQueue> task_queue = handle->task_queue();
2193
2194 EXPECT_EQ(task_queue->GetTaskQueue()->GetQueuePriority(),
2195 TaskQueue::QueuePriority::kNormalPriority);
2196
2197 // Experiment is only enabled during the loading phase.
2198 DidChangeResourceLoadingPriority(task_queue, net::RequestPriority::LOWEST);
2199 EXPECT_EQ(task_queue->GetTaskQueue()->GetQueuePriority(),
2200 TaskQueue::QueuePriority::kNormalPriority);
2201
2202 // Main thread scheduler is in the loading use case.
2203 main_frame_scheduler->OnFirstContentfulPaint();
2204 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
2205
2206 handle = GetResourceLoadingTaskRunnerHandleImpl();
2207 task_queue = handle->task_queue();
2208
2209 DidChangeResourceLoadingPriority(task_queue, net::RequestPriority::LOWEST);
2210 EXPECT_EQ(task_queue->GetTaskQueue()->GetQueuePriority(),
2211 TaskQueue::QueuePriority::kLowPriority);
2212
2213 DidChangeResourceLoadingPriority(task_queue, net::RequestPriority::HIGHEST);
2214 EXPECT_EQ(task_queue->GetTaskQueue()->GetQueuePriority(),
2215 TaskQueue::QueuePriority::kHighPriority);
2216 }
2217
TEST_F(FrameSchedulerImplTest,DidChangeResourceLoadingPriority_ResourceFecthPriorityExperimentDisabled)2218 TEST_F(
2219 FrameSchedulerImplTest,
2220 DidChangeResourceLoadingPriority_ResourceFecthPriorityExperimentDisabled) {
2221 // If the experiment is disabled, we use |loading_task_queue_| for resource
2222 // loading tasks and we don't want the priority of this queue to be affected
2223 // by individual resources.
2224 std::unique_ptr<ResourceLoadingTaskRunnerHandleImpl> handle =
2225 GetResourceLoadingTaskRunnerHandleImpl();
2226 scoped_refptr<MainThreadTaskQueue> task_queue = handle->task_queue();
2227
2228 TaskQueue::QueuePriority priority =
2229 task_queue->GetTaskQueue()->GetQueuePriority();
2230
2231 DidChangeResourceLoadingPriority(task_queue, net::RequestPriority::LOW);
2232 EXPECT_EQ(task_queue->GetTaskQueue()->GetQueuePriority(), priority);
2233
2234 DidChangeResourceLoadingPriority(task_queue, net::RequestPriority::HIGHEST);
2235 EXPECT_EQ(task_queue->GetTaskQueue()->GetQueuePriority(), priority);
2236 }
2237
2238 class LowPriorityCrossOriginTaskExperimentTest : public FrameSchedulerImplTest {
2239 public:
LowPriorityCrossOriginTaskExperimentTest()2240 LowPriorityCrossOriginTaskExperimentTest()
2241 : FrameSchedulerImplTest({kLowPriorityForCrossOrigin}, {}) {}
2242 };
2243
TEST_F(LowPriorityCrossOriginTaskExperimentTest,FrameQueuesPriorities)2244 TEST_F(LowPriorityCrossOriginTaskExperimentTest, FrameQueuesPriorities) {
2245 EXPECT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
2246
2247 // Same Origin Task Queues.
2248 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2249 TaskQueue::QueuePriority::kNormalPriority);
2250 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2251 TaskQueue::QueuePriority::kHighPriority);
2252 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2253 TaskQueue::QueuePriority::kNormalPriority);
2254 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2255 TaskQueue::QueuePriority::kNormalPriority);
2256 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2257 TaskQueue::QueuePriority::kNormalPriority);
2258 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2259 TaskQueue::QueuePriority::kNormalPriority);
2260
2261 frame_scheduler_->SetCrossOriginToMainFrame(true);
2262 EXPECT_TRUE(frame_scheduler_->IsCrossOriginToMainFrame());
2263
2264 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2265 TaskQueue::QueuePriority::kLowPriority);
2266 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2267 TaskQueue::QueuePriority::kLowPriority);
2268 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2269 TaskQueue::QueuePriority::kLowPriority);
2270 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2271 TaskQueue::QueuePriority::kLowPriority);
2272 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2273 TaskQueue::QueuePriority::kLowPriority);
2274 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2275 TaskQueue::QueuePriority::kLowPriority);
2276 }
2277
2278 class LowPriorityCrossOriginTaskDuringLoadingExperimentTest
2279 : public FrameSchedulerImplTest {
2280 public:
LowPriorityCrossOriginTaskDuringLoadingExperimentTest()2281 LowPriorityCrossOriginTaskDuringLoadingExperimentTest()
2282 : FrameSchedulerImplTest({kLowPriorityForCrossOriginOnlyWhenLoading},
2283 {}) {}
2284 };
2285
TEST_F(LowPriorityCrossOriginTaskDuringLoadingExperimentTest,FrameQueuesPriorities)2286 TEST_F(LowPriorityCrossOriginTaskDuringLoadingExperimentTest,
2287 FrameQueuesPriorities) {
2288 // Main thread is in the loading use case.
2289 std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
2290 CreateFrameScheduler(page_scheduler_.get(),
2291 frame_scheduler_delegate_.get(), nullptr,
2292 FrameScheduler::FrameType::kMainFrame);
2293
2294 main_frame_scheduler->OnFirstContentfulPaint();
2295 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
2296
2297 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2298 TaskQueue::QueuePriority::kNormalPriority);
2299 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2300 TaskQueue::QueuePriority::kHighPriority);
2301 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2302 TaskQueue::QueuePriority::kNormalPriority);
2303 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2304 TaskQueue::QueuePriority::kNormalPriority);
2305 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2306 TaskQueue::QueuePriority::kNormalPriority);
2307 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2308 TaskQueue::QueuePriority::kNormalPriority);
2309
2310 frame_scheduler_->SetCrossOriginToMainFrame(true);
2311 EXPECT_TRUE(frame_scheduler_->IsCrossOriginToMainFrame());
2312
2313 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2314 TaskQueue::QueuePriority::kLowPriority);
2315 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2316 TaskQueue::QueuePriority::kLowPriority);
2317 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2318 TaskQueue::QueuePriority::kLowPriority);
2319 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2320 TaskQueue::QueuePriority::kLowPriority);
2321 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2322 TaskQueue::QueuePriority::kLowPriority);
2323 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2324 TaskQueue::QueuePriority::kLowPriority);
2325
2326 // Main thread is no longer in loading use case.
2327 main_frame_scheduler->OnFirstMeaningfulPaint();
2328 ASSERT_EQ(scheduler_->current_use_case(), UseCase::kNone);
2329 EXPECT_FALSE(page_scheduler_->IsLoading());
2330
2331 EXPECT_EQ(LoadingTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2332 TaskQueue::QueuePriority::kNormalPriority);
2333 EXPECT_EQ(LoadingControlTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2334 TaskQueue::QueuePriority::kHighPriority);
2335 EXPECT_EQ(DeferrableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2336 TaskQueue::QueuePriority::kNormalPriority);
2337 EXPECT_EQ(ThrottleableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2338 TaskQueue::QueuePriority::kNormalPriority);
2339 EXPECT_EQ(PausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2340 TaskQueue::QueuePriority::kNormalPriority);
2341 EXPECT_EQ(UnpausableTaskQueue()->GetTaskQueue()->GetQueuePriority(),
2342 TaskQueue::QueuePriority::kNormalPriority);
2343 }
2344
TEST_F(FrameSchedulerImplTest,TaskTypeToTaskQueueMapping)2345 TEST_F(FrameSchedulerImplTest, TaskTypeToTaskQueueMapping) {
2346 // Make sure the queue lookup and task type to queue traits map works as
2347 // expected. This test will fail if these task types are moved to different
2348 // default queues.
2349 EXPECT_EQ(GetTaskQueue(TaskType::kJavascriptTimerDelayedLowNesting),
2350 JavaScriptTimerTaskQueue());
2351 EXPECT_EQ(GetTaskQueue(TaskType::kJavascriptTimerDelayedHighNesting),
2352 JavaScriptTimerTaskQueue());
2353 EXPECT_EQ(GetTaskQueue(TaskType::kJavascriptTimerImmediate),
2354 JavaScriptTimerNonThrottleableTaskQueue());
2355
2356 EXPECT_EQ(GetTaskQueue(TaskType::kWebSocket), DeferrableTaskQueue());
2357 EXPECT_EQ(GetTaskQueue(TaskType::kDatabaseAccess), PausableTaskQueue());
2358 EXPECT_EQ(GetTaskQueue(TaskType::kPostedMessage), PausableTaskQueue());
2359 EXPECT_EQ(GetTaskQueue(TaskType::kWebLocks), UnpausableTaskQueue());
2360 EXPECT_EQ(GetTaskQueue(TaskType::kNetworking), LoadingTaskQueue());
2361 EXPECT_EQ(GetTaskQueue(TaskType::kNetworkingControl),
2362 LoadingControlTaskQueue());
2363 EXPECT_EQ(GetTaskQueue(TaskType::kInternalTranslation),
2364 ForegroundOnlyTaskQueue());
2365 }
2366
2367 // Verify that kJavascriptTimer* are the only non-internal TaskType that can be
2368 // throttled. This ensures that the Javascript timer throttling experiment only
2369 // affects wake ups from Javascript timers https://crbug.com/1075553
TEST_F(FrameSchedulerImplTest,ThrottledTaskTypes)2370 TEST_F(FrameSchedulerImplTest, ThrottledTaskTypes) {
2371 page_scheduler_->SetPageVisible(false);
2372
2373 for (TaskType task_type : kAllFrameTaskTypes) {
2374 SCOPED_TRACE(testing::Message()
2375 << "TaskType is "
2376 << TaskTypeNames::TaskTypeToString(task_type));
2377 switch (task_type) {
2378 case TaskType::kInternalContentCapture:
2379 case TaskType::kJavascriptTimerDelayedLowNesting:
2380 case TaskType::kJavascriptTimerDelayedHighNesting:
2381 case TaskType::kInternalTranslation:
2382 EXPECT_TRUE(IsTaskTypeThrottled(task_type));
2383 break;
2384 default:
2385 EXPECT_FALSE(IsTaskTypeThrottled(task_type));
2386 break;
2387 };
2388 }
2389 }
2390
2391 class FrameSchedulerImplDatabaseAccessWithoutHighPriority
2392 : public FrameSchedulerImplTest {
2393 public:
FrameSchedulerImplDatabaseAccessWithoutHighPriority()2394 FrameSchedulerImplDatabaseAccessWithoutHighPriority()
2395 : FrameSchedulerImplTest({}, {kHighPriorityDatabaseTaskType}) {}
2396 };
2397
TEST_F(FrameSchedulerImplDatabaseAccessWithoutHighPriority,QueueTraits)2398 TEST_F(FrameSchedulerImplDatabaseAccessWithoutHighPriority, QueueTraits) {
2399 auto da_queue = GetTaskQueue(TaskType::kDatabaseAccess);
2400 EXPECT_EQ(da_queue->GetQueueTraits().prioritisation_type,
2401 MainThreadTaskQueue::QueueTraits::PrioritisationType::kRegular);
2402 EXPECT_EQ(da_queue->GetTaskQueue()->GetQueuePriority(),
2403 TaskQueue::QueuePriority::kNormalPriority);
2404 }
2405
2406 class FrameSchedulerImplDatabaseAccessWithHighPriority
2407 : public FrameSchedulerImplTest {
2408 public:
FrameSchedulerImplDatabaseAccessWithHighPriority()2409 FrameSchedulerImplDatabaseAccessWithHighPriority()
2410 : FrameSchedulerImplTest({kHighPriorityDatabaseTaskType}, {}) {}
2411 };
2412
TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority,QueueTraits)2413 TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, QueueTraits) {
2414 auto da_queue = GetTaskQueue(TaskType::kDatabaseAccess);
2415 EXPECT_EQ(da_queue->GetQueueTraits().prioritisation_type,
2416 MainThreadTaskQueue::QueueTraits::PrioritisationType::
2417 kExperimentalDatabase);
2418 EXPECT_EQ(da_queue->GetTaskQueue()->GetQueuePriority(),
2419 TaskQueue::QueuePriority::kHighPriority);
2420 }
2421
TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority,RunOrder)2422 TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, RunOrder) {
2423 Vector<String> run_order;
2424 PostTestTasksForPrioritisationType(&run_order, "D1 R1 D2 V1 B1");
2425
2426 base::RunLoop().RunUntilIdle();
2427 EXPECT_THAT(run_order, testing::ElementsAre("V1", "D1", "D2", "R1", "B1"));
2428 }
2429
TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority,NormalPriorityInBackground)2430 TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority,
2431 NormalPriorityInBackground) {
2432 page_scheduler_->SetPageVisible(false);
2433
2434 Vector<String> run_order;
2435 PostTestTasksForPrioritisationType(&run_order, "D1 R1 D2 V1 B1");
2436
2437 base::RunLoop().RunUntilIdle();
2438 EXPECT_THAT(run_order, testing::ElementsAre("V1", "D1", "R1", "D2", "B1"));
2439 }
2440
TEST_F(FrameSchedulerImplTest,ContentCaptureHasIdleTaskQueue)2441 TEST_F(FrameSchedulerImplTest, ContentCaptureHasIdleTaskQueue) {
2442 auto task_queue = GetTaskQueue(TaskType::kInternalContentCapture);
2443
2444 EXPECT_EQ(TaskQueue::QueuePriority::kBestEffortPriority,
2445 task_queue->GetTaskQueue()->GetQueuePriority());
2446 }
2447
TEST_F(FrameSchedulerImplTest,ComputePriorityForDetachedFrame)2448 TEST_F(FrameSchedulerImplTest, ComputePriorityForDetachedFrame) {
2449 auto task_queue = GetTaskQueue(TaskType::kJavascriptTimerDelayedLowNesting);
2450 // Just check that it does not crash.
2451 page_scheduler_.reset();
2452 frame_scheduler_->ComputePriority(task_queue.get());
2453 }
2454
2455 namespace {
2456
2457 // Mask is a preferred way of plumbing the list of features, but a list
2458 // is more convenient to read in the tests.
2459 // Here we ensure that these two methods are equivalent.
ComputeMaskFromFeatures(FrameSchedulerImpl * frame_scheduler)2460 uint64_t ComputeMaskFromFeatures(FrameSchedulerImpl* frame_scheduler) {
2461 uint64_t result = 0;
2462 for (SchedulingPolicy::Feature feature :
2463 frame_scheduler->GetActiveFeaturesTrackedForBackForwardCacheMetrics()) {
2464 result |= (1 << static_cast<size_t>(feature));
2465 }
2466 return result;
2467 }
2468
2469 } // namespace
2470
TEST_F(FrameSchedulerImplTest,BackForwardCacheOptOut)2471 TEST_F(FrameSchedulerImplTest, BackForwardCacheOptOut) {
2472 EXPECT_THAT(
2473 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2474 testing::UnorderedElementsAre());
2475 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2476 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2477 frame_scheduler_.get()));
2478
2479 auto feature_handle1 = frame_scheduler_->RegisterFeature(
2480 SchedulingPolicy::Feature::kWebSocket,
2481 {SchedulingPolicy::RecordMetricsForBackForwardCache()});
2482
2483 EXPECT_THAT(
2484 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2485 testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket));
2486 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2487 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2488 frame_scheduler_.get()));
2489
2490 auto feature_handle2 = frame_scheduler_->RegisterFeature(
2491 SchedulingPolicy::Feature::kWebRTC,
2492 {SchedulingPolicy::RecordMetricsForBackForwardCache()});
2493
2494 EXPECT_THAT(
2495 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2496 testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket,
2497 SchedulingPolicy::Feature::kWebRTC));
2498 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2499 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2500 frame_scheduler_.get()));
2501
2502 feature_handle1.reset();
2503
2504 EXPECT_THAT(
2505 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2506 testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebRTC));
2507 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2508 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2509 frame_scheduler_.get()));
2510
2511 feature_handle2.reset();
2512
2513 EXPECT_THAT(
2514 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2515 testing::UnorderedElementsAre());
2516 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2517 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2518 frame_scheduler_.get()));
2519 }
2520
TEST_F(FrameSchedulerImplTest,BackForwardCacheOptOut_FrameNavigated)2521 TEST_F(FrameSchedulerImplTest, BackForwardCacheOptOut_FrameNavigated) {
2522 EXPECT_THAT(
2523 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2524 testing::UnorderedElementsAre());
2525 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2526 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2527 frame_scheduler_.get()));
2528
2529 auto feature_handle = frame_scheduler_->RegisterFeature(
2530 SchedulingPolicy::Feature::kWebSocket,
2531 {SchedulingPolicy::RecordMetricsForBackForwardCache()});
2532
2533 EXPECT_THAT(
2534 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2535 testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket));
2536 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2537 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2538 frame_scheduler_.get()));
2539
2540 frame_scheduler_->RegisterStickyFeature(
2541 SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore,
2542 {SchedulingPolicy::RecordMetricsForBackForwardCache()});
2543
2544 EXPECT_THAT(
2545 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2546 testing::UnorderedElementsAre(
2547 SchedulingPolicy::Feature::kWebSocket,
2548 SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore));
2549 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2550 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2551 frame_scheduler_.get()));
2552
2553 // Same document navigations don't affect anything.
2554 frame_scheduler_->DidCommitProvisionalLoad(
2555 false, FrameScheduler::NavigationType::kSameDocument);
2556 EXPECT_THAT(
2557 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2558 testing::UnorderedElementsAre(
2559 SchedulingPolicy::Feature::kWebSocket,
2560 SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore));
2561 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2562 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2563 frame_scheduler_.get()));
2564
2565 // Regular navigations reset all features.
2566 frame_scheduler_->DidCommitProvisionalLoad(
2567 false, FrameScheduler::NavigationType::kOther);
2568 EXPECT_THAT(
2569 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2570 testing::UnorderedElementsAre());
2571 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2572 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2573 frame_scheduler_.get()));
2574
2575 // Resetting a feature handle after navigation shouldn't do anything.
2576 feature_handle.reset();
2577
2578 EXPECT_THAT(
2579 frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(),
2580 testing::UnorderedElementsAre());
2581 EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()),
2582 GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
2583 frame_scheduler_.get()));
2584 }
2585
TEST_F(FrameSchedulerImplTest,FeatureUpload)2586 TEST_F(FrameSchedulerImplTest, FeatureUpload) {
2587 ResetFrameScheduler(FrameScheduler::FrameType::kMainFrame);
2588
2589 frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerImmediate)
2590 ->PostTask(
2591 FROM_HERE,
2592 base::BindOnce(
2593 [](FrameSchedulerImpl* frame_scheduler,
2594 testing::StrictMock<FrameSchedulerDelegateForTesting>*
2595 delegate) {
2596 frame_scheduler->RegisterStickyFeature(
2597 SchedulingPolicy::Feature::
2598 kMainResourceHasCacheControlNoStore,
2599 {SchedulingPolicy::RecordMetricsForBackForwardCache()});
2600 frame_scheduler->RegisterStickyFeature(
2601 SchedulingPolicy::Feature::
2602 kMainResourceHasCacheControlNoCache,
2603 {SchedulingPolicy::RecordMetricsForBackForwardCache()});
2604 // Ensure that the feature upload is delayed.
2605 testing::Mock::VerifyAndClearExpectations(delegate);
2606 EXPECT_CALL(
2607 *delegate,
2608 UpdateActiveSchedulerTrackedFeatures(
2609 (1 << static_cast<size_t>(
2610 SchedulingPolicy::Feature::
2611 kMainResourceHasCacheControlNoStore)) |
2612 (1 << static_cast<size_t>(
2613 SchedulingPolicy::Feature::
2614 kMainResourceHasCacheControlNoCache))));
2615 },
2616 frame_scheduler_.get(), frame_scheduler_delegate_.get()));
2617
2618 base::RunLoop().RunUntilIdle();
2619
2620 testing::Mock::VerifyAndClearExpectations(frame_scheduler_delegate_.get());
2621 }
2622
TEST_F(FrameSchedulerImplTest,FeatureUpload_FrameDestruction)2623 TEST_F(FrameSchedulerImplTest, FeatureUpload_FrameDestruction) {
2624 ResetFrameScheduler(FrameScheduler::FrameType::kMainFrame);
2625
2626 FeatureHandle feature_handle;
2627
2628 frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerImmediate)
2629 ->PostTask(
2630 FROM_HERE,
2631 base::BindOnce(
2632 [](FrameSchedulerImpl* frame_scheduler,
2633 testing::StrictMock<FrameSchedulerDelegateForTesting>*
2634 delegate,
2635 FeatureHandle* feature_handle) {
2636 *feature_handle = frame_scheduler->RegisterFeature(
2637 SchedulingPolicy::Feature::kWebSocket,
2638 {SchedulingPolicy::RecordMetricsForBackForwardCache()});
2639 // Ensure that the feature upload is delayed.
2640 testing::Mock::VerifyAndClearExpectations(delegate);
2641 EXPECT_CALL(*delegate,
2642 UpdateActiveSchedulerTrackedFeatures(
2643 (1 << static_cast<size_t>(
2644 SchedulingPolicy::Feature::kWebSocket))));
2645 },
2646 frame_scheduler_.get(), frame_scheduler_delegate_.get(),
2647 &feature_handle));
2648 frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimerImmediate)
2649 ->PostTask(FROM_HERE,
2650 base::BindOnce(
2651 [](FrameSchedulerImpl* frame_scheduler,
2652 testing::StrictMock<FrameSchedulerDelegateForTesting>*
2653 delegate,
2654 FeatureHandle* feature_handle) {
2655 feature_handle->reset();
2656 ResetForNavigation(frame_scheduler);
2657 // Ensure that we don't upload the features for frame
2658 // destruction.
2659 testing::Mock::VerifyAndClearExpectations(delegate);
2660 EXPECT_CALL(
2661 *delegate,
2662 UpdateActiveSchedulerTrackedFeatures(testing::_))
2663 .Times(0);
2664 },
2665 frame_scheduler_.get(), frame_scheduler_delegate_.get(),
2666 &feature_handle));
2667
2668 base::RunLoop().RunUntilIdle();
2669
2670 testing::Mock::VerifyAndClearExpectations(frame_scheduler_delegate_.get());
2671 }
2672
2673 class WebSchedulingTaskQueueTest : public FrameSchedulerImplTest {
2674 public:
SetUp()2675 void SetUp() override {
2676 FrameSchedulerImplTest::SetUp();
2677
2678 for (int i = 0; i <= static_cast<int>(WebSchedulingPriority::kLastPriority);
2679 i++) {
2680 WebSchedulingPriority priority = static_cast<WebSchedulingPriority>(i);
2681 // We only need the TaskRunner, so it's ok that the WebSchedulingTaskQueue
2682 // gets destroyed right away.
2683 std::unique_ptr<WebSchedulingTaskQueue> task_queue =
2684 frame_scheduler_->CreateWebSchedulingTaskQueue(priority);
2685 web_scheduling_task_runners_.push_back(task_queue->GetTaskRunner());
2686 task_queues_.push_back(std::move(task_queue));
2687 }
2688 }
2689
TearDown()2690 void TearDown() override {
2691 FrameSchedulerImplTest::TearDown();
2692
2693 web_scheduling_task_runners_.clear();
2694 }
2695
2696 protected:
2697 // Helper for posting tasks to a WebSchedulingTaskQueue. |task_descriptor| is
2698 // a string with space delimited task identifiers. The first letter of each
2699 // task identifier specifies the task queue priority:
2700 // - 'U': UserBlocking
2701 // - 'V': UserVisible
2702 // - 'B': Background
PostWebSchedulingTestTasks(Vector<String> * run_order,const String & task_descriptor)2703 void PostWebSchedulingTestTasks(Vector<String>* run_order,
2704 const String& task_descriptor) {
2705 std::istringstream stream(task_descriptor.Utf8());
2706 while (!stream.eof()) {
2707 std::string task;
2708 stream >> task;
2709 WebSchedulingPriority priority;
2710 switch (task[0]) {
2711 case 'U':
2712 priority = WebSchedulingPriority::kUserBlockingPriority;
2713 break;
2714 case 'V':
2715 priority = WebSchedulingPriority::kUserVisiblePriority;
2716 break;
2717 case 'B':
2718 priority = WebSchedulingPriority::kBackgroundPriority;
2719 break;
2720 default:
2721 EXPECT_FALSE(true);
2722 return;
2723 }
2724 web_scheduling_task_runners_[static_cast<int>(priority)]->PostTask(
2725 FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order,
2726 String::FromUTF8(task)));
2727 }
2728 }
2729
2730 Vector<scoped_refptr<base::SingleThreadTaskRunner>>
2731 web_scheduling_task_runners_;
2732
2733 Vector<std::unique_ptr<WebSchedulingTaskQueue>> task_queues_;
2734 };
2735
TEST_F(WebSchedulingTaskQueueTest,TasksRunInPriorityOrder)2736 TEST_F(WebSchedulingTaskQueueTest, TasksRunInPriorityOrder) {
2737 Vector<String> run_order;
2738
2739 PostWebSchedulingTestTasks(&run_order, "B1 B2 V1 V2 U1 U2");
2740
2741 base::RunLoop().RunUntilIdle();
2742 EXPECT_THAT(run_order,
2743 testing::ElementsAre("U1", "U2", "V1", "V2", "B1", "B2"));
2744 }
2745
TEST_F(WebSchedulingTaskQueueTest,DynamicTaskPriorityOrder)2746 TEST_F(WebSchedulingTaskQueueTest, DynamicTaskPriorityOrder) {
2747 Vector<String> run_order;
2748
2749 PostWebSchedulingTestTasks(&run_order, "B1 B2 V1 V2 U1 U2");
2750 task_queues_[static_cast<int>(WebSchedulingPriority::kUserBlockingPriority)]
2751 ->SetPriority(WebSchedulingPriority::kBackgroundPriority);
2752
2753 base::RunLoop().RunUntilIdle();
2754 EXPECT_THAT(run_order,
2755 testing::ElementsAre("V1", "V2", "B1", "B2", "U1", "U2"));
2756 }
2757
2758 // Verify that tasks posted with TaskType::kJavascriptTimerDelayed* run at the
2759 // expected time when throttled.
TEST_F(FrameSchedulerImplTest,ThrottledJSTimerTasksRunTime)2760 TEST_F(FrameSchedulerImplTest, ThrottledJSTimerTasksRunTime) {
2761 constexpr TaskType kJavaScriptTimerTaskTypes[] = {
2762 TaskType::kJavascriptTimerDelayedLowNesting,
2763 TaskType::kJavascriptTimerDelayedHighNesting};
2764
2765 // Snap the time to a multiple of 1 second. Otherwise, the exact run time
2766 // of throttled tasks after hiding the page will vary.
2767 FastForwardToAlignedTime(base::TimeDelta::FromSeconds(1));
2768 const base::TimeTicks start = base::TimeTicks::Now();
2769
2770 // Hide the page to start throttling JS Timers.
2771 page_scheduler_->SetPageVisible(false);
2772
2773 std::map<TaskType, std::vector<base::TimeTicks>> run_times;
2774
2775 // Post tasks with each Javascript Timer Task Type.
2776 for (TaskType task_type : kJavaScriptTimerTaskTypes) {
2777 const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
2778 frame_scheduler_->GetTaskRunner(task_type);
2779
2780 // Note: Taking the address of an element in |run_times| is safe because
2781 // inserting elements in a map does not invalidate references.
2782
2783 task_runner->PostTask(
2784 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]));
2785 task_runner->PostDelayedTask(
2786 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]),
2787 base::TimeDelta::FromMilliseconds(1000));
2788 task_runner->PostDelayedTask(
2789 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]),
2790 base::TimeDelta::FromMilliseconds(1002));
2791 task_runner->PostDelayedTask(
2792 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]),
2793 base::TimeDelta::FromMilliseconds(1004));
2794 task_runner->PostDelayedTask(
2795 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]),
2796 base::TimeDelta::FromMilliseconds(2500));
2797 task_runner->PostDelayedTask(
2798 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times[task_type]),
2799 base::TimeDelta::FromMilliseconds(6000));
2800 }
2801
2802 // Make posted tasks run.
2803 task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
2804
2805 // The effective delay of a throttled task is >= the requested delay, and is
2806 // within [N * 1000, N * 1000 + 3] ms, where N is an integer. This is because
2807 // the wake up rate is 1 per second, and the duration of each wake up is 3 ms.
2808 for (TaskType task_type : kJavaScriptTimerTaskTypes) {
2809 EXPECT_THAT(
2810 run_times[task_type],
2811 testing::ElementsAre(start + base::TimeDelta::FromMilliseconds(0),
2812 start + base::TimeDelta::FromMilliseconds(1000),
2813 start + base::TimeDelta::FromMilliseconds(1002),
2814 start + base::TimeDelta::FromMilliseconds(2000),
2815 start + base::TimeDelta::FromMilliseconds(3000),
2816 start + base::TimeDelta::FromMilliseconds(6000)));
2817 }
2818 }
2819
2820 namespace {
2821 class MockMainThreadScheduler : public MainThreadSchedulerImpl {
2822 public:
MockMainThreadScheduler(base::test::TaskEnvironment & task_environment)2823 explicit MockMainThreadScheduler(
2824 base::test::TaskEnvironment& task_environment)
2825 : MainThreadSchedulerImpl(
2826 base::sequence_manager::SequenceManagerForTest::Create(
2827 nullptr,
2828 task_environment.GetMainThreadTaskRunner(),
2829 task_environment.GetMockTickClock()),
2830 base::nullopt) {}
2831
2832 MOCK_METHOD(void, OnMainFramePaint, ());
2833 };
2834 } // namespace
2835
TEST_F(FrameSchedulerImplTest,ReportFMPAndFCPForMainFrames)2836 TEST_F(FrameSchedulerImplTest, ReportFMPAndFCPForMainFrames) {
2837 MockMainThreadScheduler mock_main_thread_scheduler{task_environment_};
2838 std::unique_ptr<WebAgentGroupScheduler> agent_group_scheduler =
2839 mock_main_thread_scheduler.CreateAgentGroupScheduler();
2840 std::unique_ptr<PageSchedulerImpl> page_scheduler = CreatePageScheduler(
2841 nullptr, &mock_main_thread_scheduler, *agent_group_scheduler);
2842
2843 std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
2844 CreateFrameScheduler(page_scheduler.get(), nullptr, nullptr,
2845 FrameScheduler::FrameType::kMainFrame);
2846
2847 EXPECT_CALL(mock_main_thread_scheduler, OnMainFramePaint).Times(2);
2848
2849 main_frame_scheduler->OnFirstMeaningfulPaint();
2850 main_frame_scheduler->OnFirstContentfulPaint();
2851
2852 main_frame_scheduler = nullptr;
2853 page_scheduler = nullptr;
2854 agent_group_scheduler = nullptr;
2855 mock_main_thread_scheduler.Shutdown();
2856 }
2857
TEST_F(FrameSchedulerImplTest,DontReportFMPAndFCPForSubframes)2858 TEST_F(FrameSchedulerImplTest, DontReportFMPAndFCPForSubframes) {
2859 MockMainThreadScheduler mock_main_thread_scheduler{task_environment_};
2860 std::unique_ptr<WebAgentGroupScheduler> agent_group_scheduler =
2861 mock_main_thread_scheduler.CreateAgentGroupScheduler();
2862 std::unique_ptr<PageSchedulerImpl> page_scheduler = CreatePageScheduler(
2863 nullptr, &mock_main_thread_scheduler, *agent_group_scheduler);
2864
2865 std::unique_ptr<FrameSchedulerImpl> subframe_scheduler =
2866 CreateFrameScheduler(page_scheduler.get(), nullptr, nullptr,
2867 FrameScheduler::FrameType::kSubframe);
2868
2869 EXPECT_CALL(mock_main_thread_scheduler, OnMainFramePaint).Times(0);
2870
2871 subframe_scheduler->OnFirstMeaningfulPaint();
2872 subframe_scheduler->OnFirstContentfulPaint();
2873
2874 subframe_scheduler = nullptr;
2875 page_scheduler = nullptr;
2876 agent_group_scheduler = nullptr;
2877 mock_main_thread_scheduler.Shutdown();
2878 }
2879
2880 // Verify that tasks run at the expected time in frame that is same-origin with
2881 // the main frame with intensive wake up throttling.
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,TaskExecutionSameOriginFrame)2882 TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
2883 TaskExecutionSameOriginFrame) {
2884 ASSERT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
2885
2886 // Throttled TaskRunner to which tasks are posted in this test.
2887 const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
2888 frame_scheduler_->GetTaskRunner(GetTaskType());
2889
2890 // Snap the time to a multiple of
2891 // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which
2892 // tasks can run after throttling is enabled will vary.
2893 FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
2894 const base::TimeTicks test_start = base::TimeTicks::Now();
2895
2896 // Hide the page. This starts the delay to throttle background wake ups.
2897 EXPECT_TRUE(page_scheduler_->IsPageVisible());
2898 page_scheduler_->SetPageVisible(false);
2899
2900 // Initially, wake ups are not intensively throttled.
2901 {
2902 const base::TimeTicks scope_start = base::TimeTicks::Now();
2903 EXPECT_EQ(scope_start, test_start);
2904 std::vector<base::TimeTicks> run_times;
2905
2906 for (int i = 0; i < kNumTasks; ++i) {
2907 task_runner->PostDelayedTask(
2908 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
2909 kShortDelay + i * kDefaultThrottledWakeUpInterval);
2910 }
2911
2912 task_environment_.FastForwardBy(kGracePeriod);
2913 EXPECT_THAT(run_times, testing::ElementsAre(
2914 scope_start + base::TimeDelta::FromSeconds(1),
2915 scope_start + base::TimeDelta::FromSeconds(2),
2916 scope_start + base::TimeDelta::FromSeconds(3),
2917 scope_start + base::TimeDelta::FromSeconds(4),
2918 scope_start + base::TimeDelta::FromSeconds(5)));
2919 }
2920
2921 // After the grace period:
2922
2923 // Test that wake ups are 1-second aligned if there is no recent wake up.
2924 {
2925 const base::TimeTicks scope_start = base::TimeTicks::Now();
2926 EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(5));
2927 std::vector<base::TimeTicks> run_times;
2928
2929 task_runner->PostDelayedTask(FROM_HERE,
2930 base::BindOnce(&RecordRunTime, &run_times),
2931 kDefaultThrottledWakeUpInterval);
2932
2933 task_environment_.FastForwardBy(kDefaultThrottledWakeUpInterval);
2934 EXPECT_THAT(run_times, testing::ElementsAre(
2935 scope_start + base::TimeDelta::FromSeconds(1)));
2936 }
2937
2938 // Test that if there is a recent wake up:
2939 // TaskType can be intensively throttled: Wake ups are 1-minute aligned
2940 // Otherwise: Wake ups are 1-second aligned
2941 {
2942 const base::TimeTicks scope_start = base::TimeTicks::Now();
2943 EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(5) +
2944 base::TimeDelta::FromSeconds(1));
2945 std::vector<base::TimeTicks> run_times;
2946
2947 for (int i = 0; i < kNumTasks; ++i) {
2948 task_runner->PostDelayedTask(
2949 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
2950 kShortDelay + i * kDefaultThrottledWakeUpInterval);
2951 }
2952
2953 FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
2954
2955 if (IsIntensiveThrottlingExpected()) {
2956 const base::TimeTicks aligned_time =
2957 scope_start + base::TimeDelta::FromSeconds(59);
2958 EXPECT_THAT(run_times,
2959 testing::ElementsAre(aligned_time, aligned_time, aligned_time,
2960 aligned_time, aligned_time));
2961 } else {
2962 EXPECT_THAT(
2963 run_times,
2964 testing::ElementsAre(scope_start + base::TimeDelta::FromSeconds(1),
2965 scope_start + base::TimeDelta::FromSeconds(2),
2966 scope_start + base::TimeDelta::FromSeconds(3),
2967 scope_start + base::TimeDelta::FromSeconds(4),
2968 scope_start + base::TimeDelta::FromSeconds(5)));
2969 }
2970 }
2971
2972 // Post an extra task with a short delay. The wake up should be 1-minute
2973 // aligned if the TaskType supports intensive throttling, or 1-second aligned
2974 // otherwise.
2975 {
2976 const base::TimeTicks scope_start = base::TimeTicks::Now();
2977 EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(6));
2978 std::vector<base::TimeTicks> run_times;
2979
2980 task_runner->PostDelayedTask(FROM_HERE,
2981 base::BindOnce(&RecordRunTime, &run_times),
2982 kDefaultThrottledWakeUpInterval);
2983
2984 task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps);
2985
2986 EXPECT_THAT(run_times, testing::ElementsAre(scope_start +
2987 GetExpectedWakeUpInterval()));
2988 }
2989
2990 // Post an extra task with a delay longer than the intensive throttling wake
2991 // up interval. The wake up should be 1-second aligned, even if the TaskType
2992 // supports intensive throttling, because there was no wake up in the last
2993 // minute.
2994 {
2995 const base::TimeTicks scope_start = base::TimeTicks::Now();
2996 EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(7));
2997 std::vector<base::TimeTicks> run_times;
2998
2999 const base::TimeDelta kLongDelay =
3000 kIntensiveThrottlingDurationBetweenWakeUps * 5 +
3001 kDefaultThrottledWakeUpInterval;
3002 task_runner->PostDelayedTask(
3003 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times), kLongDelay);
3004
3005 task_environment_.FastForwardBy(kLongDelay);
3006 EXPECT_THAT(run_times, testing::ElementsAre(scope_start + kLongDelay));
3007 }
3008
3009 // Post tasks with short delays after the page communicated with the user in
3010 // background. Tasks should be 1-second aligned for 3 seconds. After that, if
3011 // the TaskType supports intensive throttling, wake ups should be 1-minute
3012 // aligned.
3013 {
3014 const base::TimeTicks scope_start = base::TimeTicks::Now();
3015 EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(12) +
3016 kDefaultThrottledWakeUpInterval);
3017 std::vector<base::TimeTicks> run_times;
3018
3019 page_scheduler_->OnTitleOrFaviconUpdated();
3020 task_runner->PostDelayedTask(
3021 FROM_HERE, base::BindLambdaForTesting([&]() {
3022 RecordRunTime(&run_times);
3023 for (int i = 0; i < kNumTasks; ++i) {
3024 task_runner->PostDelayedTask(
3025 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
3026 kDefaultThrottledWakeUpInterval * (i + 1));
3027 }
3028 page_scheduler_->OnTitleOrFaviconUpdated();
3029 }),
3030 kDefaultThrottledWakeUpInterval);
3031
3032 task_environment_.FastForwardUntilNoTasksRemain();
3033
3034 if (IsIntensiveThrottlingExpected()) {
3035 EXPECT_THAT(run_times, testing::ElementsAre(
3036 scope_start + base::TimeDelta::FromSeconds(1),
3037 scope_start + base::TimeDelta::FromSeconds(2),
3038 scope_start + base::TimeDelta::FromSeconds(3),
3039 scope_start - kDefaultThrottledWakeUpInterval +
3040 base::TimeDelta::FromMinutes(1),
3041 scope_start - kDefaultThrottledWakeUpInterval +
3042 base::TimeDelta::FromMinutes(1),
3043 scope_start - kDefaultThrottledWakeUpInterval +
3044 base::TimeDelta::FromMinutes(1)));
3045 } else {
3046 EXPECT_THAT(
3047 run_times,
3048 testing::ElementsAre(scope_start + base::TimeDelta::FromSeconds(1),
3049 scope_start + base::TimeDelta::FromSeconds(2),
3050 scope_start + base::TimeDelta::FromSeconds(3),
3051 scope_start + base::TimeDelta::FromSeconds(4),
3052 scope_start + base::TimeDelta::FromSeconds(5),
3053 scope_start + base::TimeDelta::FromSeconds(6)));
3054 }
3055 }
3056 }
3057
3058 // Verify that tasks run at the expected time in a frame that is cross-origin
3059 // with the main frame with intensive wake up throttling.
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,TaskExecutionCrossOriginFrame)3060 TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
3061 TaskExecutionCrossOriginFrame) {
3062 frame_scheduler_->SetCrossOriginToMainFrame(true);
3063
3064 // Throttled TaskRunner to which tasks are posted in this test.
3065 const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
3066 frame_scheduler_->GetTaskRunner(GetTaskType());
3067
3068 // Snap the time to a multiple of
3069 // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which
3070 // tasks can run after throttling is enabled will vary.
3071 FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
3072 const base::TimeTicks test_start = base::TimeTicks::Now();
3073
3074 // Hide the page. This starts the delay to throttle background wake ups.
3075 EXPECT_TRUE(page_scheduler_->IsPageVisible());
3076 page_scheduler_->SetPageVisible(false);
3077
3078 // Initially, wake ups are not intensively throttled.
3079 {
3080 const base::TimeTicks scope_start = base::TimeTicks::Now();
3081 EXPECT_EQ(scope_start, test_start);
3082 std::vector<base::TimeTicks> run_times;
3083
3084 for (int i = 0; i < kNumTasks; ++i) {
3085 task_runner->PostDelayedTask(
3086 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
3087 kShortDelay + i * kDefaultThrottledWakeUpInterval);
3088 }
3089
3090 task_environment_.FastForwardBy(kGracePeriod);
3091 EXPECT_THAT(run_times, testing::ElementsAre(
3092 scope_start + base::TimeDelta::FromSeconds(1),
3093 scope_start + base::TimeDelta::FromSeconds(2),
3094 scope_start + base::TimeDelta::FromSeconds(3),
3095 scope_start + base::TimeDelta::FromSeconds(4),
3096 scope_start + base::TimeDelta::FromSeconds(5)));
3097 }
3098
3099 // After the grace period:
3100
3101 // Test posting a task when there is no recent wake up. The wake up should be
3102 // 1-minute aligned if the TaskType supports intensive throttling (in a main
3103 // frame, it would have been 1-second aligned since there was no wake up in
3104 // the last minute). Otherwise, it should be 1-second aligned.
3105 {
3106 const base::TimeTicks scope_start = base::TimeTicks::Now();
3107 EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(5));
3108 std::vector<base::TimeTicks> run_times;
3109
3110 task_runner->PostDelayedTask(FROM_HERE,
3111 base::BindOnce(&RecordRunTime, &run_times),
3112 kDefaultThrottledWakeUpInterval);
3113
3114 task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps);
3115 EXPECT_THAT(run_times, testing::ElementsAre(scope_start +
3116 GetExpectedWakeUpInterval()));
3117 }
3118
3119 // Test posting many tasks with short delays. Wake ups should be 1-minute
3120 // aligned if the TaskType supports intensive throttling, or 1-second aligned
3121 // otherwise.
3122 {
3123 const base::TimeTicks scope_start = base::TimeTicks::Now();
3124 EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(6));
3125 std::vector<base::TimeTicks> run_times;
3126
3127 for (int i = 0; i < kNumTasks; ++i) {
3128 task_runner->PostDelayedTask(
3129 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
3130 kShortDelay + i * kDefaultThrottledWakeUpInterval);
3131 }
3132
3133 task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps);
3134
3135 if (IsIntensiveThrottlingExpected()) {
3136 const base::TimeTicks aligned_time =
3137 scope_start + kIntensiveThrottlingDurationBetweenWakeUps;
3138 EXPECT_THAT(run_times,
3139 testing::ElementsAre(aligned_time, aligned_time, aligned_time,
3140 aligned_time, aligned_time));
3141 } else {
3142 EXPECT_THAT(
3143 run_times,
3144 testing::ElementsAre(scope_start + base::TimeDelta::FromSeconds(1),
3145 scope_start + base::TimeDelta::FromSeconds(2),
3146 scope_start + base::TimeDelta::FromSeconds(3),
3147 scope_start + base::TimeDelta::FromSeconds(4),
3148 scope_start + base::TimeDelta::FromSeconds(5)));
3149 }
3150 }
3151
3152 // Post an extra task with a short delay. Wake ups should be 1-minute aligned
3153 // if the TaskType supports intensive throttling, or 1-second aligned
3154 // otherwise.
3155 {
3156 const base::TimeTicks scope_start = base::TimeTicks::Now();
3157 EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(7));
3158 std::vector<base::TimeTicks> run_times;
3159
3160 task_runner->PostDelayedTask(FROM_HERE,
3161 base::BindOnce(&RecordRunTime, &run_times),
3162 kDefaultThrottledWakeUpInterval);
3163
3164 task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps);
3165 EXPECT_THAT(run_times, testing::ElementsAre(scope_start +
3166 GetExpectedWakeUpInterval()));
3167 }
3168
3169 // Post an extra task with a delay longer than the intensive throttling wake
3170 // up interval. The wake up should be 1-minute aligned if the TaskType
3171 // supports intensive throttling (in a main frame, it would have been 1-second
3172 // aligned because there was no wake up in the last minute). Otherwise, it
3173 // should be 1-second aligned.
3174 {
3175 const base::TimeTicks scope_start = base::TimeTicks::Now();
3176 EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(8));
3177 std::vector<base::TimeTicks> run_times;
3178
3179 const base::TimeDelta kLongDelay =
3180 kIntensiveThrottlingDurationBetweenWakeUps * 6;
3181 task_runner->PostDelayedTask(FROM_HERE,
3182 base::BindOnce(&RecordRunTime, &run_times),
3183 kLongDelay - kShortDelay);
3184
3185 task_environment_.FastForwardBy(kLongDelay);
3186 EXPECT_THAT(run_times, testing::ElementsAre(scope_start + kLongDelay));
3187 }
3188
3189 // Post tasks with short delays after the page communicated with the user in
3190 // background. Wake ups should be 1-minute aligned if the TaskType supports
3191 // intensive throttling, since cross-origin frames are not affected by title
3192 // or favicon update. Otherwise, they should be 1-second aligned.
3193 {
3194 const base::TimeTicks scope_start = base::TimeTicks::Now();
3195 EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(14));
3196 std::vector<base::TimeTicks> run_times;
3197
3198 page_scheduler_->OnTitleOrFaviconUpdated();
3199 task_runner->PostDelayedTask(
3200 FROM_HERE, base::BindLambdaForTesting([&]() {
3201 RecordRunTime(&run_times);
3202 for (int i = 0; i < kNumTasks; ++i) {
3203 task_runner->PostDelayedTask(
3204 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
3205 kDefaultThrottledWakeUpInterval * (i + 1));
3206 }
3207 page_scheduler_->OnTitleOrFaviconUpdated();
3208 }),
3209 kDefaultThrottledWakeUpInterval);
3210
3211 task_environment_.FastForwardUntilNoTasksRemain();
3212
3213 if (IsIntensiveThrottlingExpected()) {
3214 EXPECT_THAT(
3215 run_times,
3216 testing::ElementsAre(scope_start + base::TimeDelta::FromMinutes(1),
3217 scope_start + base::TimeDelta::FromMinutes(2),
3218 scope_start + base::TimeDelta::FromMinutes(2),
3219 scope_start + base::TimeDelta::FromMinutes(2),
3220 scope_start + base::TimeDelta::FromMinutes(2),
3221 scope_start + base::TimeDelta::FromMinutes(2)));
3222 } else {
3223 EXPECT_THAT(
3224 run_times,
3225 testing::ElementsAre(scope_start + base::TimeDelta::FromSeconds(1),
3226 scope_start + base::TimeDelta::FromSeconds(2),
3227 scope_start + base::TimeDelta::FromSeconds(3),
3228 scope_start + base::TimeDelta::FromSeconds(4),
3229 scope_start + base::TimeDelta::FromSeconds(5),
3230 scope_start + base::TimeDelta::FromSeconds(6)));
3231 }
3232 }
3233 }
3234
3235 // Verify that tasks from different frames that are same-origin with the main
3236 // frame run at the expected time.
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,ManySameOriginFrames)3237 TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
3238 ManySameOriginFrames) {
3239 ASSERT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
3240 const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
3241 frame_scheduler_->GetTaskRunner(GetTaskType());
3242
3243 // Create a FrameScheduler that is same-origin with the main frame, and an
3244 // associated throttled TaskRunner.
3245 std::unique_ptr<FrameSchedulerImpl> other_frame_scheduler =
3246 CreateFrameScheduler(page_scheduler_.get(),
3247 frame_scheduler_delegate_.get(), nullptr,
3248 FrameScheduler::FrameType::kSubframe);
3249 ASSERT_FALSE(other_frame_scheduler->IsCrossOriginToMainFrame());
3250 const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner =
3251 other_frame_scheduler->GetTaskRunner(GetTaskType());
3252
3253 // Snap the time to a multiple of
3254 // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which
3255 // tasks can run after throttling is enabled will vary.
3256 FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
3257
3258 // Hide the page and wait until the intensive throttling grace period has
3259 // elapsed.
3260 EXPECT_TRUE(page_scheduler_->IsPageVisible());
3261 page_scheduler_->SetPageVisible(false);
3262 task_environment_.FastForwardBy(kGracePeriod);
3263
3264 // Post tasks in both frames, with delays shorter than the intensive wake up
3265 // interval.
3266 const base::TimeTicks post_time = base::TimeTicks::Now();
3267 std::vector<base::TimeTicks> run_times;
3268 task_runner->PostDelayedTask(FROM_HERE,
3269 base::BindOnce(&RecordRunTime, &run_times),
3270 kDefaultThrottledWakeUpInterval + kShortDelay);
3271 other_task_runner->PostDelayedTask(
3272 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
3273 2 * kDefaultThrottledWakeUpInterval + kShortDelay);
3274 task_environment_.FastForwardUntilNoTasksRemain();
3275
3276 // The first task is 1-second aligned, because there was no wake up in the
3277 // last minute. The second task is 1-minute aligned if the TaskType supports
3278 // intensive throttling, or 1-second aligned otherwise.
3279 if (IsIntensiveThrottlingExpected()) {
3280 EXPECT_THAT(run_times,
3281 testing::ElementsAre(
3282 post_time + 2 * kDefaultThrottledWakeUpInterval,
3283 post_time + kIntensiveThrottlingDurationBetweenWakeUps));
3284 } else {
3285 EXPECT_THAT(
3286 run_times,
3287 testing::ElementsAre(post_time + 2 * kDefaultThrottledWakeUpInterval,
3288 post_time + 3 * kDefaultThrottledWakeUpInterval));
3289 }
3290 }
3291
3292 // Verify that intensive throttling is disabled when there is an opt-out.
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,AggressiveThrottlingOptOut)3293 TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
3294 AggressiveThrottlingOptOut) {
3295 constexpr int kNumTasks = 3;
3296 // |task_runner| is throttled.
3297 const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
3298 frame_scheduler_->GetTaskRunner(GetTaskType());
3299 // |other_task_runner| is throttled. It belongs to a different frame on the
3300 // same page.
3301 const auto other_frame_scheduler = CreateFrameScheduler(
3302 page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
3303 FrameScheduler::FrameType::kSubframe);
3304 const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner =
3305 frame_scheduler_->GetTaskRunner(GetTaskType());
3306
3307 // Fast-forward the time to a multiple of
3308 // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise,
3309 // the time at which tasks can run after throttling is enabled will vary.
3310 FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
3311
3312 // Hide the page and wait until the intensive throttling grace period has
3313 // elapsed.
3314 EXPECT_TRUE(page_scheduler_->IsPageVisible());
3315 page_scheduler_->SetPageVisible(false);
3316 task_environment_.FastForwardBy(kGracePeriod);
3317
3318 {
3319 // Wake ups are intensively throttled, since there is no throttling opt-out.
3320 const base::TimeTicks scope_start = base::TimeTicks::Now();
3321 std::vector<base::TimeTicks> run_times;
3322 for (int i = 1; i < kNumTasks + 1; ++i) {
3323 task_runner->PostDelayedTask(FROM_HERE,
3324 base::BindOnce(&RecordRunTime, &run_times),
3325 i * kShortDelay);
3326 }
3327 for (int i = 1; i < kNumTasks + 1; ++i) {
3328 task_runner->PostDelayedTask(
3329 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
3330 kDefaultThrottledWakeUpInterval + i * kShortDelay);
3331 }
3332 task_environment_.FastForwardUntilNoTasksRemain();
3333 if (IsIntensiveThrottlingExpected()) {
3334 // Note: Wake ups can be unaligned when there is no recent wake up.
3335 EXPECT_THAT(
3336 run_times,
3337 testing::ElementsAre(
3338 scope_start + kDefaultThrottledWakeUpInterval,
3339 scope_start + kDefaultThrottledWakeUpInterval,
3340 scope_start + kDefaultThrottledWakeUpInterval,
3341 scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
3342 scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
3343 scope_start + kIntensiveThrottlingDurationBetweenWakeUps));
3344 } else {
3345 EXPECT_THAT(run_times,
3346 testing::ElementsAre(
3347 scope_start + kDefaultThrottledWakeUpInterval,
3348 scope_start + kDefaultThrottledWakeUpInterval,
3349 scope_start + kDefaultThrottledWakeUpInterval,
3350 scope_start + 2 * kDefaultThrottledWakeUpInterval,
3351 scope_start + 2 * kDefaultThrottledWakeUpInterval,
3352 scope_start + 2 * kDefaultThrottledWakeUpInterval));
3353 }
3354 }
3355
3356 {
3357 // Create an opt-out.
3358 auto handle = frame_scheduler_->RegisterFeature(
3359 SchedulingPolicy::Feature::kWebRTC,
3360 {SchedulingPolicy::DisableAggressiveThrottling()});
3361
3362 {
3363 // Tasks should run after |kDefaultThrottledWakeUpInterval|, since
3364 // aggressive throttling is disabled, but default wake up throttling
3365 // remains enabled.
3366 const base::TimeTicks scope_start = base::TimeTicks::Now();
3367 std::vector<base::TimeTicks> run_times;
3368 for (int i = 1; i < kNumTasks + 1; ++i) {
3369 task_runner->PostDelayedTask(FROM_HERE,
3370 base::BindOnce(&RecordRunTime, &run_times),
3371 i * kShortDelay);
3372 }
3373 task_environment_.FastForwardUntilNoTasksRemain();
3374 EXPECT_THAT(
3375 run_times,
3376 testing::ElementsAre(scope_start + kDefaultThrottledWakeUpInterval,
3377 scope_start + kDefaultThrottledWakeUpInterval,
3378 scope_start + kDefaultThrottledWakeUpInterval));
3379 }
3380
3381 {
3382 // Same thing for another frame on the same page.
3383 const base::TimeTicks scope_start = base::TimeTicks::Now();
3384 std::vector<base::TimeTicks> run_times;
3385 for (int i = 1; i < kNumTasks + 1; ++i) {
3386 other_task_runner->PostDelayedTask(
3387 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
3388 i * kShortDelay);
3389 }
3390 task_environment_.FastForwardUntilNoTasksRemain();
3391 EXPECT_THAT(
3392 run_times,
3393 testing::ElementsAre(scope_start + kDefaultThrottledWakeUpInterval,
3394 scope_start + kDefaultThrottledWakeUpInterval,
3395 scope_start + kDefaultThrottledWakeUpInterval));
3396 }
3397 }
3398
3399 // Fast-forward so that there is no recent wake up. Then, align the time on
3400 // |kIntensiveThrottlingDurationBetweenWakeUps| to simplify expectations.
3401 task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps);
3402 FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
3403
3404 {
3405 // Wake ups are intensively throttled, since there is no throttling opt-out.
3406 const base::TimeTicks scope_start = base::TimeTicks::Now();
3407 std::vector<base::TimeTicks> run_times;
3408 for (int i = 1; i < kNumTasks + 1; ++i) {
3409 task_runner->PostDelayedTask(FROM_HERE,
3410 base::BindOnce(&RecordRunTime, &run_times),
3411 i * kShortDelay);
3412 }
3413 for (int i = 1; i < kNumTasks + 1; ++i) {
3414 task_runner->PostDelayedTask(
3415 FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
3416 kDefaultThrottledWakeUpInterval + i * kShortDelay);
3417 }
3418 task_environment_.FastForwardUntilNoTasksRemain();
3419 if (IsIntensiveThrottlingExpected()) {
3420 // Note: Wake ups can be unaligned when there is no recent wake up.
3421 EXPECT_THAT(
3422 run_times,
3423 testing::ElementsAre(
3424 scope_start + kDefaultThrottledWakeUpInterval,
3425 scope_start + kDefaultThrottledWakeUpInterval,
3426 scope_start + kDefaultThrottledWakeUpInterval,
3427 scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
3428 scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
3429 scope_start + kIntensiveThrottlingDurationBetweenWakeUps));
3430 } else {
3431 EXPECT_THAT(run_times,
3432 testing::ElementsAre(
3433 scope_start + kDefaultThrottledWakeUpInterval,
3434 scope_start + kDefaultThrottledWakeUpInterval,
3435 scope_start + kDefaultThrottledWakeUpInterval,
3436 scope_start + 2 * kDefaultThrottledWakeUpInterval,
3437 scope_start + 2 * kDefaultThrottledWakeUpInterval,
3438 scope_start + 2 * kDefaultThrottledWakeUpInterval));
3439 }
3440 }
3441 }
3442
3443 // Verify that tasks run at the same time when a frame switches between being
3444 // same-origin and cross-origin with the main frame.
TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,FrameChangesOriginType)3445 TEST_P(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
3446 FrameChangesOriginType) {
3447 EXPECT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
3448 const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
3449 frame_scheduler_->GetTaskRunner(GetTaskType());
3450
3451 // Create a new FrameScheduler that remains cross-origin with the main frame
3452 // throughout the test.
3453 std::unique_ptr<FrameSchedulerImpl> cross_origin_frame_scheduler =
3454 CreateFrameScheduler(page_scheduler_.get(),
3455 frame_scheduler_delegate_.get(), nullptr,
3456 FrameScheduler::FrameType::kSubframe);
3457 cross_origin_frame_scheduler->SetCrossOriginToMainFrame(true);
3458 const scoped_refptr<base::SingleThreadTaskRunner> cross_origin_task_runner =
3459 cross_origin_frame_scheduler->GetTaskRunner(GetTaskType());
3460
3461 // Snap the time to a multiple of
3462 // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which
3463 // tasks can run after throttling is enabled will vary.
3464 FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
3465
3466 // Hide the page and wait until the intensive throttling grace period has
3467 // elapsed.
3468 EXPECT_TRUE(page_scheduler_->IsPageVisible());
3469 page_scheduler_->SetPageVisible(false);
3470 task_environment_.FastForwardBy(kGracePeriod);
3471
3472 {
3473 // Post delayed tasks with short delays to both frames. The
3474 // main-frame-origin task can run at the desired time, because there is no
3475 // recent wake up. The cross-origin task must run at an aligned time.
3476 int counter = 0;
3477 task_runner->PostDelayedTask(
3478 FROM_HERE,
3479 base::BindOnce(&IncrementCounter, base::Unretained(&counter)),
3480 kDefaultThrottledWakeUpInterval);
3481 int cross_origin_counter = 0;
3482 cross_origin_task_runner->PostDelayedTask(
3483 FROM_HERE,
3484 base::BindOnce(&IncrementCounter,
3485 base::Unretained(&cross_origin_counter)),
3486 kDefaultThrottledWakeUpInterval);
3487
3488 // Make the |frame_scheduler_| cross-origin. Its task must now run at an
3489 // aligned time.
3490 frame_scheduler_->SetCrossOriginToMainFrame(true);
3491
3492 task_environment_.FastForwardBy(kDefaultThrottledWakeUpInterval);
3493 if (IsIntensiveThrottlingExpected()) {
3494 EXPECT_EQ(0, counter);
3495 EXPECT_EQ(0, cross_origin_counter);
3496 } else {
3497 EXPECT_EQ(1, counter);
3498 EXPECT_EQ(1, cross_origin_counter);
3499 }
3500
3501 FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
3502 EXPECT_EQ(1, counter);
3503 EXPECT_EQ(1, cross_origin_counter);
3504 }
3505
3506 {
3507 // Post delayed tasks with long delays that aren't aligned with the wake up
3508 // interval. They should run at aligned times, since they are cross-origin.
3509 const base::TimeDelta kLongUnalignedDelay =
3510 5 * kIntensiveThrottlingDurationBetweenWakeUps +
3511 kDefaultThrottledWakeUpInterval;
3512 int counter = 0;
3513 task_runner->PostDelayedTask(
3514 FROM_HERE,
3515 base::BindOnce(&IncrementCounter, base::Unretained(&counter)),
3516 kLongUnalignedDelay);
3517 int cross_origin_counter = 0;
3518 cross_origin_task_runner->PostDelayedTask(
3519 FROM_HERE,
3520 base::BindOnce(&IncrementCounter,
3521 base::Unretained(&cross_origin_counter)),
3522 kLongUnalignedDelay);
3523
3524 // Make the |frame_scheduler_| same-origin. Its task can now run at a
3525 // 1-second aligned time, since there was no wake up in the last minute.
3526 frame_scheduler_->SetCrossOriginToMainFrame(false);
3527
3528 task_environment_.FastForwardBy(kLongUnalignedDelay);
3529 if (IsIntensiveThrottlingExpected()) {
3530 EXPECT_EQ(1, counter);
3531 EXPECT_EQ(0, cross_origin_counter);
3532 } else {
3533 EXPECT_EQ(1, counter);
3534 EXPECT_EQ(1, cross_origin_counter);
3535 }
3536
3537 FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
3538 EXPECT_EQ(1, counter);
3539 EXPECT_EQ(1, cross_origin_counter);
3540 }
3541 }
3542
3543 INSTANTIATE_TEST_SUITE_P(
3544 AllTimerTaskTypes,
3545 FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
3546 testing::Values(
3547 IntensiveWakeUpThrottlingTestParam{
3548 /* task_type=*/TaskType::kJavascriptTimerDelayedLowNesting,
3549 /* can_intensively_throttle_low_nesting_level=*/false,
3550 /* is_intensive_throttling_expected=*/false},
3551 IntensiveWakeUpThrottlingTestParam{
3552 /* task_type=*/TaskType::kJavascriptTimerDelayedLowNesting,
3553 /* can_intensively_throttle_low_nesting_level=*/true,
3554 /* is_intensive_throttling_expected=*/true},
3555 IntensiveWakeUpThrottlingTestParam{
3556 /* task_type=*/TaskType::kJavascriptTimerDelayedHighNesting,
3557 /* can_intensively_throttle_low_nesting_level=*/false,
3558 /* is_intensive_throttling_expected=*/true}),
__anonca7fdf3d1102(const testing::TestParamInfo<IntensiveWakeUpThrottlingTestParam>& info) 3559 [](const testing::TestParamInfo<IntensiveWakeUpThrottlingTestParam>& info) {
3560 const std::string task_type =
3561 TaskTypeNames::TaskTypeToString(info.param.task_type);
3562 if (info.param.can_intensively_throttle_low_nesting_level)
3563 return task_type + "_can_intensively_throttle_low_nesting_level";
3564 return task_type;
3565 });
3566
TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride,PolicyForceEnable)3567 TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride,
3568 PolicyForceEnable) {
3569 SetPolicyOverride(/* enabled = */ true);
3570 EXPECT_TRUE(IsIntensiveWakeUpThrottlingEnabled());
3571
3572 // The parameters should be the defaults.
3573 EXPECT_EQ(base::TimeDelta::FromSeconds(
3574 kIntensiveWakeUpThrottling_GracePeriodSeconds_Default),
3575 GetIntensiveWakeUpThrottlingGracePeriod());
3576 EXPECT_EQ(
3577 base::TimeDelta::FromSeconds(
3578 kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds_Default),
3579 GetIntensiveWakeUpThrottlingDurationBetweenWakeUps());
3580 EXPECT_EQ(
3581 kIntensiveWakeUpThrottling_CanIntensivelyThrottleLowNestingLevel_Default,
3582 CanIntensivelyThrottleLowNestingLevel());
3583 }
3584
TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride,PolicyForceDisable)3585 TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride,
3586 PolicyForceDisable) {
3587 SetPolicyOverride(/* enabled = */ false);
3588 EXPECT_FALSE(IsIntensiveWakeUpThrottlingEnabled());
3589 }
3590
3591 } // namespace frame_scheduler_impl_unittest
3592 } // namespace scheduler
3593 } // namespace blink
3594