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