Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(863)

Side by Side Diff: components/scheduler/renderer/renderer_scheduler_impl_unittest.cc

Issue 2118903002: scheduler: Move the Blink scheduler into Blink (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 "components/scheduler/renderer/renderer_scheduler_impl.h"
6
7 #include <utility>
8
9 #include "base/callback.h"
10 #include "base/macros.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/run_loop.h"
13 #include "base/test/simple_test_tick_clock.h"
14 #include "cc/output/begin_frame_args.h"
15 #include "cc/test/ordered_simple_task_runner.h"
16 #include "components/scheduler/base/test_time_source.h"
17 #include "components/scheduler/child/scheduler_tqm_delegate_for_test.h"
18 #include "components/scheduler/child/scheduler_tqm_delegate_impl.h"
19 #include "components/scheduler/renderer/auto_advancing_virtual_time_domain.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace scheduler {
24
25 namespace {
26 class FakeInputEvent : public blink::WebInputEvent {
27 public:
28 explicit FakeInputEvent(blink::WebInputEvent::Type event_type)
29 : WebInputEvent(sizeof(FakeInputEvent)) {
30 type = event_type;
31 }
32
33 FakeInputEvent(blink::WebInputEvent::Type event_type, int event_modifiers)
34 : WebInputEvent(sizeof(FakeInputEvent)) {
35 type = event_type;
36 modifiers = event_modifiers;
37 }
38 };
39
40 void AppendToVectorTestTask(std::vector<std::string>* vector,
41 std::string value) {
42 vector->push_back(value);
43 }
44
45 void AppendToVectorIdleTestTask(std::vector<std::string>* vector,
46 std::string value,
47 base::TimeTicks deadline) {
48 AppendToVectorTestTask(vector, value);
49 }
50
51 void NullTask() {
52 }
53
54 void AppendToVectorReentrantTask(base::SingleThreadTaskRunner* task_runner,
55 std::vector<int>* vector,
56 int* reentrant_count,
57 int max_reentrant_count) {
58 vector->push_back((*reentrant_count)++);
59 if (*reentrant_count < max_reentrant_count) {
60 task_runner->PostTask(
61 FROM_HERE,
62 base::Bind(AppendToVectorReentrantTask, base::Unretained(task_runner),
63 vector, reentrant_count, max_reentrant_count));
64 }
65 }
66
67 void IdleTestTask(int* run_count,
68 base::TimeTicks* deadline_out,
69 base::TimeTicks deadline) {
70 (*run_count)++;
71 *deadline_out = deadline;
72 }
73
74 int max_idle_task_reposts = 2;
75
76 void RepostingIdleTestTask(SingleThreadIdleTaskRunner* idle_task_runner,
77 int* run_count,
78 base::TimeTicks deadline) {
79 if ((*run_count + 1) < max_idle_task_reposts) {
80 idle_task_runner->PostIdleTask(
81 FROM_HERE, base::Bind(&RepostingIdleTestTask,
82 base::Unretained(idle_task_runner), run_count));
83 }
84 (*run_count)++;
85 }
86
87 void RepostingUpdateClockIdleTestTask(
88 SingleThreadIdleTaskRunner* idle_task_runner,
89 int* run_count,
90 base::SimpleTestTickClock* clock,
91 base::TimeDelta advance_time,
92 std::vector<base::TimeTicks>* deadlines,
93 base::TimeTicks deadline) {
94 if ((*run_count + 1) < max_idle_task_reposts) {
95 idle_task_runner->PostIdleTask(
96 FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask,
97 base::Unretained(idle_task_runner), run_count,
98 clock, advance_time, deadlines));
99 }
100 deadlines->push_back(deadline);
101 (*run_count)++;
102 clock->Advance(advance_time);
103 }
104
105 void WillBeginFrameIdleTask(RendererScheduler* scheduler,
106 base::SimpleTestTickClock* clock,
107 base::TimeTicks deadline) {
108 scheduler->WillBeginFrame(cc::BeginFrameArgs::Create(
109 BEGINFRAME_FROM_HERE, clock->NowTicks(), base::TimeTicks(),
110 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
111 }
112
113 void UpdateClockToDeadlineIdleTestTask(base::SimpleTestTickClock* clock,
114 int* run_count,
115 base::TimeTicks deadline) {
116 clock->Advance(deadline - clock->NowTicks());
117 (*run_count)++;
118 }
119
120 void PostingYieldingTestTask(RendererSchedulerImpl* scheduler,
121 base::SingleThreadTaskRunner* task_runner,
122 bool simulate_input,
123 bool* should_yield_before,
124 bool* should_yield_after) {
125 *should_yield_before = scheduler->ShouldYieldForHighPriorityWork();
126 task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
127 if (simulate_input) {
128 scheduler->DidHandleInputEventOnCompositorThread(
129 FakeInputEvent(blink::WebInputEvent::TouchMove),
130 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
131 }
132 *should_yield_after = scheduler->ShouldYieldForHighPriorityWork();
133 }
134
135 enum class SimulateInputType {
136 None,
137 TouchStart,
138 TouchEnd,
139 GestureScrollBegin,
140 GestureScrollEnd
141 };
142
143 void AnticipationTestTask(RendererSchedulerImpl* scheduler,
144 SimulateInputType simulate_input,
145 bool* is_anticipated_before,
146 bool* is_anticipated_after) {
147 *is_anticipated_before = scheduler->IsHighPriorityWorkAnticipated();
148 switch (simulate_input) {
149 case SimulateInputType::None:
150 break;
151
152 case SimulateInputType::TouchStart:
153 scheduler->DidHandleInputEventOnCompositorThread(
154 FakeInputEvent(blink::WebInputEvent::TouchStart),
155 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
156 break;
157
158 case SimulateInputType::TouchEnd:
159 scheduler->DidHandleInputEventOnCompositorThread(
160 FakeInputEvent(blink::WebInputEvent::TouchEnd),
161 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
162 break;
163
164 case SimulateInputType::GestureScrollBegin:
165 scheduler->DidHandleInputEventOnCompositorThread(
166 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin),
167 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
168 break;
169
170 case SimulateInputType::GestureScrollEnd:
171 scheduler->DidHandleInputEventOnCompositorThread(
172 FakeInputEvent(blink::WebInputEvent::GestureScrollEnd),
173 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
174 break;
175 }
176 *is_anticipated_after = scheduler->IsHighPriorityWorkAnticipated();
177 }
178
179 }; // namespace
180
181 class RendererSchedulerImplForTest : public RendererSchedulerImpl {
182 public:
183 using RendererSchedulerImpl::OnIdlePeriodEnded;
184 using RendererSchedulerImpl::OnIdlePeriodStarted;
185 using RendererSchedulerImpl::EstimateLongestJankFreeTaskDuration;
186
187 RendererSchedulerImplForTest(
188 scoped_refptr<SchedulerTqmDelegate> main_task_runner)
189 : RendererSchedulerImpl(main_task_runner), update_policy_count_(0) {}
190
191 void UpdatePolicyLocked(UpdateType update_type) override {
192 update_policy_count_++;
193 RendererSchedulerImpl::UpdatePolicyLocked(update_type);
194
195 std::string use_case = RendererSchedulerImpl::UseCaseToString(
196 MainThreadOnly().current_use_case);
197 if (MainThreadOnly().touchstart_expected_soon) {
198 use_cases_.push_back(use_case + " touchstart expected");
199 } else {
200 use_cases_.push_back(use_case);
201 }
202 }
203
204 void EnsureUrgentPolicyUpdatePostedOnMainThread() {
205 base::AutoLock lock(any_thread_lock_);
206 RendererSchedulerImpl::EnsureUrgentPolicyUpdatePostedOnMainThread(
207 FROM_HERE);
208 }
209
210 void ScheduleDelayedPolicyUpdate(base::TimeTicks now, base::TimeDelta delay) {
211 delayed_update_policy_runner_.SetDeadline(FROM_HERE, delay, now);
212 }
213
214 bool BeginMainFrameOnCriticalPath() {
215 base::AutoLock lock(any_thread_lock_);
216 return AnyThread().begin_main_frame_on_critical_path;
217 }
218
219 int update_policy_count_;
220 std::vector<std::string> use_cases_;
221 };
222
223 // Lets gtest print human readable Policy values.
224 ::std::ostream& operator<<(::std::ostream& os,
225 const RendererSchedulerImpl::UseCase& use_case) {
226 return os << RendererSchedulerImpl::UseCaseToString(use_case);
227 }
228
229 class RendererSchedulerImplTest : public testing::Test {
230 public:
231 using UseCase = RendererSchedulerImpl::UseCase;
232
233 RendererSchedulerImplTest() : clock_(new base::SimpleTestTickClock()) {
234 clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
235 }
236
237 RendererSchedulerImplTest(base::MessageLoop* message_loop)
238 : clock_(new base::SimpleTestTickClock()), message_loop_(message_loop) {
239 clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
240 }
241
242 ~RendererSchedulerImplTest() override {}
243
244 void SetUp() override {
245 if (message_loop_) {
246 main_task_runner_ = SchedulerTqmDelegateImpl::Create(
247 message_loop_.get(),
248 base::WrapUnique(new TestTimeSource(clock_.get())));
249 } else {
250 mock_task_runner_ = make_scoped_refptr(
251 new cc::OrderedSimpleTaskRunner(clock_.get(), false));
252 main_task_runner_ = SchedulerTqmDelegateForTest::Create(
253 mock_task_runner_,
254 base::WrapUnique(new TestTimeSource(clock_.get())));
255 }
256 Initialize(
257 base::WrapUnique(new RendererSchedulerImplForTest(main_task_runner_)));
258 }
259
260 void Initialize(std::unique_ptr<RendererSchedulerImplForTest> scheduler) {
261 scheduler_ = std::move(scheduler);
262 default_task_runner_ = scheduler_->DefaultTaskRunner();
263 compositor_task_runner_ = scheduler_->CompositorTaskRunner();
264 loading_task_runner_ = scheduler_->LoadingTaskRunner();
265 idle_task_runner_ = scheduler_->IdleTaskRunner();
266 timer_task_runner_ = scheduler_->TimerTaskRunner();
267 }
268
269 void TearDown() override {
270 DCHECK(!mock_task_runner_.get() || !message_loop_.get());
271 scheduler_->Shutdown();
272 if (mock_task_runner_.get()) {
273 // Check that all tests stop posting tasks.
274 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
275 while (mock_task_runner_->RunUntilIdle()) {
276 }
277 } else {
278 base::RunLoop().RunUntilIdle();
279 }
280 scheduler_.reset();
281 }
282
283 void RunUntilIdle() {
284 // Only one of mock_task_runner_ or message_loop_ should be set.
285 DCHECK(!mock_task_runner_.get() || !message_loop_.get());
286 if (mock_task_runner_.get())
287 mock_task_runner_->RunUntilIdle();
288 else
289 base::RunLoop().RunUntilIdle();
290 }
291
292 void DoMainFrame() {
293 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
294 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
295 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
296 begin_frame_args.on_critical_path = false;
297 scheduler_->WillBeginFrame(begin_frame_args);
298 scheduler_->DidCommitFrameToCompositor();
299 }
300
301 void DoMainFrameOnCriticalPath() {
302 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
303 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
304 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
305 begin_frame_args.on_critical_path = true;
306 scheduler_->WillBeginFrame(begin_frame_args);
307 }
308
309 void ForceTouchStartToBeExpectedSoon() {
310 scheduler_->DidHandleInputEventOnCompositorThread(
311 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate),
312 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
313 scheduler_->DidHandleInputEventOnCompositorThread(
314 FakeInputEvent(blink::WebInputEvent::GestureScrollEnd),
315 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
316 clock_->Advance(priority_escalation_after_input_duration() * 2);
317 scheduler_->ForceUpdatePolicy();
318 }
319
320 void SimulateExpensiveTasks(
321 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
322 // RunUntilIdle won't actually run all of the SimpleTestTickClock::Advance
323 // tasks unless we set AutoAdvanceNow to true :/
324 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
325
326 // Simulate a bunch of expensive tasks
327 for (int i = 0; i < 10; i++) {
328 task_runner->PostTask(FROM_HERE,
329 base::Bind(&base::SimpleTestTickClock::Advance,
330 base::Unretained(clock_.get()),
331 base::TimeDelta::FromMilliseconds(500)));
332 }
333
334 RunUntilIdle();
335
336 // Switch back to not auto-advancing because we want to be in control of
337 // when time advances.
338 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(false);
339 }
340
341 enum class TouchEventPolicy {
342 SEND_TOUCH_START,
343 DONT_SEND_TOUCH_START,
344 };
345
346 void SimulateCompositorGestureStart(TouchEventPolicy touch_event_policy) {
347 if (touch_event_policy == TouchEventPolicy::SEND_TOUCH_START) {
348 scheduler_->DidHandleInputEventOnCompositorThread(
349 FakeInputEvent(blink::WebInputEvent::TouchStart),
350 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
351 scheduler_->DidHandleInputEventOnCompositorThread(
352 FakeInputEvent(blink::WebInputEvent::TouchMove),
353 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
354 scheduler_->DidHandleInputEventOnCompositorThread(
355 FakeInputEvent(blink::WebInputEvent::TouchMove),
356 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
357 }
358 scheduler_->DidHandleInputEventOnCompositorThread(
359 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin),
360 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
361 scheduler_->DidHandleInputEventOnCompositorThread(
362 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate),
363 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
364 }
365
366 // Simulate a gesture where there is an active compositor scroll, but no
367 // scroll updates are generated. Instead, the main thread handles
368 // non-canceleable touch events, making this an effectively main thread
369 // driven gesture.
370 void SimulateMainThreadGestureWithoutScrollUpdates() {
371 scheduler_->DidHandleInputEventOnCompositorThread(
372 FakeInputEvent(blink::WebInputEvent::TouchStart),
373 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
374 scheduler_->DidHandleInputEventOnCompositorThread(
375 FakeInputEvent(blink::WebInputEvent::TouchMove),
376 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
377 scheduler_->DidHandleInputEventOnCompositorThread(
378 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin),
379 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
380 scheduler_->DidHandleInputEventOnCompositorThread(
381 FakeInputEvent(blink::WebInputEvent::TouchMove),
382 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
383 }
384
385 // Simulate a gesture where the main thread handles touch events but does not
386 // preventDefault(), allowing the gesture to turn into a compositor driven
387 // gesture. This function also verifies the necessary policy updates are
388 // scheduled.
389 void SimulateMainThreadGestureWithoutPreventDefault() {
390 scheduler_->DidHandleInputEventOnCompositorThread(
391 FakeInputEvent(blink::WebInputEvent::TouchStart),
392 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
393
394 // Touchstart policy update.
395 EXPECT_TRUE(scheduler_->PolicyNeedsUpdateForTesting());
396 EXPECT_EQ(UseCase::TOUCHSTART, ForceUpdatePolicyAndGetCurrentUseCase());
397 EXPECT_FALSE(scheduler_->PolicyNeedsUpdateForTesting());
398
399 scheduler_->DidHandleInputEventOnCompositorThread(
400 FakeInputEvent(blink::WebInputEvent::TouchMove),
401 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
402 scheduler_->DidHandleInputEventOnCompositorThread(
403 FakeInputEvent(blink::WebInputEvent::GestureTapCancel),
404 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
405 scheduler_->DidHandleInputEventOnCompositorThread(
406 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin),
407 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
408
409 // Main thread gesture policy update.
410 EXPECT_TRUE(scheduler_->PolicyNeedsUpdateForTesting());
411 EXPECT_EQ(UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
412 ForceUpdatePolicyAndGetCurrentUseCase());
413 EXPECT_FALSE(scheduler_->PolicyNeedsUpdateForTesting());
414
415 scheduler_->DidHandleInputEventOnCompositorThread(
416 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate),
417 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
418 scheduler_->DidHandleInputEventOnCompositorThread(
419 FakeInputEvent(blink::WebInputEvent::TouchScrollStarted),
420 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
421 scheduler_->DidHandleInputEventOnCompositorThread(
422 FakeInputEvent(blink::WebInputEvent::TouchMove),
423 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
424
425 // Compositor thread gesture policy update.
426 EXPECT_TRUE(scheduler_->PolicyNeedsUpdateForTesting());
427 EXPECT_EQ(UseCase::COMPOSITOR_GESTURE,
428 ForceUpdatePolicyAndGetCurrentUseCase());
429 EXPECT_FALSE(scheduler_->PolicyNeedsUpdateForTesting());
430 }
431
432 void SimulateMainThreadGestureStart(TouchEventPolicy touch_event_policy,
433 blink::WebInputEvent::Type gesture_type) {
434 if (touch_event_policy == TouchEventPolicy::SEND_TOUCH_START) {
435 scheduler_->DidHandleInputEventOnCompositorThread(
436 FakeInputEvent(blink::WebInputEvent::TouchStart),
437 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
438 scheduler_->DidHandleInputEventOnMainThread(
439 FakeInputEvent(blink::WebInputEvent::TouchStart));
440
441 scheduler_->DidHandleInputEventOnCompositorThread(
442 FakeInputEvent(blink::WebInputEvent::TouchMove),
443 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
444 scheduler_->DidHandleInputEventOnMainThread(
445 FakeInputEvent(blink::WebInputEvent::TouchMove));
446
447 scheduler_->DidHandleInputEventOnCompositorThread(
448 FakeInputEvent(blink::WebInputEvent::TouchMove),
449 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
450 scheduler_->DidHandleInputEventOnMainThread(
451 FakeInputEvent(blink::WebInputEvent::TouchMove));
452 }
453 if (gesture_type != blink::WebInputEvent::Undefined) {
454 scheduler_->DidHandleInputEventOnCompositorThread(
455 FakeInputEvent(gesture_type),
456 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
457 scheduler_->DidHandleInputEventOnMainThread(FakeInputEvent(gesture_type));
458 }
459 }
460
461 void SimulateMainThreadInputHandlingCompositorTask(
462 base::TimeDelta begin_main_frame_duration) {
463 scheduler_->DidHandleInputEventOnCompositorThread(
464 FakeInputEvent(blink::WebInputEvent::TouchMove),
465 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
466 clock_->Advance(begin_main_frame_duration);
467 scheduler_->DidHandleInputEventOnMainThread(
468 FakeInputEvent(blink::WebInputEvent::TouchMove));
469 scheduler_->DidCommitFrameToCompositor();
470 }
471
472 void SimulateMainThreadCompositorTask(
473 base::TimeDelta begin_main_frame_duration) {
474 clock_->Advance(begin_main_frame_duration);
475 scheduler_->DidCommitFrameToCompositor();
476 simulate_compositor_task_ran_ = true;
477 }
478
479 bool SimulatedCompositorTaskPending() const {
480 return !simulate_compositor_task_ran_;
481 }
482
483 void SimulateTimerTask(base::TimeDelta duration) {
484 clock_->Advance(duration);
485 simulate_timer_task_ran_ = true;
486 }
487
488 void EnableIdleTasks() { DoMainFrame(); }
489
490 UseCase CurrentUseCase() {
491 return scheduler_->MainThreadOnly().current_use_case;
492 }
493
494 UseCase ForceUpdatePolicyAndGetCurrentUseCase() {
495 scheduler_->ForceUpdatePolicy();
496 return scheduler_->MainThreadOnly().current_use_case;
497 }
498
499 v8::RAILMode RAILMode() {
500 return scheduler_->MainThreadOnly().current_policy.rail_mode;
501 }
502
503 bool BeginFrameNotExpectedSoon() {
504 return scheduler_->MainThreadOnly().begin_frame_not_expected_soon;
505 }
506
507 bool TouchStartExpectedSoon() {
508 return scheduler_->MainThreadOnly().touchstart_expected_soon;
509 }
510
511 bool HaveSeenABeginMainframe() {
512 return scheduler_->MainThreadOnly().have_seen_a_begin_main_frame;
513 }
514
515 bool LoadingTasksSeemExpensive() {
516 return scheduler_->MainThreadOnly().loading_tasks_seem_expensive;
517 }
518
519 bool TimerTasksSeemExpensive() {
520 return scheduler_->MainThreadOnly().timer_tasks_seem_expensive;
521 }
522
523 base::TimeTicks EstimatedNextFrameBegin() {
524 return scheduler_->MainThreadOnly().estimated_next_frame_begin;
525 }
526
527 int NavigationTaskExpectedCount() {
528 return scheduler_->MainThreadOnly().navigation_task_expected_count;
529 }
530
531 // Helper for posting several tasks of specific types. |task_descriptor| is a
532 // string with space delimited task identifiers. The first letter of each
533 // task identifier specifies the task type:
534 // - 'D': Default task
535 // - 'C': Compositor task
536 // - 'L': Loading task
537 // - 'I': Idle task
538 // - 'T': Timer task
539 void PostTestTasks(std::vector<std::string>* run_order,
540 const std::string& task_descriptor) {
541 std::istringstream stream(task_descriptor);
542 while (!stream.eof()) {
543 std::string task;
544 stream >> task;
545 switch (task[0]) {
546 case 'D':
547 default_task_runner_->PostTask(
548 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
549 break;
550 case 'C':
551 compositor_task_runner_->PostTask(
552 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
553 break;
554 case 'L':
555 loading_task_runner_->PostTask(
556 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
557 break;
558 case 'I':
559 idle_task_runner_->PostIdleTask(
560 FROM_HERE,
561 base::Bind(&AppendToVectorIdleTestTask, run_order, task));
562 break;
563 case 'T':
564 timer_task_runner_->PostTask(
565 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
566 break;
567 default:
568 NOTREACHED();
569 }
570 }
571 }
572
573 protected:
574 static base::TimeDelta priority_escalation_after_input_duration() {
575 return base::TimeDelta::FromMilliseconds(
576 UserModel::kGestureEstimationLimitMillis);
577 }
578
579 static base::TimeDelta subsequent_input_expected_after_input_duration() {
580 return base::TimeDelta::FromMilliseconds(
581 UserModel::kExpectSubsequentGestureMillis);
582 }
583
584 static base::TimeDelta maximum_idle_period_duration() {
585 return base::TimeDelta::FromMilliseconds(
586 IdleHelper::kMaximumIdlePeriodMillis);
587 }
588
589 static base::TimeDelta end_idle_when_hidden_delay() {
590 return base::TimeDelta::FromMilliseconds(
591 RendererSchedulerImpl::kEndIdleWhenHiddenDelayMillis);
592 }
593
594 static base::TimeDelta idle_period_starvation_threshold() {
595 return base::TimeDelta::FromMilliseconds(
596 RendererSchedulerImpl::kIdlePeriodStarvationThresholdMillis);
597 }
598
599 static base::TimeDelta suspend_timers_when_backgrounded_delay() {
600 return base::TimeDelta::FromMilliseconds(
601 RendererSchedulerImpl::kSuspendTimersWhenBackgroundedDelayMillis);
602 }
603
604 static base::TimeDelta rails_response_time() {
605 return base::TimeDelta::FromMilliseconds(
606 RendererSchedulerImpl::kRailsResponseTimeMillis);
607 }
608
609 template <typename E>
610 static void CallForEachEnumValue(E first,
611 E last,
612 const char* (*function)(E)) {
613 for (E val = first; val < last;
614 val = static_cast<E>(static_cast<int>(val) + 1)) {
615 (*function)(val);
616 }
617 }
618
619 static void CheckAllUseCaseToString() {
620 CallForEachEnumValue<RendererSchedulerImpl::UseCase>(
621 RendererSchedulerImpl::UseCase::FIRST_USE_CASE,
622 RendererSchedulerImpl::UseCase::USE_CASE_COUNT,
623 &RendererSchedulerImpl::UseCaseToString);
624 }
625
626 std::unique_ptr<base::SimpleTestTickClock> clock_;
627 // Only one of mock_task_runner_ or message_loop_ will be set.
628 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
629 std::unique_ptr<base::MessageLoop> message_loop_;
630
631 scoped_refptr<SchedulerTqmDelegate> main_task_runner_;
632 std::unique_ptr<RendererSchedulerImplForTest> scheduler_;
633 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
634 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
635 scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
636 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
637 scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_;
638 bool simulate_timer_task_ran_;
639 bool simulate_compositor_task_ran_;
640
641 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest);
642 };
643
644 TEST_F(RendererSchedulerImplTest, TestPostDefaultTask) {
645 std::vector<std::string> run_order;
646 PostTestTasks(&run_order, "D1 D2 D3 D4");
647
648 RunUntilIdle();
649 EXPECT_THAT(run_order,
650 testing::ElementsAre(std::string("D1"), std::string("D2"),
651 std::string("D3"), std::string("D4")));
652 }
653
654 TEST_F(RendererSchedulerImplTest, TestPostDefaultAndCompositor) {
655 std::vector<std::string> run_order;
656 PostTestTasks(&run_order, "D1 C1");
657 RunUntilIdle();
658 EXPECT_THAT(run_order, testing::Contains("D1"));
659 EXPECT_THAT(run_order, testing::Contains("C1"));
660 }
661
662 TEST_F(RendererSchedulerImplTest, TestRentrantTask) {
663 int count = 0;
664 std::vector<int> run_order;
665 default_task_runner_->PostTask(
666 FROM_HERE, base::Bind(AppendToVectorReentrantTask,
667 base::RetainedRef(default_task_runner_), &run_order,
668 &count, 5));
669 RunUntilIdle();
670
671 EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4));
672 }
673
674 TEST_F(RendererSchedulerImplTest, TestPostIdleTask) {
675 int run_count = 0;
676 base::TimeTicks expected_deadline =
677 clock_->NowTicks() + base::TimeDelta::FromMilliseconds(2300);
678 base::TimeTicks deadline_in_task;
679
680 clock_->Advance(base::TimeDelta::FromMilliseconds(100));
681 idle_task_runner_->PostIdleTask(
682 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
683
684 RunUntilIdle();
685 EXPECT_EQ(0, run_count); // Shouldn't run yet as no WillBeginFrame.
686
687 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
688 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
689 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
690 RunUntilIdle();
691 EXPECT_EQ(0, run_count); // Shouldn't run as no DidCommitFrameToCompositor.
692
693 clock_->Advance(base::TimeDelta::FromMilliseconds(1200));
694 scheduler_->DidCommitFrameToCompositor();
695 RunUntilIdle();
696 EXPECT_EQ(0, run_count); // We missed the deadline.
697
698 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
699 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
700 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
701 clock_->Advance(base::TimeDelta::FromMilliseconds(800));
702 scheduler_->DidCommitFrameToCompositor();
703 RunUntilIdle();
704 EXPECT_EQ(1, run_count);
705 EXPECT_EQ(expected_deadline, deadline_in_task);
706 }
707
708 TEST_F(RendererSchedulerImplTest, TestRepostingIdleTask) {
709 int run_count = 0;
710
711 max_idle_task_reposts = 2;
712 idle_task_runner_->PostIdleTask(
713 FROM_HERE, base::Bind(&RepostingIdleTestTask,
714 base::RetainedRef(idle_task_runner_), &run_count));
715 EnableIdleTasks();
716 RunUntilIdle();
717 EXPECT_EQ(1, run_count);
718
719 // Reposted tasks shouldn't run until next idle period.
720 RunUntilIdle();
721 EXPECT_EQ(1, run_count);
722
723 EnableIdleTasks();
724 RunUntilIdle();
725 EXPECT_EQ(2, run_count);
726 }
727
728 TEST_F(RendererSchedulerImplTest, TestIdleTaskExceedsDeadline) {
729 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
730 int run_count = 0;
731
732 // Post two UpdateClockToDeadlineIdleTestTask tasks.
733 idle_task_runner_->PostIdleTask(
734 FROM_HERE,
735 base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_.get(), &run_count));
736 idle_task_runner_->PostIdleTask(
737 FROM_HERE,
738 base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_.get(), &run_count));
739
740 EnableIdleTasks();
741 RunUntilIdle();
742 // Only the first idle task should execute since it's used up the deadline.
743 EXPECT_EQ(1, run_count);
744
745 EnableIdleTasks();
746 RunUntilIdle();
747 // Second task should be run on the next idle period.
748 EXPECT_EQ(2, run_count);
749 }
750
751 TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeup) {
752 base::TimeTicks deadline_in_task;
753 int run_count = 0;
754
755 idle_task_runner_->PostIdleTaskAfterWakeup(
756 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
757
758 EnableIdleTasks();
759 RunUntilIdle();
760 // Shouldn't run yet as no other task woke up the scheduler.
761 EXPECT_EQ(0, run_count);
762
763 idle_task_runner_->PostIdleTaskAfterWakeup(
764 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
765
766 EnableIdleTasks();
767 RunUntilIdle();
768 // Another after wakeup idle task shouldn't wake the scheduler.
769 EXPECT_EQ(0, run_count);
770
771 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
772
773 RunUntilIdle();
774 EnableIdleTasks(); // Must start a new idle period before idle task runs.
775 RunUntilIdle();
776 // Execution of default task queue task should trigger execution of idle task.
777 EXPECT_EQ(2, run_count);
778 }
779
780 TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeupWhileAwake) {
781 base::TimeTicks deadline_in_task;
782 int run_count = 0;
783
784 idle_task_runner_->PostIdleTaskAfterWakeup(
785 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
786 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
787
788 RunUntilIdle();
789 EnableIdleTasks(); // Must start a new idle period before idle task runs.
790 RunUntilIdle();
791 // Should run as the scheduler was already awakened by the normal task.
792 EXPECT_EQ(1, run_count);
793 }
794
795 TEST_F(RendererSchedulerImplTest, TestPostIdleTaskWakesAfterWakeupIdleTask) {
796 base::TimeTicks deadline_in_task;
797 int run_count = 0;
798
799 idle_task_runner_->PostIdleTaskAfterWakeup(
800 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
801 idle_task_runner_->PostIdleTask(
802 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
803
804 EnableIdleTasks();
805 RunUntilIdle();
806 // Must start a new idle period before after-wakeup idle task runs.
807 EnableIdleTasks();
808 RunUntilIdle();
809 // Normal idle task should wake up after-wakeup idle task.
810 EXPECT_EQ(2, run_count);
811 }
812
813 TEST_F(RendererSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) {
814 int run_count = 0;
815
816 base::TimeTicks deadline_in_task;
817 idle_task_runner_->PostIdleTask(
818 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
819
820 // Trigger the beginning of an idle period for 1000ms.
821 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
822 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
823 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
824 DoMainFrame();
825
826 // End the idle period early (after 500ms), and send a WillBeginFrame which
827 // specifies that the next idle period should end 1000ms from now.
828 clock_->Advance(base::TimeDelta::FromMilliseconds(500));
829 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
830 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
831 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
832
833 RunUntilIdle();
834 EXPECT_EQ(0, run_count); // Not currently in an idle period.
835
836 // Trigger the start of the idle period before the task to end the previous
837 // idle period has been triggered.
838 clock_->Advance(base::TimeDelta::FromMilliseconds(400));
839 scheduler_->DidCommitFrameToCompositor();
840
841 // Post a task which simulates running until after the previous end idle
842 // period delayed task was scheduled for
843 scheduler_->DefaultTaskRunner()->PostTask(FROM_HERE, base::Bind(NullTask));
844 clock_->Advance(base::TimeDelta::FromMilliseconds(300));
845
846 RunUntilIdle();
847 EXPECT_EQ(1, run_count); // We should still be in the new idle period.
848 }
849
850 TEST_F(RendererSchedulerImplTest, TestDefaultPolicy) {
851 std::vector<std::string> run_order;
852 PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
853
854 EnableIdleTasks();
855 RunUntilIdle();
856 EXPECT_THAT(run_order,
857 testing::ElementsAre(std::string("L1"), std::string("D1"),
858 std::string("C1"), std::string("D2"),
859 std::string("C2"), std::string("I1")));
860 EXPECT_EQ(RendererSchedulerImpl::UseCase::NONE, CurrentUseCase());
861 }
862
863 TEST_F(RendererSchedulerImplTest,
864 TestCompositorPolicy_CompositorHandlesInput_WithTouchHandler) {
865 std::vector<std::string> run_order;
866 PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
867
868 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
869 EnableIdleTasks();
870 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
871 RunUntilIdle();
872 EXPECT_THAT(run_order,
873 testing::ElementsAre(std::string("L1"), std::string("D1"),
874 std::string("D2"), std::string("I1"),
875 std::string("C1"), std::string("C2")));
876 EXPECT_EQ(RendererSchedulerImpl::UseCase::COMPOSITOR_GESTURE,
877 CurrentUseCase());
878 }
879
880 TEST_F(RendererSchedulerImplTest,
881 TestCompositorPolicy_MainThreadHandlesInput_WithoutScrollUpdates) {
882 std::vector<std::string> run_order;
883 PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
884
885 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
886 EnableIdleTasks();
887 SimulateMainThreadGestureWithoutScrollUpdates();
888 RunUntilIdle();
889 EXPECT_THAT(run_order,
890 testing::ElementsAre(std::string("C1"), std::string("C2"),
891 std::string("L1"), std::string("D1"),
892 std::string("D2"), std::string("I1")));
893 EXPECT_EQ(RendererSchedulerImpl::UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
894 CurrentUseCase());
895 }
896
897 TEST_F(RendererSchedulerImplTest,
898 TestCompositorPolicy_MainThreadHandlesInput_WithoutPreventDefault) {
899 std::vector<std::string> run_order;
900 PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
901
902 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
903 EnableIdleTasks();
904 SimulateMainThreadGestureWithoutPreventDefault();
905 RunUntilIdle();
906 EXPECT_THAT(run_order,
907 testing::ElementsAre(std::string("L1"), std::string("D1"),
908 std::string("D2"), std::string("I1"),
909 std::string("C1"), std::string("C2")));
910 EXPECT_EQ(RendererSchedulerImpl::UseCase::COMPOSITOR_GESTURE,
911 CurrentUseCase());
912 }
913
914 TEST_F(RendererSchedulerImplTest,
915 TestCompositorPolicy_CompositorHandlesInput_LongGestureDuration) {
916 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
917 EnableIdleTasks();
918 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
919
920 base::TimeTicks loop_end_time =
921 clock_->NowTicks() + base::TimeDelta::FromMilliseconds(
922 UserModel::kMedianGestureDurationMillis * 2);
923
924 // The UseCase::COMPOSITOR_GESTURE usecase initially deprioritizes compositor
925 // tasks (see TestCompositorPolicy_CompositorHandlesInput_WithTouchHandler)
926 // but if the gesture is long enough, compositor tasks get prioritized again.
927 while (clock_->NowTicks() < loop_end_time) {
928 scheduler_->DidHandleInputEventOnCompositorThread(
929 FakeInputEvent(blink::WebInputEvent::TouchMove),
930 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
931 clock_->Advance(base::TimeDelta::FromMilliseconds(16));
932 RunUntilIdle();
933 }
934
935 std::vector<std::string> run_order;
936 PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
937
938 RunUntilIdle();
939 EXPECT_THAT(run_order,
940 testing::ElementsAre(std::string("C1"), std::string("C2"),
941 std::string("L1"), std::string("D1"),
942 std::string("D2")));
943 EXPECT_EQ(RendererSchedulerImpl::UseCase::COMPOSITOR_GESTURE,
944 CurrentUseCase());
945 }
946
947 TEST_F(RendererSchedulerImplTest,
948 TestCompositorPolicy_CompositorHandlesInput_WithoutTouchHandler) {
949 std::vector<std::string> run_order;
950 PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
951
952 EnableIdleTasks();
953 SimulateCompositorGestureStart(TouchEventPolicy::DONT_SEND_TOUCH_START);
954 RunUntilIdle();
955 EXPECT_THAT(run_order,
956 testing::ElementsAre(std::string("L1"), std::string("D1"),
957 std::string("D2"), std::string("I1"),
958 std::string("C1"), std::string("C2")));
959 EXPECT_EQ(RendererSchedulerImpl::UseCase::COMPOSITOR_GESTURE,
960 CurrentUseCase());
961 }
962
963 TEST_F(RendererSchedulerImplTest,
964 TestCompositorPolicy_MainThreadHandlesInput_WithTouchHandler) {
965 std::vector<std::string> run_order;
966 PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
967
968 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
969 EnableIdleTasks();
970 SimulateMainThreadGestureStart(TouchEventPolicy::SEND_TOUCH_START,
971 blink::WebInputEvent::GestureScrollBegin);
972 RunUntilIdle();
973 EXPECT_THAT(run_order,
974 testing::ElementsAre(std::string("C1"), std::string("C2"),
975 std::string("L1"), std::string("D1"),
976 std::string("D2"), std::string("I1")));
977 EXPECT_EQ(RendererSchedulerImpl::UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
978 CurrentUseCase());
979 scheduler_->DidHandleInputEventOnMainThread(
980 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
981 }
982
983 TEST_F(RendererSchedulerImplTest,
984 TestCompositorPolicy_MainThreadHandlesInput_WithoutTouchHandler) {
985 std::vector<std::string> run_order;
986 PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
987
988 EnableIdleTasks();
989 SimulateMainThreadGestureStart(TouchEventPolicy::DONT_SEND_TOUCH_START,
990 blink::WebInputEvent::GestureScrollBegin);
991 RunUntilIdle();
992 EXPECT_THAT(run_order,
993 testing::ElementsAre(std::string("C1"), std::string("C2"),
994 std::string("L1"), std::string("D1"),
995 std::string("D2"), std::string("I1")));
996 EXPECT_EQ(RendererSchedulerImpl::UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
997 CurrentUseCase());
998 scheduler_->DidHandleInputEventOnMainThread(
999 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
1000 }
1001
1002 TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) {
1003 std::vector<std::string> run_order;
1004 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
1005
1006 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
1007 scheduler_->DidAnimateForInputOnCompositorThread();
1008 // Note DidAnimateForInputOnCompositorThread does not by itself trigger a
1009 // policy update.
1010 EXPECT_EQ(RendererSchedulerImpl::UseCase::COMPOSITOR_GESTURE,
1011 ForceUpdatePolicyAndGetCurrentUseCase());
1012 EnableIdleTasks();
1013 RunUntilIdle();
1014 EXPECT_THAT(run_order,
1015 testing::ElementsAre(std::string("D1"), std::string("D2"),
1016 std::string("I1"), std::string("C1"),
1017 std::string("C2")));
1018 EXPECT_EQ(RendererSchedulerImpl::UseCase::COMPOSITOR_GESTURE,
1019 CurrentUseCase());
1020 }
1021
1022 TEST_F(RendererSchedulerImplTest, Navigation_ResetsTaskCostEstimations) {
1023 std::vector<std::string> run_order;
1024
1025 SimulateExpensiveTasks(timer_task_runner_);
1026 scheduler_->OnNavigationStarted();
1027 PostTestTasks(&run_order, "C1 T1");
1028
1029 SimulateMainThreadGestureStart(TouchEventPolicy::DONT_SEND_TOUCH_START,
1030 blink::WebInputEvent::GestureScrollBegin);
1031 scheduler_->DidCommitFrameToCompositor(); // Starts Idle Period
1032 RunUntilIdle();
1033
1034 EXPECT_THAT(run_order,
1035 testing::ElementsAre(std::string("C1"), std::string("T1")));
1036 }
1037
1038 TEST_F(RendererSchedulerImplTest,
1039 ExpensiveTimersDontRunWhenMainThreadScrolling) {
1040 std::vector<std::string> run_order;
1041
1042 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
1043 SimulateExpensiveTasks(timer_task_runner_);
1044 DoMainFrame();
1045 SimulateMainThreadGestureStart(TouchEventPolicy::SEND_TOUCH_START,
1046 blink::WebInputEvent::GestureScrollUpdate);
1047
1048 PostTestTasks(&run_order, "C1 T1");
1049
1050 RunUntilIdle();
1051 EXPECT_FALSE(TouchStartExpectedSoon());
1052 EXPECT_EQ(RendererSchedulerImpl::UseCase::MAIN_THREAD_GESTURE,
1053 CurrentUseCase());
1054
1055 EXPECT_THAT(run_order, testing::ElementsAre(std::string("C1")));
1056 }
1057
1058 TEST_F(RendererSchedulerImplTest,
1059 ExpensiveTimersDoRunWhenMainThreadInputHandling) {
1060 std::vector<std::string> run_order;
1061
1062 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
1063 SimulateExpensiveTasks(timer_task_runner_);
1064 DoMainFrame();
1065 SimulateMainThreadGestureStart(TouchEventPolicy::SEND_TOUCH_START,
1066 blink::WebInputEvent::Undefined);
1067
1068 PostTestTasks(&run_order, "C1 T1");
1069
1070 RunUntilIdle();
1071 EXPECT_FALSE(TouchStartExpectedSoon());
1072 EXPECT_EQ(RendererSchedulerImpl::UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
1073 CurrentUseCase());
1074
1075 EXPECT_THAT(run_order,
1076 testing::ElementsAre(std::string("C1"), std::string("T1")));
1077 }
1078
1079 TEST_F(RendererSchedulerImplTest,
1080 ExpensiveTimersDoRunWhenMainThreadScrolling_AndOnCriticalPath) {
1081 std::vector<std::string> run_order;
1082
1083 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
1084 SimulateExpensiveTasks(timer_task_runner_);
1085 DoMainFrameOnCriticalPath();
1086 SimulateMainThreadGestureStart(TouchEventPolicy::SEND_TOUCH_START,
1087 blink::WebInputEvent::GestureScrollBegin);
1088
1089 PostTestTasks(&run_order, "C1 T1");
1090
1091 RunUntilIdle();
1092 EXPECT_FALSE(TouchStartExpectedSoon());
1093 EXPECT_EQ(RendererSchedulerImpl::UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
1094 CurrentUseCase());
1095
1096 EXPECT_THAT(run_order,
1097 testing::ElementsAre(std::string("C1"), std::string("T1")));
1098 }
1099
1100 TEST_F(RendererSchedulerImplTest, TestTouchstartPolicy_Compositor) {
1101 std::vector<std::string> run_order;
1102 PostTestTasks(&run_order, "L1 D1 C1 D2 C2 T1 T2");
1103
1104 // Observation of touchstart should defer execution of timer, idle and loading
1105 // tasks.
1106 scheduler_->DidHandleInputEventOnCompositorThread(
1107 FakeInputEvent(blink::WebInputEvent::TouchStart),
1108 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1109 EnableIdleTasks();
1110 RunUntilIdle();
1111 EXPECT_THAT(run_order,
1112 testing::ElementsAre(std::string("C1"), std::string("C2"),
1113 std::string("D1"), std::string("D2")));
1114
1115 // Animation or meta events like TapDown/FlingCancel shouldn't affect the
1116 // priority.
1117 run_order.clear();
1118 scheduler_->DidAnimateForInputOnCompositorThread();
1119 scheduler_->DidHandleInputEventOnCompositorThread(
1120 FakeInputEvent(blink::WebInputEvent::GestureFlingCancel),
1121 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1122 scheduler_->DidHandleInputEventOnCompositorThread(
1123 FakeInputEvent(blink::WebInputEvent::GestureTapDown),
1124 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1125 RunUntilIdle();
1126 EXPECT_TRUE(run_order.empty());
1127
1128 // Action events like ScrollBegin will kick us back into compositor priority,
1129 // allowing service of the timer, loading and idle queues.
1130 run_order.clear();
1131 scheduler_->DidHandleInputEventOnCompositorThread(
1132 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin),
1133 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1134 RunUntilIdle();
1135
1136 EXPECT_THAT(run_order,
1137 testing::ElementsAre(std::string("L1"), std::string("T1"),
1138 std::string("T2")));
1139 }
1140
1141 TEST_F(RendererSchedulerImplTest, TestTouchstartPolicy_MainThread) {
1142 std::vector<std::string> run_order;
1143 PostTestTasks(&run_order, "L1 D1 C1 D2 C2 T1 T2");
1144
1145 // Observation of touchstart should defer execution of timer, idle and loading
1146 // tasks.
1147 scheduler_->DidHandleInputEventOnCompositorThread(
1148 FakeInputEvent(blink::WebInputEvent::TouchStart),
1149 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1150 scheduler_->DidHandleInputEventOnMainThread(
1151 FakeInputEvent(blink::WebInputEvent::TouchStart));
1152 EnableIdleTasks();
1153 RunUntilIdle();
1154 EXPECT_THAT(run_order,
1155 testing::ElementsAre(std::string("C1"), std::string("C2"),
1156 std::string("D1"), std::string("D2")));
1157
1158 // Meta events like TapDown/FlingCancel shouldn't affect the priority.
1159 run_order.clear();
1160 scheduler_->DidHandleInputEventOnCompositorThread(
1161 FakeInputEvent(blink::WebInputEvent::GestureFlingCancel),
1162 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1163 scheduler_->DidHandleInputEventOnMainThread(
1164 FakeInputEvent(blink::WebInputEvent::GestureFlingCancel));
1165 scheduler_->DidHandleInputEventOnCompositorThread(
1166 FakeInputEvent(blink::WebInputEvent::GestureTapDown),
1167 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1168 scheduler_->DidHandleInputEventOnMainThread(
1169 FakeInputEvent(blink::WebInputEvent::GestureTapDown));
1170 RunUntilIdle();
1171 EXPECT_TRUE(run_order.empty());
1172
1173 // Action events like ScrollBegin will kick us back into compositor priority,
1174 // allowing service of the timer, loading and idle queues.
1175 run_order.clear();
1176 scheduler_->DidHandleInputEventOnCompositorThread(
1177 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin),
1178 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1179 scheduler_->DidHandleInputEventOnMainThread(
1180 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin));
1181 RunUntilIdle();
1182
1183 EXPECT_THAT(run_order,
1184 testing::ElementsAre(std::string("L1"), std::string("T1"),
1185 std::string("T2")));
1186 }
1187
1188 // TODO(alexclarke): Reenable once we've reinstaed the Loading UseCase.
1189 TEST_F(RendererSchedulerImplTest, DISABLED_LoadingUseCase) {
1190 std::vector<std::string> run_order;
1191 PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2");
1192
1193 scheduler_->OnNavigationStarted();
1194 EnableIdleTasks();
1195 RunUntilIdle();
1196
1197 // In loading policy, loading tasks are prioritized other others.
1198 std::string loading_policy_expected[] = {
1199 std::string("D1"), std::string("L1"), std::string("D2"),
1200 std::string("L2"), std::string("C1"), std::string("T1"),
1201 std::string("C2"), std::string("T2"), std::string("I1")};
1202 EXPECT_THAT(run_order, testing::ElementsAreArray(loading_policy_expected));
1203 EXPECT_EQ(RendererSchedulerImpl::UseCase::LOADING, CurrentUseCase());
1204
1205 // Advance 15s and try again, the loading policy should have ended and the
1206 // task order should return to the NONE use case where loading tasks are no
1207 // longer prioritized.
1208 clock_->Advance(base::TimeDelta::FromMilliseconds(150000));
1209 run_order.clear();
1210 PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2");
1211 EnableIdleTasks();
1212 RunUntilIdle();
1213
1214 std::string default_order_expected[] = {
1215 std::string("D1"), std::string("C1"), std::string("T1"),
1216 std::string("L1"), std::string("D2"), std::string("C2"),
1217 std::string("T2"), std::string("L2"), std::string("I1")};
1218 EXPECT_THAT(run_order, testing::ElementsAreArray(default_order_expected));
1219 EXPECT_EQ(RendererSchedulerImpl::UseCase::NONE, CurrentUseCase());
1220 }
1221
1222 TEST_F(RendererSchedulerImplTest,
1223 EventConsumedOnCompositorThread_IgnoresMouseMove_WhenMouseUp) {
1224 std::vector<std::string> run_order;
1225 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
1226
1227 EnableIdleTasks();
1228 scheduler_->DidHandleInputEventOnCompositorThread(
1229 FakeInputEvent(blink::WebInputEvent::MouseMove),
1230 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1231 RunUntilIdle();
1232 // Note compositor tasks are not prioritized.
1233 EXPECT_EQ(RendererSchedulerImpl::UseCase::NONE, CurrentUseCase());
1234 EXPECT_THAT(run_order,
1235 testing::ElementsAre(std::string("D1"), std::string("C1"),
1236 std::string("D2"), std::string("C2"),
1237 std::string("I1")));
1238 }
1239
1240 TEST_F(RendererSchedulerImplTest,
1241 EventForwardedToMainThread_IgnoresMouseMove_WhenMouseUp) {
1242 std::vector<std::string> run_order;
1243 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
1244
1245 EnableIdleTasks();
1246 scheduler_->DidHandleInputEventOnCompositorThread(
1247 FakeInputEvent(blink::WebInputEvent::MouseMove),
1248 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1249 RunUntilIdle();
1250 // Note compositor tasks are not prioritized.
1251 EXPECT_EQ(RendererSchedulerImpl::UseCase::NONE, CurrentUseCase());
1252 EXPECT_THAT(run_order,
1253 testing::ElementsAre(std::string("D1"), std::string("C1"),
1254 std::string("D2"), std::string("C2"),
1255 std::string("I1")));
1256 }
1257
1258 TEST_F(RendererSchedulerImplTest,
1259 EventConsumedOnCompositorThread_MouseMove_WhenMouseDown) {
1260 std::vector<std::string> run_order;
1261 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
1262
1263 EnableIdleTasks();
1264 scheduler_->DidHandleInputEventOnCompositorThread(
1265 FakeInputEvent(blink::WebInputEvent::MouseMove,
1266 blink::WebInputEvent::LeftButtonDown),
1267 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1268 RunUntilIdle();
1269 // Note compositor tasks are prioritized.
1270 EXPECT_THAT(run_order,
1271 testing::ElementsAre(std::string("C1"), std::string("C2"),
1272 std::string("D1"), std::string("D2"),
1273 std::string("I1")));
1274 }
1275
1276 TEST_F(RendererSchedulerImplTest,
1277 EventForwardedToMainThread_MouseMove_WhenMouseDown) {
1278 std::vector<std::string> run_order;
1279 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
1280
1281 EnableIdleTasks();
1282 scheduler_->DidHandleInputEventOnCompositorThread(
1283 FakeInputEvent(blink::WebInputEvent::MouseMove,
1284 blink::WebInputEvent::LeftButtonDown),
1285 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1286 RunUntilIdle();
1287 // Note compositor tasks are prioritized.
1288 EXPECT_THAT(run_order,
1289 testing::ElementsAre(std::string("C1"), std::string("C2"),
1290 std::string("D1"), std::string("D2"),
1291 std::string("I1")));
1292 scheduler_->DidHandleInputEventOnMainThread(FakeInputEvent(
1293 blink::WebInputEvent::MouseMove, blink::WebInputEvent::LeftButtonDown));
1294 }
1295
1296 TEST_F(RendererSchedulerImplTest, EventConsumedOnCompositorThread_MouseWheel) {
1297 std::vector<std::string> run_order;
1298 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
1299
1300 EnableIdleTasks();
1301 scheduler_->DidHandleInputEventOnCompositorThread(
1302 FakeInputEvent(blink::WebInputEvent::MouseWheel),
1303 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1304 RunUntilIdle();
1305 // Note compositor tasks are prioritized.
1306 EXPECT_THAT(run_order,
1307 testing::ElementsAre(std::string("C1"), std::string("C2"),
1308 std::string("D1"), std::string("D2"),
1309 std::string("I1")));
1310 }
1311
1312 TEST_F(RendererSchedulerImplTest, EventForwardedToMainThread_MouseWheel) {
1313 std::vector<std::string> run_order;
1314 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
1315
1316 EnableIdleTasks();
1317 scheduler_->DidHandleInputEventOnCompositorThread(
1318 FakeInputEvent(blink::WebInputEvent::MouseWheel),
1319 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1320 RunUntilIdle();
1321 // Note compositor tasks are prioritized.
1322 EXPECT_THAT(run_order,
1323 testing::ElementsAre(std::string("C1"), std::string("C2"),
1324 std::string("D1"), std::string("D2"),
1325 std::string("I1")));
1326 EXPECT_EQ(RendererSchedulerImpl::UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
1327 CurrentUseCase());
1328 }
1329
1330 TEST_F(RendererSchedulerImplTest,
1331 EventConsumedOnCompositorThread_IgnoresKeyboardEvents) {
1332 std::vector<std::string> run_order;
1333 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
1334
1335 EnableIdleTasks();
1336 scheduler_->DidHandleInputEventOnCompositorThread(
1337 FakeInputEvent(blink::WebInputEvent::KeyDown),
1338 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1339 RunUntilIdle();
1340 // Note compositor tasks are not prioritized.
1341 EXPECT_THAT(run_order,
1342 testing::ElementsAre(std::string("D1"), std::string("C1"),
1343 std::string("D2"), std::string("C2"),
1344 std::string("I1")));
1345 EXPECT_EQ(RendererSchedulerImpl::UseCase::NONE, CurrentUseCase());
1346 }
1347
1348 TEST_F(RendererSchedulerImplTest,
1349 EventForwardedToMainThread_IgnoresKeyboardEvents) {
1350 std::vector<std::string> run_order;
1351 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
1352
1353 EnableIdleTasks();
1354 scheduler_->DidHandleInputEventOnCompositorThread(
1355 FakeInputEvent(blink::WebInputEvent::KeyDown),
1356 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1357 RunUntilIdle();
1358 // Note compositor tasks are not prioritized.
1359 EXPECT_THAT(run_order,
1360 testing::ElementsAre(std::string("D1"), std::string("C1"),
1361 std::string("D2"), std::string("C2"),
1362 std::string("I1")));
1363 EXPECT_EQ(RendererSchedulerImpl::UseCase::NONE, CurrentUseCase());
1364 // Note compositor tasks are not prioritized.
1365 scheduler_->DidHandleInputEventOnMainThread(
1366 FakeInputEvent(blink::WebInputEvent::KeyDown));
1367 }
1368
1369 TEST_F(RendererSchedulerImplTest,
1370 TestMainthreadScrollingUseCaseDoesNotStarveDefaultTasks) {
1371 SimulateMainThreadGestureStart(TouchEventPolicy::DONT_SEND_TOUCH_START,
1372 blink::WebInputEvent::GestureScrollBegin);
1373 EnableIdleTasks();
1374
1375 std::vector<std::string> run_order;
1376 PostTestTasks(&run_order, "D1 C1");
1377
1378 for (int i = 0; i < 20; i++) {
1379 compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
1380 }
1381 PostTestTasks(&run_order, "C2");
1382
1383 scheduler_->DidHandleInputEventOnCompositorThread(
1384 FakeInputEvent(blink::WebInputEvent::GestureFlingStart),
1385 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1386 RunUntilIdle();
1387 // Ensure that the default D1 task gets to run at some point before the final
1388 // C2 compositor task.
1389 EXPECT_THAT(run_order,
1390 testing::ElementsAre(std::string("C1"), std::string("D1"),
1391 std::string("C2")));
1392 }
1393
1394 TEST_F(RendererSchedulerImplTest,
1395 TestCompositorPolicyEnds_CompositorHandlesInput) {
1396 SimulateCompositorGestureStart(TouchEventPolicy::DONT_SEND_TOUCH_START);
1397 EXPECT_EQ(UseCase::COMPOSITOR_GESTURE,
1398 ForceUpdatePolicyAndGetCurrentUseCase());
1399
1400 clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
1401 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
1402 }
1403
1404 TEST_F(RendererSchedulerImplTest,
1405 TestCompositorPolicyEnds_MainThreadHandlesInput) {
1406 SimulateMainThreadGestureStart(TouchEventPolicy::DONT_SEND_TOUCH_START,
1407 blink::WebInputEvent::GestureScrollBegin);
1408 EXPECT_EQ(UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
1409 ForceUpdatePolicyAndGetCurrentUseCase());
1410
1411 clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
1412 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
1413 }
1414
1415 TEST_F(RendererSchedulerImplTest, TestTouchstartPolicyEndsAfterTimeout) {
1416 std::vector<std::string> run_order;
1417 PostTestTasks(&run_order, "L1 D1 C1 D2 C2");
1418
1419 scheduler_->DidHandleInputEventOnCompositorThread(
1420 FakeInputEvent(blink::WebInputEvent::TouchStart),
1421 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1422 RunUntilIdle();
1423 EXPECT_THAT(run_order,
1424 testing::ElementsAre(std::string("C1"), std::string("C2"),
1425 std::string("D1"), std::string("D2")));
1426
1427 run_order.clear();
1428 clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
1429
1430 // Don't post any compositor tasks to simulate a very long running event
1431 // handler.
1432 PostTestTasks(&run_order, "D1 D2");
1433
1434 // Touchstart policy mode should have ended now that the clock has advanced.
1435 RunUntilIdle();
1436 EXPECT_THAT(run_order,
1437 testing::ElementsAre(std::string("L1"), std::string("D1"),
1438 std::string("D2")));
1439 }
1440
1441 TEST_F(RendererSchedulerImplTest,
1442 TestTouchstartPolicyEndsAfterConsecutiveTouchmoves) {
1443 std::vector<std::string> run_order;
1444 PostTestTasks(&run_order, "L1 D1 C1 D2 C2");
1445
1446 // Observation of touchstart should defer execution of idle and loading tasks.
1447 scheduler_->DidHandleInputEventOnCompositorThread(
1448 FakeInputEvent(blink::WebInputEvent::TouchStart),
1449 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1450 RunUntilIdle();
1451 EXPECT_THAT(run_order,
1452 testing::ElementsAre(std::string("C1"), std::string("C2"),
1453 std::string("D1"), std::string("D2")));
1454
1455 // Receiving the first touchmove will not affect scheduler priority.
1456 run_order.clear();
1457 scheduler_->DidHandleInputEventOnCompositorThread(
1458 FakeInputEvent(blink::WebInputEvent::TouchMove),
1459 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1460 RunUntilIdle();
1461 EXPECT_TRUE(run_order.empty());
1462
1463 // Receiving the second touchmove will kick us back into compositor priority.
1464 run_order.clear();
1465 scheduler_->DidHandleInputEventOnCompositorThread(
1466 FakeInputEvent(blink::WebInputEvent::TouchMove),
1467 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1468 RunUntilIdle();
1469 EXPECT_THAT(run_order, testing::ElementsAre(std::string("L1")));
1470 }
1471
1472 TEST_F(RendererSchedulerImplTest, TestIsHighPriorityWorkAnticipated) {
1473 bool is_anticipated_before = false;
1474 bool is_anticipated_after = false;
1475
1476 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
1477 default_task_runner_->PostTask(
1478 FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
1479 SimulateInputType::None, &is_anticipated_before,
1480 &is_anticipated_after));
1481 RunUntilIdle();
1482 // In its default state, without input receipt, the scheduler should indicate
1483 // that no high-priority is anticipated.
1484 EXPECT_FALSE(is_anticipated_before);
1485 EXPECT_FALSE(is_anticipated_after);
1486
1487 default_task_runner_->PostTask(
1488 FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
1489 SimulateInputType::TouchStart,
1490 &is_anticipated_before, &is_anticipated_after));
1491 bool dummy;
1492 default_task_runner_->PostTask(
1493 FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
1494 SimulateInputType::TouchEnd, &dummy, &dummy));
1495 default_task_runner_->PostTask(
1496 FROM_HERE,
1497 base::Bind(&AnticipationTestTask, scheduler_.get(),
1498 SimulateInputType::GestureScrollBegin, &dummy, &dummy));
1499 default_task_runner_->PostTask(
1500 FROM_HERE,
1501 base::Bind(&AnticipationTestTask, scheduler_.get(),
1502 SimulateInputType::GestureScrollEnd, &dummy, &dummy));
1503
1504 RunUntilIdle();
1505 // When input is received, the scheduler should indicate that high-priority
1506 // work is anticipated.
1507 EXPECT_FALSE(is_anticipated_before);
1508 EXPECT_TRUE(is_anticipated_after);
1509
1510 clock_->Advance(priority_escalation_after_input_duration() * 2);
1511 default_task_runner_->PostTask(
1512 FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
1513 SimulateInputType::None, &is_anticipated_before,
1514 &is_anticipated_after));
1515 RunUntilIdle();
1516 // Without additional input, the scheduler should go into NONE
1517 // use case but with scrolling expected where high-priority work is still
1518 // anticipated.
1519 EXPECT_EQ(UseCase::NONE, CurrentUseCase());
1520 EXPECT_TRUE(TouchStartExpectedSoon());
1521 EXPECT_TRUE(is_anticipated_before);
1522 EXPECT_TRUE(is_anticipated_after);
1523
1524 clock_->Advance(subsequent_input_expected_after_input_duration() * 2);
1525 default_task_runner_->PostTask(
1526 FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
1527 SimulateInputType::None, &is_anticipated_before,
1528 &is_anticipated_after));
1529 RunUntilIdle();
1530 // Eventually the scheduler should go into the default use case where
1531 // high-priority work is no longer anticipated.
1532 EXPECT_EQ(UseCase::NONE, CurrentUseCase());
1533 EXPECT_FALSE(TouchStartExpectedSoon());
1534 EXPECT_FALSE(is_anticipated_before);
1535 EXPECT_FALSE(is_anticipated_after);
1536 }
1537
1538 TEST_F(RendererSchedulerImplTest, TestShouldYield) {
1539 bool should_yield_before = false;
1540 bool should_yield_after = false;
1541
1542 default_task_runner_->PostTask(
1543 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
1544 base::RetainedRef(default_task_runner_), false,
1545 &should_yield_before, &should_yield_after));
1546 RunUntilIdle();
1547 // Posting to default runner shouldn't cause yielding.
1548 EXPECT_FALSE(should_yield_before);
1549 EXPECT_FALSE(should_yield_after);
1550
1551 default_task_runner_->PostTask(
1552 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
1553 base::RetainedRef(compositor_task_runner_), false,
1554 &should_yield_before, &should_yield_after));
1555 RunUntilIdle();
1556 // Posting while not mainthread scrolling shouldn't cause yielding.
1557 EXPECT_FALSE(should_yield_before);
1558 EXPECT_FALSE(should_yield_after);
1559
1560 default_task_runner_->PostTask(
1561 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
1562 base::RetainedRef(compositor_task_runner_), true,
1563 &should_yield_before, &should_yield_after));
1564 RunUntilIdle();
1565 // We should be able to switch to compositor priority mid-task.
1566 EXPECT_FALSE(should_yield_before);
1567 EXPECT_TRUE(should_yield_after);
1568 }
1569
1570 TEST_F(RendererSchedulerImplTest, TestShouldYield_TouchStart) {
1571 // Receiving a touchstart should immediately trigger yielding, even if
1572 // there's no immediately pending work in the compositor queue.
1573 EXPECT_FALSE(scheduler_->ShouldYieldForHighPriorityWork());
1574 scheduler_->DidHandleInputEventOnCompositorThread(
1575 FakeInputEvent(blink::WebInputEvent::TouchStart),
1576 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1577 EXPECT_TRUE(scheduler_->ShouldYieldForHighPriorityWork());
1578 RunUntilIdle();
1579 }
1580
1581 TEST_F(RendererSchedulerImplTest, SlowMainThreadInputEvent) {
1582 EXPECT_EQ(UseCase::NONE, CurrentUseCase());
1583
1584 // An input event should bump us into input priority.
1585 scheduler_->DidHandleInputEventOnCompositorThread(
1586 FakeInputEvent(blink::WebInputEvent::GestureFlingStart),
1587 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1588 RunUntilIdle();
1589 EXPECT_EQ(UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING, CurrentUseCase());
1590
1591 // Simulate the input event being queued for a very long time. The compositor
1592 // task we post here represents the enqueued input task.
1593 clock_->Advance(priority_escalation_after_input_duration() * 2);
1594 scheduler_->DidHandleInputEventOnMainThread(
1595 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
1596 RunUntilIdle();
1597
1598 // Even though we exceeded the input priority escalation period, we should
1599 // still be in main thread gesture since the input remains queued.
1600 EXPECT_EQ(UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING, CurrentUseCase());
1601
1602 // After the escalation period ends we should go back into normal mode.
1603 clock_->Advance(priority_escalation_after_input_duration() * 2);
1604 RunUntilIdle();
1605 EXPECT_EQ(UseCase::NONE, CurrentUseCase());
1606 }
1607
1608 class RendererSchedulerImplWithMockSchedulerTest
1609 : public RendererSchedulerImplTest {
1610 public:
1611 void SetUp() override {
1612 mock_task_runner_ = make_scoped_refptr(
1613 new cc::OrderedSimpleTaskRunner(clock_.get(), false));
1614 main_task_runner_ = SchedulerTqmDelegateForTest::Create(
1615 mock_task_runner_, base::WrapUnique(new TestTimeSource(clock_.get())));
1616 mock_scheduler_ = new RendererSchedulerImplForTest(main_task_runner_);
1617 Initialize(base::WrapUnique(mock_scheduler_));
1618 }
1619
1620 protected:
1621 RendererSchedulerImplForTest* mock_scheduler_;
1622 };
1623
1624 TEST_F(RendererSchedulerImplWithMockSchedulerTest,
1625 OnlyOnePendingUrgentPolicyUpdatey) {
1626 mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
1627 mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
1628 mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
1629 mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
1630
1631 RunUntilIdle();
1632
1633 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1634 }
1635
1636 TEST_F(RendererSchedulerImplWithMockSchedulerTest,
1637 OnePendingDelayedAndOneUrgentUpdatePolicy) {
1638 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1639
1640 mock_scheduler_->ScheduleDelayedPolicyUpdate(
1641 clock_->NowTicks(), base::TimeDelta::FromMilliseconds(1));
1642 mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
1643
1644 RunUntilIdle();
1645
1646 // We expect both the urgent and the delayed updates to run.
1647 EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
1648 }
1649
1650 TEST_F(RendererSchedulerImplWithMockSchedulerTest,
1651 OneUrgentAndOnePendingDelayedUpdatePolicy) {
1652 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1653
1654 mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
1655 mock_scheduler_->ScheduleDelayedPolicyUpdate(
1656 clock_->NowTicks(), base::TimeDelta::FromMilliseconds(1));
1657
1658 RunUntilIdle();
1659
1660 // We expect both the urgent and the delayed updates to run.
1661 EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
1662 }
1663
1664 TEST_F(RendererSchedulerImplWithMockSchedulerTest,
1665 UpdatePolicyCountTriggeredByOneInputEvent) {
1666 // We expect DidHandleInputEventOnCompositorThread to post an urgent policy
1667 // update.
1668 scheduler_->DidHandleInputEventOnCompositorThread(
1669 FakeInputEvent(blink::WebInputEvent::TouchStart),
1670 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1671 EXPECT_EQ(0, mock_scheduler_->update_policy_count_);
1672 mock_task_runner_->RunPendingTasks();
1673 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1674
1675 scheduler_->DidHandleInputEventOnMainThread(
1676 FakeInputEvent(blink::WebInputEvent::TouchStart));
1677 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1678
1679 clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
1680 RunUntilIdle();
1681
1682 // We finally expect a delayed policy update 100ms later.
1683 EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
1684 }
1685
1686 TEST_F(RendererSchedulerImplWithMockSchedulerTest,
1687 UpdatePolicyCountTriggeredByThreeInputEvents) {
1688 // We expect DidHandleInputEventOnCompositorThread to post an urgent policy
1689 // update.
1690 scheduler_->DidHandleInputEventOnCompositorThread(
1691 FakeInputEvent(blink::WebInputEvent::TouchStart),
1692 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1693 EXPECT_EQ(0, mock_scheduler_->update_policy_count_);
1694 mock_task_runner_->RunPendingTasks();
1695 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1696
1697 scheduler_->DidHandleInputEventOnMainThread(
1698 FakeInputEvent(blink::WebInputEvent::TouchStart));
1699 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1700
1701 // The second call to DidHandleInputEventOnCompositorThread should not post a
1702 // policy update because we are already in compositor priority.
1703 scheduler_->DidHandleInputEventOnCompositorThread(
1704 FakeInputEvent(blink::WebInputEvent::TouchMove),
1705 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1706 mock_task_runner_->RunPendingTasks();
1707 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1708
1709 // We expect DidHandleInputEvent to trigger a policy update.
1710 scheduler_->DidHandleInputEventOnMainThread(
1711 FakeInputEvent(blink::WebInputEvent::TouchMove));
1712 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1713
1714 // The third call to DidHandleInputEventOnCompositorThread should post a
1715 // policy update because the awaiting_touch_start_response_ flag changed.
1716 scheduler_->DidHandleInputEventOnCompositorThread(
1717 FakeInputEvent(blink::WebInputEvent::TouchMove),
1718 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1719 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1720 mock_task_runner_->RunPendingTasks();
1721 EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
1722
1723 // We expect DidHandleInputEvent to trigger a policy update.
1724 scheduler_->DidHandleInputEventOnMainThread(
1725 FakeInputEvent(blink::WebInputEvent::TouchMove));
1726 EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
1727
1728 clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
1729 RunUntilIdle();
1730
1731 // We finally expect a delayed policy update.
1732 EXPECT_EQ(3, mock_scheduler_->update_policy_count_);
1733 }
1734
1735 TEST_F(RendererSchedulerImplWithMockSchedulerTest,
1736 UpdatePolicyCountTriggeredByTwoInputEventsWithALongSeparatingDelay) {
1737 // We expect DidHandleInputEventOnCompositorThread to post an urgent policy
1738 // update.
1739 scheduler_->DidHandleInputEventOnCompositorThread(
1740 FakeInputEvent(blink::WebInputEvent::TouchStart),
1741 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1742 EXPECT_EQ(0, mock_scheduler_->update_policy_count_);
1743 mock_task_runner_->RunPendingTasks();
1744 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1745
1746 scheduler_->DidHandleInputEventOnMainThread(
1747 FakeInputEvent(blink::WebInputEvent::TouchStart));
1748 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1749
1750 clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
1751 RunUntilIdle();
1752 // We expect a delayed policy update.
1753 EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
1754
1755 // We expect the second call to DidHandleInputEventOnCompositorThread to post
1756 // an urgent policy update because we are no longer in compositor priority.
1757 scheduler_->DidHandleInputEventOnCompositorThread(
1758 FakeInputEvent(blink::WebInputEvent::TouchMove),
1759 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1760 EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
1761 mock_task_runner_->RunPendingTasks();
1762 EXPECT_EQ(3, mock_scheduler_->update_policy_count_);
1763
1764 scheduler_->DidHandleInputEventOnMainThread(
1765 FakeInputEvent(blink::WebInputEvent::TouchMove));
1766 EXPECT_EQ(3, mock_scheduler_->update_policy_count_);
1767
1768 clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
1769 RunUntilIdle();
1770
1771 // We finally expect a delayed policy update.
1772 EXPECT_EQ(4, mock_scheduler_->update_policy_count_);
1773 }
1774
1775 TEST_F(RendererSchedulerImplWithMockSchedulerTest,
1776 EnsureUpdatePolicyNotTriggeredTooOften) {
1777 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1778
1779 EXPECT_EQ(0, mock_scheduler_->update_policy_count_);
1780 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
1781 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1782
1783 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
1784
1785 // We expect the first call to IsHighPriorityWorkAnticipated to be called
1786 // after receiving an input event (but before the UpdateTask was processed) to
1787 // call UpdatePolicy.
1788 EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
1789 scheduler_->IsHighPriorityWorkAnticipated();
1790 EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
1791 // Subsequent calls should not call UpdatePolicy.
1792 scheduler_->IsHighPriorityWorkAnticipated();
1793 scheduler_->IsHighPriorityWorkAnticipated();
1794 scheduler_->IsHighPriorityWorkAnticipated();
1795 scheduler_->ShouldYieldForHighPriorityWork();
1796 scheduler_->ShouldYieldForHighPriorityWork();
1797 scheduler_->ShouldYieldForHighPriorityWork();
1798 scheduler_->ShouldYieldForHighPriorityWork();
1799
1800 scheduler_->DidHandleInputEventOnCompositorThread(
1801 FakeInputEvent(blink::WebInputEvent::GestureScrollEnd),
1802 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
1803 scheduler_->DidHandleInputEventOnCompositorThread(
1804 FakeInputEvent(blink::WebInputEvent::TouchEnd),
1805 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
1806
1807 scheduler_->DidHandleInputEventOnMainThread(
1808 FakeInputEvent(blink::WebInputEvent::TouchStart));
1809 scheduler_->DidHandleInputEventOnMainThread(
1810 FakeInputEvent(blink::WebInputEvent::TouchMove));
1811 scheduler_->DidHandleInputEventOnMainThread(
1812 FakeInputEvent(blink::WebInputEvent::TouchMove));
1813 scheduler_->DidHandleInputEventOnMainThread(
1814 FakeInputEvent(blink::WebInputEvent::TouchEnd));
1815
1816 EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
1817
1818 // We expect both the urgent and the delayed updates to run in addition to the
1819 // earlier updated cause by IsHighPriorityWorkAnticipated, a final update
1820 // transitions from 'not_scrolling touchstart expected' to 'not_scrolling'.
1821 RunUntilIdle();
1822 EXPECT_THAT(
1823 mock_scheduler_->use_cases_,
1824 testing::ElementsAre(
1825 std::string("none"), std::string("compositor_gesture"),
1826 std::string("compositor_gesture touchstart expected"),
1827 std::string("none touchstart expected"), std::string("none")));
1828 }
1829
1830 class RendererSchedulerImplWithMessageLoopTest
1831 : public RendererSchedulerImplTest {
1832 public:
1833 RendererSchedulerImplWithMessageLoopTest()
1834 : RendererSchedulerImplTest(new base::MessageLoop()) {}
1835 ~RendererSchedulerImplWithMessageLoopTest() override {}
1836
1837 void PostFromNestedRunloop(std::vector<
1838 std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>* tasks) {
1839 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_.get());
1840 for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) {
1841 if (pair.second) {
1842 idle_task_runner_->PostIdleTask(FROM_HERE, pair.first);
1843 } else {
1844 idle_task_runner_->PostNonNestableIdleTask(FROM_HERE, pair.first);
1845 }
1846 }
1847 EnableIdleTasks();
1848 base::RunLoop().RunUntilIdle();
1849 }
1850
1851 private:
1852 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplWithMessageLoopTest);
1853 };
1854
1855 TEST_F(RendererSchedulerImplWithMessageLoopTest,
1856 NonNestableIdleTaskDoesntExecuteInNestedLoop) {
1857 std::vector<std::string> order;
1858 idle_task_runner_->PostIdleTask(
1859 FROM_HERE,
1860 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("1")));
1861 idle_task_runner_->PostIdleTask(
1862 FROM_HERE,
1863 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("2")));
1864
1865 std::vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>
1866 tasks_to_post_from_nested_loop;
1867 tasks_to_post_from_nested_loop.push_back(std::make_pair(
1868 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("3")),
1869 false));
1870 tasks_to_post_from_nested_loop.push_back(std::make_pair(
1871 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("4")), true));
1872 tasks_to_post_from_nested_loop.push_back(std::make_pair(
1873 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("5")), true));
1874
1875 default_task_runner_->PostTask(
1876 FROM_HERE,
1877 base::Bind(
1878 &RendererSchedulerImplWithMessageLoopTest::PostFromNestedRunloop,
1879 base::Unretained(this),
1880 base::Unretained(&tasks_to_post_from_nested_loop)));
1881
1882 EnableIdleTasks();
1883 RunUntilIdle();
1884 // Note we expect task 3 to run last because it's non-nestable.
1885 EXPECT_THAT(order, testing::ElementsAre(std::string("1"), std::string("2"),
1886 std::string("4"), std::string("5"),
1887 std::string("3")));
1888 }
1889
1890 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriod) {
1891 base::TimeTicks expected_deadline =
1892 clock_->NowTicks() + maximum_idle_period_duration();
1893 base::TimeTicks deadline_in_task;
1894 int run_count = 0;
1895
1896 idle_task_runner_->PostIdleTask(
1897 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1898
1899 RunUntilIdle();
1900 EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period.
1901
1902 scheduler_->BeginFrameNotExpectedSoon();
1903 RunUntilIdle();
1904 EXPECT_EQ(1, run_count); // Should have run in a long idle time.
1905 EXPECT_EQ(expected_deadline, deadline_in_task);
1906 }
1907
1908 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) {
1909 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30);
1910 base::TimeTicks expected_deadline = clock_->NowTicks() + pending_task_delay;
1911 base::TimeTicks deadline_in_task;
1912 int run_count = 0;
1913
1914 idle_task_runner_->PostIdleTask(
1915 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1916 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
1917 pending_task_delay);
1918
1919 scheduler_->BeginFrameNotExpectedSoon();
1920 RunUntilIdle();
1921 EXPECT_EQ(1, run_count); // Should have run in a long idle time.
1922 EXPECT_EQ(expected_deadline, deadline_in_task);
1923 }
1924
1925 TEST_F(RendererSchedulerImplTest,
1926 TestLongIdlePeriodWithLatePendingDelayedTask) {
1927 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(10);
1928 base::TimeTicks deadline_in_task;
1929 int run_count = 0;
1930
1931 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
1932 pending_task_delay);
1933
1934 // Advance clock until after delayed task was meant to be run.
1935 clock_->Advance(base::TimeDelta::FromMilliseconds(20));
1936
1937 // Post an idle task and BeginFrameNotExpectedSoon to initiate a long idle
1938 // period. Since there is a late pending delayed task this shouldn't actually
1939 // start an idle period.
1940 idle_task_runner_->PostIdleTask(
1941 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1942 scheduler_->BeginFrameNotExpectedSoon();
1943 RunUntilIdle();
1944 EXPECT_EQ(0, run_count);
1945
1946 // After the delayed task has been run we should trigger an idle period.
1947 clock_->Advance(maximum_idle_period_duration());
1948 RunUntilIdle();
1949 EXPECT_EQ(1, run_count);
1950 }
1951
1952 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodRepeating) {
1953 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1954 std::vector<base::TimeTicks> actual_deadlines;
1955 int run_count = 0;
1956
1957 max_idle_task_reposts = 3;
1958 base::TimeTicks clock_before(clock_->NowTicks());
1959 base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
1960 idle_task_runner_->PostIdleTask(
1961 FROM_HERE,
1962 base::Bind(&RepostingUpdateClockIdleTestTask,
1963 base::RetainedRef(idle_task_runner_), &run_count, clock_.get(),
1964 idle_task_runtime, &actual_deadlines));
1965 scheduler_->BeginFrameNotExpectedSoon();
1966 RunUntilIdle();
1967 EXPECT_EQ(3, run_count);
1968 EXPECT_THAT(
1969 actual_deadlines,
1970 testing::ElementsAre(
1971 clock_before + maximum_idle_period_duration(),
1972 clock_before + idle_task_runtime + maximum_idle_period_duration(),
1973 clock_before + (2 * idle_task_runtime) +
1974 maximum_idle_period_duration()));
1975
1976 // Check that idle tasks don't run after the idle period ends with a
1977 // new BeginMainFrame.
1978 max_idle_task_reposts = 5;
1979 idle_task_runner_->PostIdleTask(
1980 FROM_HERE,
1981 base::Bind(&RepostingUpdateClockIdleTestTask,
1982 base::RetainedRef(idle_task_runner_), &run_count, clock_.get(),
1983 idle_task_runtime, &actual_deadlines));
1984 idle_task_runner_->PostIdleTask(
1985 FROM_HERE, base::Bind(&WillBeginFrameIdleTask,
1986 base::Unretained(scheduler_.get()), clock_.get()));
1987 RunUntilIdle();
1988 EXPECT_EQ(4, run_count);
1989 }
1990
1991 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodDoesNotWakeScheduler) {
1992 base::TimeTicks deadline_in_task;
1993 int run_count = 0;
1994
1995 // Start a long idle period and get the time it should end.
1996 scheduler_->BeginFrameNotExpectedSoon();
1997 // The scheduler should not run the initiate_next_long_idle_period task if
1998 // there are no idle tasks and no other task woke up the scheduler, thus
1999 // the idle period deadline shouldn't update at the end of the current long
2000 // idle period.
2001 base::TimeTicks idle_period_deadline =
2002 scheduler_->CurrentIdleTaskDeadlineForTesting();
2003 clock_->Advance(maximum_idle_period_duration());
2004 RunUntilIdle();
2005
2006 base::TimeTicks new_idle_period_deadline =
2007 scheduler_->CurrentIdleTaskDeadlineForTesting();
2008 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
2009
2010 // Posting a after-wakeup idle task also shouldn't wake the scheduler or
2011 // initiate the next long idle period.
2012 idle_task_runner_->PostIdleTaskAfterWakeup(
2013 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
2014 RunUntilIdle();
2015 new_idle_period_deadline = scheduler_->CurrentIdleTaskDeadlineForTesting();
2016 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
2017 EXPECT_EQ(0, run_count);
2018
2019 // Running a normal task should initiate a new long idle period though.
2020 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
2021 RunUntilIdle();
2022 new_idle_period_deadline = scheduler_->CurrentIdleTaskDeadlineForTesting();
2023 EXPECT_EQ(idle_period_deadline + maximum_idle_period_duration(),
2024 new_idle_period_deadline);
2025
2026 EXPECT_EQ(1, run_count);
2027 }
2028
2029 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) {
2030 base::TimeTicks deadline_in_task;
2031 int run_count = 0;
2032
2033 idle_task_runner_->PostIdleTask(
2034 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
2035
2036 // Observation of touchstart should defer the start of the long idle period.
2037 scheduler_->DidHandleInputEventOnCompositorThread(
2038 FakeInputEvent(blink::WebInputEvent::TouchStart),
2039 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
2040 scheduler_->BeginFrameNotExpectedSoon();
2041 RunUntilIdle();
2042 EXPECT_EQ(0, run_count);
2043
2044 // The long idle period should start after the touchstart policy has finished.
2045 clock_->Advance(priority_escalation_after_input_duration());
2046 RunUntilIdle();
2047 EXPECT_EQ(1, run_count);
2048 }
2049
2050 void TestCanExceedIdleDeadlineIfRequiredTask(RendererScheduler* scheduler,
2051 bool* can_exceed_idle_deadline_out,
2052 int* run_count,
2053 base::TimeTicks deadline) {
2054 *can_exceed_idle_deadline_out = scheduler->CanExceedIdleDeadlineIfRequired();
2055 (*run_count)++;
2056 }
2057
2058 TEST_F(RendererSchedulerImplTest, CanExceedIdleDeadlineIfRequired) {
2059 int run_count = 0;
2060 bool can_exceed_idle_deadline = false;
2061
2062 // Should return false if not in an idle period.
2063 EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired());
2064
2065 // Should return false for short idle periods.
2066 idle_task_runner_->PostIdleTask(
2067 FROM_HERE,
2068 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
2069 &can_exceed_idle_deadline, &run_count));
2070 EnableIdleTasks();
2071 RunUntilIdle();
2072 EXPECT_EQ(1, run_count);
2073 EXPECT_FALSE(can_exceed_idle_deadline);
2074
2075 // Should return false for a long idle period which is shortened due to a
2076 // pending delayed task.
2077 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
2078 base::TimeDelta::FromMilliseconds(10));
2079 idle_task_runner_->PostIdleTask(
2080 FROM_HERE,
2081 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
2082 &can_exceed_idle_deadline, &run_count));
2083 scheduler_->BeginFrameNotExpectedSoon();
2084 RunUntilIdle();
2085 EXPECT_EQ(2, run_count);
2086 EXPECT_FALSE(can_exceed_idle_deadline);
2087
2088 // Next long idle period will be for the maximum time, so
2089 // CanExceedIdleDeadlineIfRequired should return true.
2090 clock_->Advance(maximum_idle_period_duration());
2091 idle_task_runner_->PostIdleTask(
2092 FROM_HERE,
2093 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
2094 &can_exceed_idle_deadline, &run_count));
2095 RunUntilIdle();
2096 EXPECT_EQ(3, run_count);
2097 EXPECT_TRUE(can_exceed_idle_deadline);
2098
2099 // Next long idle period will be for the maximum time, so
2100 // CanExceedIdleDeadlineIfRequired should return true.
2101 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
2102 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
2103 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
2104 EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired());
2105 }
2106
2107 TEST_F(RendererSchedulerImplTest, TestRendererHiddenIdlePeriod) {
2108 int run_count = 0;
2109
2110 max_idle_task_reposts = 2;
2111 idle_task_runner_->PostIdleTask(
2112 FROM_HERE, base::Bind(&RepostingIdleTestTask,
2113 base::RetainedRef(idle_task_runner_), &run_count));
2114
2115 // Renderer should start in visible state.
2116 RunUntilIdle();
2117 EXPECT_EQ(0, run_count);
2118
2119 // When we hide the renderer it should start a max deadline idle period, which
2120 // will run an idle task and then immediately start a new idle period, which
2121 // runs the second idle task.
2122 scheduler_->SetAllRenderWidgetsHidden(true);
2123 RunUntilIdle();
2124 EXPECT_EQ(2, run_count);
2125
2126 // Advance time by amount of time by the maximum amount of time we execute
2127 // idle tasks when hidden (plus some slack) - idle period should have ended.
2128 max_idle_task_reposts = 3;
2129 idle_task_runner_->PostIdleTask(
2130 FROM_HERE, base::Bind(&RepostingIdleTestTask,
2131 base::RetainedRef(idle_task_runner_), &run_count));
2132 clock_->Advance(end_idle_when_hidden_delay() +
2133 base::TimeDelta::FromMilliseconds(10));
2134 RunUntilIdle();
2135 EXPECT_EQ(2, run_count);
2136 }
2137
2138 TEST_F(RendererSchedulerImplTest, TimerQueueEnabledByDefault) {
2139 std::vector<std::string> run_order;
2140 PostTestTasks(&run_order, "T1 T2");
2141 RunUntilIdle();
2142 EXPECT_THAT(run_order,
2143 testing::ElementsAre(std::string("T1"), std::string("T2")));
2144 }
2145
2146 TEST_F(RendererSchedulerImplTest, SuspendAndResumeTimerQueue) {
2147 std::vector<std::string> run_order;
2148 PostTestTasks(&run_order, "T1 T2");
2149
2150 scheduler_->SuspendTimerQueue();
2151 RunUntilIdle();
2152 EXPECT_TRUE(run_order.empty());
2153
2154 scheduler_->ResumeTimerQueue();
2155 RunUntilIdle();
2156 EXPECT_THAT(run_order,
2157 testing::ElementsAre(std::string("T1"), std::string("T2")));
2158 }
2159
2160 TEST_F(RendererSchedulerImplTest, SuspendAndThrottleTimerQueue) {
2161 std::vector<std::string> run_order;
2162 PostTestTasks(&run_order, "T1 T2");
2163
2164 scheduler_->SuspendTimerQueue();
2165 RunUntilIdle();
2166 scheduler_->throttling_helper()->IncreaseThrottleRefCount(
2167 static_cast<TaskQueue*>(timer_task_runner_.get()));
2168 RunUntilIdle();
2169 EXPECT_TRUE(run_order.empty());
2170 }
2171
2172 TEST_F(RendererSchedulerImplTest, ThrottleAndSuspendTimerQueue) {
2173 std::vector<std::string> run_order;
2174 PostTestTasks(&run_order, "T1 T2");
2175
2176 scheduler_->throttling_helper()->IncreaseThrottleRefCount(
2177 static_cast<TaskQueue*>(timer_task_runner_.get()));
2178 RunUntilIdle();
2179 scheduler_->SuspendTimerQueue();
2180 RunUntilIdle();
2181 EXPECT_TRUE(run_order.empty());
2182 }
2183
2184 TEST_F(RendererSchedulerImplTest, MultipleSuspendsNeedMultipleResumes) {
2185 std::vector<std::string> run_order;
2186 PostTestTasks(&run_order, "T1 T2");
2187
2188 scheduler_->SuspendTimerQueue();
2189 scheduler_->SuspendTimerQueue();
2190 scheduler_->SuspendTimerQueue();
2191 RunUntilIdle();
2192 EXPECT_TRUE(run_order.empty());
2193
2194 scheduler_->ResumeTimerQueue();
2195 RunUntilIdle();
2196 EXPECT_TRUE(run_order.empty());
2197
2198 scheduler_->ResumeTimerQueue();
2199 RunUntilIdle();
2200 EXPECT_TRUE(run_order.empty());
2201
2202 scheduler_->ResumeTimerQueue();
2203 RunUntilIdle();
2204 EXPECT_THAT(run_order,
2205 testing::ElementsAre(std::string("T1"), std::string("T2")));
2206 }
2207
2208 TEST_F(RendererSchedulerImplTest, SuspendRenderer) {
2209 // Assume that the renderer is backgrounded.
2210 scheduler_->OnRendererBackgrounded();
2211
2212 // Tasks in some queues don't fire when the renderer is suspended.
2213 std::vector<std::string> run_order;
2214 PostTestTasks(&run_order, "D1 C1 L1 I1 T1");
2215 scheduler_->SuspendRenderer();
2216 EnableIdleTasks();
2217 RunUntilIdle();
2218 EXPECT_THAT(run_order,
2219 testing::ElementsAre(std::string("D1"), std::string("C1"),
2220 std::string("I1")));
2221
2222 // The rest queued tasks fire when the tab goes foregrounded.
2223 run_order.clear();
2224 scheduler_->OnRendererForegrounded();
2225 RunUntilIdle();
2226 EXPECT_THAT(run_order,
2227 testing::ElementsAre(std::string("L1"), std::string("T1")));
2228 }
2229
2230 TEST_F(RendererSchedulerImplTest, UseCaseToString) {
2231 CheckAllUseCaseToString();
2232 }
2233
2234 TEST_F(RendererSchedulerImplTest, MismatchedDidHandleInputEventOnMainThread) {
2235 // This should not DCHECK because there was no corresponding compositor side
2236 // call to DidHandleInputEventOnCompositorThread with
2237 // INPUT_EVENT_ACK_STATE_NOT_CONSUMED. There are legitimate reasons for the
2238 // compositor to not be there and we don't want to make debugging impossible.
2239 scheduler_->DidHandleInputEventOnMainThread(
2240 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
2241 }
2242
2243 TEST_F(RendererSchedulerImplTest, BeginMainFrameOnCriticalPath) {
2244 ASSERT_FALSE(scheduler_->BeginMainFrameOnCriticalPath());
2245
2246 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
2247 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
2248 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL);
2249 scheduler_->WillBeginFrame(begin_frame_args);
2250 ASSERT_TRUE(scheduler_->BeginMainFrameOnCriticalPath());
2251
2252 begin_frame_args.on_critical_path = false;
2253 scheduler_->WillBeginFrame(begin_frame_args);
2254 ASSERT_FALSE(scheduler_->BeginMainFrameOnCriticalPath());
2255 }
2256
2257 TEST_F(RendererSchedulerImplTest, ShutdownPreventsPostingOfNewTasks) {
2258 scheduler_->Shutdown();
2259 std::vector<std::string> run_order;
2260 PostTestTasks(&run_order, "D1 C1");
2261 RunUntilIdle();
2262 EXPECT_TRUE(run_order.empty());
2263 }
2264
2265 TEST_F(RendererSchedulerImplTest, TestRendererBackgroundedTimerSuspension) {
2266 scheduler_->SetTimerQueueSuspensionWhenBackgroundedEnabled(true);
2267
2268 std::vector<std::string> run_order;
2269 PostTestTasks(&run_order, "T1 T2");
2270
2271 // The background signal will not immediately suspend the timer queue.
2272 scheduler_->OnRendererBackgrounded();
2273 RunUntilIdle();
2274 EXPECT_THAT(run_order,
2275 testing::ElementsAre(std::string("T1"), std::string("T2")));
2276
2277 run_order.clear();
2278 PostTestTasks(&run_order, "T3");
2279 RunUntilIdle();
2280 EXPECT_THAT(run_order, testing::ElementsAre(std::string("T3")));
2281
2282 // Advance the time until after the scheduled timer queue suspension.
2283 run_order.clear();
2284 clock_->Advance(suspend_timers_when_backgrounded_delay() +
2285 base::TimeDelta::FromMilliseconds(10));
2286 RunUntilIdle();
2287 ASSERT_TRUE(run_order.empty());
2288
2289 // Timer tasks should be suspended until the foregrounded signal.
2290 PostTestTasks(&run_order, "T4 T5");
2291 RunUntilIdle();
2292 EXPECT_TRUE(run_order.empty());
2293
2294 scheduler_->OnRendererForegrounded();
2295 RunUntilIdle();
2296 EXPECT_THAT(run_order,
2297 testing::ElementsAre(std::string("T4"), std::string("T5")));
2298
2299 // Subsequent timer tasks should fire as usual.
2300 run_order.clear();
2301 PostTestTasks(&run_order, "T6");
2302 RunUntilIdle();
2303 EXPECT_THAT(run_order, testing::ElementsAre(std::string("T6")));
2304 }
2305
2306 TEST_F(RendererSchedulerImplTest,
2307 ExpensiveLoadingTasksNotBlockedTillFirstBeginMainFrame) {
2308 std::vector<std::string> run_order;
2309
2310 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2311 SimulateExpensiveTasks(loading_task_runner_);
2312 ForceTouchStartToBeExpectedSoon();
2313 PostTestTasks(&run_order, "L1 D1");
2314 RunUntilIdle();
2315
2316 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
2317 EXPECT_FALSE(HaveSeenABeginMainframe());
2318 EXPECT_TRUE(LoadingTasksSeemExpensive());
2319 EXPECT_FALSE(TimerTasksSeemExpensive());
2320 EXPECT_TRUE(TouchStartExpectedSoon());
2321 EXPECT_THAT(run_order,
2322 testing::ElementsAre(std::string("L1"), std::string("D1")));
2323
2324 // Emit a BeginMainFrame, and the loading task should get blocked.
2325 DoMainFrame();
2326 run_order.clear();
2327
2328 PostTestTasks(&run_order, "L1 D1");
2329 RunUntilIdle();
2330
2331 EXPECT_EQ(RendererSchedulerImpl::UseCase::NONE, CurrentUseCase());
2332 EXPECT_TRUE(HaveSeenABeginMainframe());
2333 EXPECT_TRUE(LoadingTasksSeemExpensive());
2334 EXPECT_FALSE(TimerTasksSeemExpensive());
2335 EXPECT_TRUE(TouchStartExpectedSoon());
2336 EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
2337 EXPECT_EQ(v8::PERFORMANCE_RESPONSE, RAILMode());
2338 }
2339
2340 TEST_F(RendererSchedulerImplTest,
2341 ExpensiveLoadingTasksNotBlockedIfNoTouchHandler) {
2342 std::vector<std::string> run_order;
2343
2344 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(false);
2345 DoMainFrame();
2346 SimulateExpensiveTasks(loading_task_runner_);
2347 ForceTouchStartToBeExpectedSoon();
2348 PostTestTasks(&run_order, "L1 D1");
2349 RunUntilIdle();
2350
2351 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
2352 EXPECT_TRUE(HaveSeenABeginMainframe());
2353 EXPECT_TRUE(LoadingTasksSeemExpensive());
2354 EXPECT_FALSE(TimerTasksSeemExpensive());
2355 EXPECT_FALSE(TouchStartExpectedSoon());
2356 EXPECT_THAT(run_order,
2357 testing::ElementsAre(std::string("L1"), std::string("D1")));
2358 EXPECT_EQ(v8::PERFORMANCE_ANIMATION, RAILMode());
2359 }
2360
2361 TEST_F(RendererSchedulerImplTest,
2362 ExpensiveTimerTaskBlocked_UseCase_NONE_PreviousCompositorGesture) {
2363 std::vector<std::string> run_order;
2364
2365 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2366 DoMainFrame();
2367 SimulateExpensiveTasks(timer_task_runner_);
2368 ForceTouchStartToBeExpectedSoon();
2369
2370 PostTestTasks(&run_order, "T1 D1");
2371 RunUntilIdle();
2372
2373 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
2374 EXPECT_TRUE(HaveSeenABeginMainframe());
2375 EXPECT_FALSE(LoadingTasksSeemExpensive());
2376 EXPECT_TRUE(TimerTasksSeemExpensive());
2377 EXPECT_TRUE(TouchStartExpectedSoon());
2378 EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
2379 EXPECT_EQ(v8::PERFORMANCE_RESPONSE, RAILMode());
2380 }
2381
2382 TEST_F(RendererSchedulerImplTest,
2383 ExpensiveTimerTaskNotBlocked_UseCase_NONE_PreviousMainThreadGesture) {
2384 std::vector<std::string> run_order;
2385
2386 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2387 DoMainFrame();
2388 SimulateExpensiveTasks(timer_task_runner_);
2389
2390 SimulateMainThreadGestureStart(TouchEventPolicy::SEND_TOUCH_START,
2391 blink::WebInputEvent::GestureScrollBegin);
2392 EXPECT_EQ(UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
2393 ForceUpdatePolicyAndGetCurrentUseCase());
2394
2395 scheduler_->DidHandleInputEventOnCompositorThread(
2396 FakeInputEvent(blink::WebInputEvent::TouchEnd),
2397 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
2398 scheduler_->DidHandleInputEventOnMainThread(
2399 FakeInputEvent(blink::WebInputEvent::TouchEnd));
2400
2401 clock_->Advance(priority_escalation_after_input_duration() * 2);
2402 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
2403
2404 PostTestTasks(&run_order, "T1 D1");
2405 RunUntilIdle();
2406
2407 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
2408 EXPECT_TRUE(HaveSeenABeginMainframe());
2409 EXPECT_FALSE(LoadingTasksSeemExpensive());
2410 EXPECT_TRUE(TimerTasksSeemExpensive());
2411 EXPECT_TRUE(TouchStartExpectedSoon());
2412 EXPECT_THAT(run_order,
2413 testing::ElementsAre(std::string("T1"), std::string("D1")));
2414 EXPECT_EQ(v8::PERFORMANCE_ANIMATION, RAILMode());
2415 }
2416
2417 TEST_F(RendererSchedulerImplTest,
2418 ExpensiveTimerTaskBlocked_UseCase_COMPOSITOR_GESTURE) {
2419 std::vector<std::string> run_order;
2420
2421 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2422 DoMainFrame();
2423 SimulateExpensiveTasks(timer_task_runner_);
2424 ForceTouchStartToBeExpectedSoon();
2425 scheduler_->DidAnimateForInputOnCompositorThread();
2426
2427 PostTestTasks(&run_order, "T1 D1");
2428 RunUntilIdle();
2429
2430 EXPECT_EQ(UseCase::COMPOSITOR_GESTURE,
2431 ForceUpdatePolicyAndGetCurrentUseCase());
2432 EXPECT_TRUE(HaveSeenABeginMainframe());
2433 EXPECT_FALSE(LoadingTasksSeemExpensive());
2434 EXPECT_TRUE(TimerTasksSeemExpensive());
2435 EXPECT_TRUE(TouchStartExpectedSoon());
2436 EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
2437 EXPECT_EQ(v8::PERFORMANCE_RESPONSE, RAILMode());
2438 }
2439
2440 TEST_F(RendererSchedulerImplTest,
2441 ExpensiveTimerTaskNotBlockedIfDisallowed_UseCase_COMPOSITOR_GESTURE) {
2442 std::vector<std::string> run_order;
2443
2444 scheduler_->SetExpensiveTaskBlockingAllowed(false);
2445 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2446 DoMainFrame();
2447 SimulateExpensiveTasks(timer_task_runner_);
2448 ForceTouchStartToBeExpectedSoon();
2449 scheduler_->DidAnimateForInputOnCompositorThread();
2450
2451 PostTestTasks(&run_order, "T1 D1");
2452 RunUntilIdle();
2453
2454 EXPECT_EQ(UseCase::COMPOSITOR_GESTURE,
2455 ForceUpdatePolicyAndGetCurrentUseCase());
2456 EXPECT_TRUE(HaveSeenABeginMainframe());
2457 EXPECT_FALSE(LoadingTasksSeemExpensive());
2458 EXPECT_TRUE(TimerTasksSeemExpensive());
2459 EXPECT_TRUE(TouchStartExpectedSoon());
2460 EXPECT_THAT(run_order, testing::ElementsAre(std::string("T1"),
2461 std::string("D1")));
2462 EXPECT_EQ(v8::PERFORMANCE_RESPONSE, RAILMode());
2463 }
2464
2465 TEST_F(RendererSchedulerImplTest,
2466 ExpensiveTimerTaskBlocked_EvenIfBeginMainFrameNotExpectedSoon) {
2467 std::vector<std::string> run_order;
2468
2469 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2470 DoMainFrame();
2471 SimulateExpensiveTasks(timer_task_runner_);
2472 ForceTouchStartToBeExpectedSoon();
2473 scheduler_->BeginFrameNotExpectedSoon();
2474
2475 PostTestTasks(&run_order, "T1 D1");
2476 RunUntilIdle();
2477
2478 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
2479 EXPECT_TRUE(HaveSeenABeginMainframe());
2480 EXPECT_FALSE(LoadingTasksSeemExpensive());
2481 EXPECT_TRUE(TimerTasksSeemExpensive());
2482 EXPECT_TRUE(TouchStartExpectedSoon());
2483 EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
2484 EXPECT_EQ(v8::PERFORMANCE_RESPONSE, RAILMode());
2485 }
2486
2487 TEST_F(RendererSchedulerImplTest,
2488 ExpensiveLoadingTasksBlockedIfChildFrameNavigationExpected) {
2489 std::vector<std::string> run_order;
2490
2491 DoMainFrame();
2492 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2493 SimulateExpensiveTasks(loading_task_runner_);
2494 ForceTouchStartToBeExpectedSoon();
2495 scheduler_->AddPendingNavigation(
2496 blink::WebScheduler::NavigatingFrameType::kChildFrame);
2497
2498 PostTestTasks(&run_order, "L1 D1");
2499 RunUntilIdle();
2500
2501 // The expensive loading task gets blocked.
2502 EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
2503 EXPECT_EQ(v8::PERFORMANCE_RESPONSE, RAILMode());
2504 }
2505
2506 TEST_F(RendererSchedulerImplTest,
2507 ExpensiveLoadingTasksNotBlockedIfMainFrameNavigationExpected) {
2508 std::vector<std::string> run_order;
2509
2510 DoMainFrame();
2511 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2512 SimulateExpensiveTasks(loading_task_runner_);
2513 ForceTouchStartToBeExpectedSoon();
2514 scheduler_->AddPendingNavigation(
2515 blink::WebScheduler::NavigatingFrameType::kMainFrame);
2516
2517 PostTestTasks(&run_order, "L1 D1");
2518 RunUntilIdle();
2519
2520 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
2521 EXPECT_TRUE(HaveSeenABeginMainframe());
2522 EXPECT_TRUE(LoadingTasksSeemExpensive());
2523 EXPECT_FALSE(TimerTasksSeemExpensive());
2524 EXPECT_TRUE(TouchStartExpectedSoon());
2525 EXPECT_EQ(1, NavigationTaskExpectedCount());
2526 EXPECT_THAT(run_order,
2527 testing::ElementsAre(std::string("L1"), std::string("D1")));
2528
2529 // After the nagigation has been cancelled, the expensive loading tasks should
2530 // get blocked.
2531 scheduler_->RemovePendingNavigation(
2532 blink::WebScheduler::NavigatingFrameType::kMainFrame);
2533 run_order.clear();
2534
2535 PostTestTasks(&run_order, "L1 D1");
2536 RunUntilIdle();
2537
2538 EXPECT_EQ(RendererSchedulerImpl::UseCase::NONE, CurrentUseCase());
2539 EXPECT_TRUE(HaveSeenABeginMainframe());
2540 EXPECT_TRUE(LoadingTasksSeemExpensive());
2541 EXPECT_FALSE(TimerTasksSeemExpensive());
2542 EXPECT_TRUE(TouchStartExpectedSoon());
2543 EXPECT_EQ(0, NavigationTaskExpectedCount());
2544 EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
2545 EXPECT_EQ(v8::PERFORMANCE_RESPONSE, RAILMode());
2546 }
2547
2548 TEST_F(
2549 RendererSchedulerImplTest,
2550 ExpensiveLoadingTasksNotBlockedIfMainFrameNavigationExpected_Multiple) {
2551 std::vector<std::string> run_order;
2552
2553 DoMainFrame();
2554 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2555 SimulateExpensiveTasks(loading_task_runner_);
2556 ForceTouchStartToBeExpectedSoon();
2557 scheduler_->AddPendingNavigation(
2558 blink::WebScheduler::NavigatingFrameType::kMainFrame);
2559 scheduler_->AddPendingNavigation(
2560 blink::WebScheduler::NavigatingFrameType::kMainFrame);
2561
2562 PostTestTasks(&run_order, "L1 D1");
2563 RunUntilIdle();
2564
2565 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
2566 EXPECT_TRUE(HaveSeenABeginMainframe());
2567 EXPECT_TRUE(LoadingTasksSeemExpensive());
2568 EXPECT_FALSE(TimerTasksSeemExpensive());
2569 EXPECT_TRUE(TouchStartExpectedSoon());
2570 EXPECT_EQ(2, NavigationTaskExpectedCount());
2571 EXPECT_THAT(run_order,
2572 testing::ElementsAre(std::string("L1"), std::string("D1")));
2573
2574
2575 run_order.clear();
2576 scheduler_->RemovePendingNavigation(
2577 blink::WebScheduler::NavigatingFrameType::kMainFrame);
2578 // Navigation task expected ref count non-zero so expensive tasks still not
2579 // blocked.
2580 PostTestTasks(&run_order, "L1 D1");
2581 RunUntilIdle();
2582
2583 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
2584 EXPECT_TRUE(HaveSeenABeginMainframe());
2585 EXPECT_TRUE(LoadingTasksSeemExpensive());
2586 EXPECT_FALSE(TimerTasksSeemExpensive());
2587 EXPECT_TRUE(TouchStartExpectedSoon());
2588 EXPECT_EQ(1, NavigationTaskExpectedCount());
2589 EXPECT_THAT(run_order,
2590 testing::ElementsAre(std::string("L1"), std::string("D1")));
2591
2592
2593 run_order.clear();
2594 scheduler_->RemovePendingNavigation(
2595 blink::WebScheduler::NavigatingFrameType::kMainFrame);
2596 // Navigation task expected ref count is now zero, the expensive loading tasks
2597 // should get blocked.
2598 PostTestTasks(&run_order, "L1 D1");
2599 RunUntilIdle();
2600
2601 EXPECT_EQ(RendererSchedulerImpl::UseCase::NONE, CurrentUseCase());
2602 EXPECT_TRUE(HaveSeenABeginMainframe());
2603 EXPECT_TRUE(LoadingTasksSeemExpensive());
2604 EXPECT_FALSE(TimerTasksSeemExpensive());
2605 EXPECT_TRUE(TouchStartExpectedSoon());
2606 EXPECT_EQ(0, NavigationTaskExpectedCount());
2607 EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
2608 EXPECT_EQ(v8::PERFORMANCE_RESPONSE, RAILMode());
2609 }
2610
2611 TEST_F(RendererSchedulerImplTest,
2612 ExpensiveLoadingTasksNotBlockedDuringMainThreadGestures) {
2613 std::vector<std::string> run_order;
2614
2615 SimulateExpensiveTasks(loading_task_runner_);
2616
2617 // Loading tasks should not be disabled during main thread user interactions.
2618 PostTestTasks(&run_order, "C1 L1");
2619
2620 // Trigger main_thread_gesture UseCase
2621 SimulateMainThreadGestureStart(TouchEventPolicy::SEND_TOUCH_START,
2622 blink::WebInputEvent::GestureScrollBegin);
2623 RunUntilIdle();
2624 EXPECT_EQ(RendererSchedulerImpl::UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
2625 CurrentUseCase());
2626
2627 EXPECT_TRUE(LoadingTasksSeemExpensive());
2628 EXPECT_FALSE(TimerTasksSeemExpensive());
2629 EXPECT_THAT(run_order,
2630 testing::ElementsAre(std::string("C1"), std::string("L1")));
2631 EXPECT_EQ(v8::PERFORMANCE_ANIMATION, RAILMode());
2632 }
2633
2634 TEST_F(RendererSchedulerImplTest, ModeratelyExpensiveTimer_NotBlocked) {
2635 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2636 SimulateMainThreadGestureStart(TouchEventPolicy::SEND_TOUCH_START,
2637 blink::WebInputEvent::TouchMove);
2638 RunUntilIdle();
2639 for (int i = 0; i < 20; i++) {
2640 simulate_timer_task_ran_ = false;
2641
2642 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
2643 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
2644 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
2645 begin_frame_args.on_critical_path = false;
2646 scheduler_->WillBeginFrame(begin_frame_args);
2647
2648 compositor_task_runner_->PostTask(
2649 FROM_HERE, base::Bind(&RendererSchedulerImplTest::
2650 SimulateMainThreadInputHandlingCompositorTask,
2651 base::Unretained(this),
2652 base::TimeDelta::FromMilliseconds(8)));
2653 timer_task_runner_->PostTask(
2654 FROM_HERE, base::Bind(&RendererSchedulerImplTest::SimulateTimerTask,
2655 base::Unretained(this),
2656 base::TimeDelta::FromMilliseconds(4)));
2657
2658 RunUntilIdle();
2659 EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i;
2660 EXPECT_EQ(RendererSchedulerImpl::UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
2661 CurrentUseCase())
2662 << " i = " << i;
2663 EXPECT_FALSE(LoadingTasksSeemExpensive()) << " i = " << i;
2664 EXPECT_FALSE(TimerTasksSeemExpensive()) << " i = " << i;
2665
2666 base::TimeDelta time_till_next_frame =
2667 EstimatedNextFrameBegin() - clock_->NowTicks();
2668 if (time_till_next_frame > base::TimeDelta())
2669 clock_->Advance(time_till_next_frame);
2670 }
2671 }
2672
2673 TEST_F(RendererSchedulerImplTest,
2674 FourtyMsTimer_NotBlocked_CompositorScrolling) {
2675 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2676 RunUntilIdle();
2677 for (int i = 0; i < 20; i++) {
2678 simulate_timer_task_ran_ = false;
2679
2680 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
2681 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
2682 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
2683 begin_frame_args.on_critical_path = false;
2684 scheduler_->WillBeginFrame(begin_frame_args);
2685 scheduler_->DidAnimateForInputOnCompositorThread();
2686
2687 compositor_task_runner_->PostTask(
2688 FROM_HERE,
2689 base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask,
2690 base::Unretained(this),
2691 base::TimeDelta::FromMilliseconds(8)));
2692 timer_task_runner_->PostTask(
2693 FROM_HERE, base::Bind(&RendererSchedulerImplTest::SimulateTimerTask,
2694 base::Unretained(this),
2695 base::TimeDelta::FromMilliseconds(40)));
2696
2697 RunUntilIdle();
2698 EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i;
2699 EXPECT_EQ(RendererSchedulerImpl::UseCase::COMPOSITOR_GESTURE,
2700 CurrentUseCase())
2701 << " i = " << i;
2702 EXPECT_FALSE(LoadingTasksSeemExpensive()) << " i = " << i;
2703 EXPECT_FALSE(TimerTasksSeemExpensive()) << " i = " << i;
2704
2705 base::TimeDelta time_till_next_frame =
2706 EstimatedNextFrameBegin() - clock_->NowTicks();
2707 if (time_till_next_frame > base::TimeDelta())
2708 clock_->Advance(time_till_next_frame);
2709 }
2710 }
2711
2712 TEST_F(RendererSchedulerImplTest,
2713 ExpensiveTimer_NotBlocked_UseCase_MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
2714 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2715 SimulateMainThreadGestureStart(TouchEventPolicy::SEND_TOUCH_START,
2716 blink::WebInputEvent::TouchMove);
2717 RunUntilIdle();
2718 for (int i = 0; i < 20; i++) {
2719 simulate_timer_task_ran_ = false;
2720
2721 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
2722 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
2723 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
2724 begin_frame_args.on_critical_path = false;
2725 scheduler_->WillBeginFrame(begin_frame_args);
2726
2727 compositor_task_runner_->PostTask(
2728 FROM_HERE, base::Bind(&RendererSchedulerImplTest::
2729 SimulateMainThreadInputHandlingCompositorTask,
2730 base::Unretained(this),
2731 base::TimeDelta::FromMilliseconds(8)));
2732 timer_task_runner_->PostTask(
2733 FROM_HERE, base::Bind(&RendererSchedulerImplTest::SimulateTimerTask,
2734 base::Unretained(this),
2735 base::TimeDelta::FromMilliseconds(10)));
2736
2737 RunUntilIdle();
2738 EXPECT_EQ(RendererSchedulerImpl::UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING,
2739 CurrentUseCase())
2740 << " i = " << i;
2741 EXPECT_FALSE(LoadingTasksSeemExpensive()) << " i = " << i;
2742 if (i == 0) {
2743 EXPECT_FALSE(TimerTasksSeemExpensive()) << " i = " << i;
2744 } else {
2745 EXPECT_TRUE(TimerTasksSeemExpensive()) << " i = " << i;
2746 }
2747 EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i;
2748
2749 base::TimeDelta time_till_next_frame =
2750 EstimatedNextFrameBegin() - clock_->NowTicks();
2751 if (time_till_next_frame > base::TimeDelta())
2752 clock_->Advance(time_till_next_frame);
2753 }
2754 }
2755
2756 TEST_F(RendererSchedulerImplTest,
2757 EstimateLongestJankFreeTaskDuration_UseCase_NONE) {
2758 EXPECT_EQ(UseCase::NONE, CurrentUseCase());
2759 EXPECT_EQ(rails_response_time(),
2760 scheduler_->EstimateLongestJankFreeTaskDuration());
2761 }
2762
2763 TEST_F(RendererSchedulerImplTest,
2764 EstimateLongestJankFreeTaskDuration_UseCase_COMPOSITOR_GESTURE) {
2765 SimulateCompositorGestureStart(TouchEventPolicy::DONT_SEND_TOUCH_START);
2766 EXPECT_EQ(UseCase::COMPOSITOR_GESTURE,
2767 ForceUpdatePolicyAndGetCurrentUseCase());
2768 EXPECT_EQ(rails_response_time(),
2769 scheduler_->EstimateLongestJankFreeTaskDuration());
2770 }
2771
2772 // TODO(alexclarke): Reenable once we've reinstaed the Loading UseCase.
2773 TEST_F(RendererSchedulerImplTest,
2774 DISABLED_EstimateLongestJankFreeTaskDuration_UseCase_) {
2775 scheduler_->OnNavigationStarted();
2776 EXPECT_EQ(UseCase::LOADING, ForceUpdatePolicyAndGetCurrentUseCase());
2777 EXPECT_EQ(rails_response_time(),
2778 scheduler_->EstimateLongestJankFreeTaskDuration());
2779 }
2780
2781 TEST_F(RendererSchedulerImplTest,
2782 EstimateLongestJankFreeTaskDuration_UseCase_MAIN_THREAD_GESTURE) {
2783 SimulateMainThreadGestureStart(TouchEventPolicy::SEND_TOUCH_START,
2784 blink::WebInputEvent::GestureScrollUpdate);
2785 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
2786 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
2787 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
2788 begin_frame_args.on_critical_path = false;
2789 scheduler_->WillBeginFrame(begin_frame_args);
2790
2791 compositor_task_runner_->PostTask(
2792 FROM_HERE,
2793 base::Bind(&RendererSchedulerImplTest::
2794 SimulateMainThreadInputHandlingCompositorTask,
2795 base::Unretained(this), base::TimeDelta::FromMilliseconds(5)));
2796
2797 RunUntilIdle();
2798 EXPECT_EQ(UseCase::MAIN_THREAD_GESTURE, CurrentUseCase());
2799
2800 // 16ms frame - 5ms compositor work = 11ms for other stuff.
2801 EXPECT_EQ(base::TimeDelta::FromMilliseconds(11),
2802 scheduler_->EstimateLongestJankFreeTaskDuration());
2803 }
2804
2805 TEST_F(
2806 RendererSchedulerImplTest,
2807 EstimateLongestJankFreeTaskDuration_UseCase_MAIN_THREAD_CUSTOM_INPUT_HANDLIN G) {
2808 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
2809 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
2810 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
2811 begin_frame_args.on_critical_path = false;
2812 scheduler_->WillBeginFrame(begin_frame_args);
2813
2814 compositor_task_runner_->PostTask(
2815 FROM_HERE,
2816 base::Bind(&RendererSchedulerImplTest::
2817 SimulateMainThreadInputHandlingCompositorTask,
2818 base::Unretained(this), base::TimeDelta::FromMilliseconds(5)));
2819
2820 RunUntilIdle();
2821 EXPECT_EQ(UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING, CurrentUseCase());
2822
2823 // 16ms frame - 5ms compositor work = 11ms for other stuff.
2824 EXPECT_EQ(base::TimeDelta::FromMilliseconds(11),
2825 scheduler_->EstimateLongestJankFreeTaskDuration());
2826 }
2827
2828 TEST_F(RendererSchedulerImplTest,
2829 EstimateLongestJankFreeTaskDuration_UseCase_SYNCHRONIZED_GESTURE) {
2830 SimulateCompositorGestureStart(TouchEventPolicy::DONT_SEND_TOUCH_START);
2831
2832 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
2833 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
2834 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
2835 begin_frame_args.on_critical_path = true;
2836 scheduler_->WillBeginFrame(begin_frame_args);
2837
2838 compositor_task_runner_->PostTask(
2839 FROM_HERE,
2840 base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask,
2841 base::Unretained(this), base::TimeDelta::FromMilliseconds(5)));
2842
2843 RunUntilIdle();
2844 EXPECT_EQ(UseCase::SYNCHRONIZED_GESTURE, CurrentUseCase());
2845
2846 // 16ms frame - 5ms compositor work = 11ms for other stuff.
2847 EXPECT_EQ(base::TimeDelta::FromMilliseconds(11),
2848 scheduler_->EstimateLongestJankFreeTaskDuration());
2849 }
2850
2851 class WebViewSchedulerImplForTest : public WebViewSchedulerImpl {
2852 public:
2853 WebViewSchedulerImplForTest(RendererSchedulerImpl* scheduler)
2854 : WebViewSchedulerImpl(nullptr, scheduler, false) {}
2855 ~WebViewSchedulerImplForTest() override {}
2856
2857 void AddConsoleWarning(const std::string& message) override {
2858 console_warnings_.push_back(message);
2859 }
2860
2861 const std::vector<std::string>& console_warnings() const {
2862 return console_warnings_;
2863 }
2864
2865 private:
2866 std::vector<std::string> console_warnings_;
2867
2868 DISALLOW_COPY_AND_ASSIGN(WebViewSchedulerImplForTest);
2869 };
2870
2871 TEST_F(RendererSchedulerImplTest, BlockedTimerNotification) {
2872 // Make sure we see one (and just one) console warning about an expensive
2873 // timer being deferred.
2874 WebViewSchedulerImplForTest web_view_scheduler(scheduler_.get());
2875
2876 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2877 scheduler_->SetExpensiveTaskBlockingAllowed(true);
2878 DoMainFrame();
2879 SimulateExpensiveTasks(timer_task_runner_);
2880 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
2881 ForceTouchStartToBeExpectedSoon();
2882
2883 std::vector<std::string> run_order;
2884 PostTestTasks(&run_order, "T1 T2");
2885 RunUntilIdle();
2886
2887 EXPECT_EQ(0u, run_order.size());
2888 EXPECT_EQ(1u, web_view_scheduler.console_warnings().size());
2889 EXPECT_NE(std::string::npos,
2890 web_view_scheduler.console_warnings()[0].find("crbug.com/574343"));
2891 }
2892
2893 TEST_F(RendererSchedulerImplTest,
2894 BlockedTimerNotification_ExpensiveTaskBlockingNotAllowed) {
2895 // Make sure we don't report warnings about blocked tasks when expensive task
2896 // blocking is not allowed.
2897 WebViewSchedulerImplForTest web_view_scheduler(scheduler_.get());
2898
2899 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2900 scheduler_->SetExpensiveTaskBlockingAllowed(false);
2901 scheduler_->SuspendTimerQueue();
2902 DoMainFrame();
2903 SimulateExpensiveTasks(timer_task_runner_);
2904 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
2905 ForceTouchStartToBeExpectedSoon();
2906
2907 std::vector<std::string> run_order;
2908 PostTestTasks(&run_order, "T1 T2");
2909 RunUntilIdle();
2910
2911 EXPECT_EQ(0u, run_order.size());
2912 EXPECT_EQ(0u, web_view_scheduler.console_warnings().size());
2913 }
2914
2915 TEST_F(RendererSchedulerImplTest, BlockedTimerNotification_TimersSuspended) {
2916 // Make sure we don't report warnings about blocked tasks when timers are
2917 // being blocked for other reasons.
2918 WebViewSchedulerImplForTest web_view_scheduler(scheduler_.get());
2919
2920 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2921 scheduler_->SetExpensiveTaskBlockingAllowed(true);
2922 scheduler_->SuspendTimerQueue();
2923 DoMainFrame();
2924 SimulateExpensiveTasks(timer_task_runner_);
2925 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
2926 ForceTouchStartToBeExpectedSoon();
2927
2928 std::vector<std::string> run_order;
2929 PostTestTasks(&run_order, "T1 T2");
2930 RunUntilIdle();
2931
2932 EXPECT_EQ(0u, run_order.size());
2933 EXPECT_EQ(0u, web_view_scheduler.console_warnings().size());
2934 }
2935
2936 TEST_F(RendererSchedulerImplTest, BlockedTimerNotification_TOUCHSTART) {
2937 // Make sure we don't report warnings about blocked tasks during TOUCHSTART.
2938 WebViewSchedulerImplForTest web_view_scheduler(scheduler_.get());
2939
2940 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2941 DoMainFrame();
2942 SimulateExpensiveTasks(timer_task_runner_);
2943 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
2944 scheduler_->DidHandleInputEventOnCompositorThread(
2945 FakeInputEvent(blink::WebInputEvent::TouchStart),
2946 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
2947 EXPECT_EQ(UseCase::TOUCHSTART, ForceUpdatePolicyAndGetCurrentUseCase());
2948
2949 std::vector<std::string> run_order;
2950 PostTestTasks(&run_order, "T1 T2");
2951 RunUntilIdle();
2952
2953 EXPECT_EQ(0u, run_order.size());
2954 EXPECT_EQ(0u, web_view_scheduler.console_warnings().size());
2955 }
2956
2957 TEST_F(RendererSchedulerImplTest,
2958 BlockedTimerNotification_SYNCHRONIZED_GESTURE) {
2959 // Make sure we only report warnings during a high blocking threshold.
2960 WebViewSchedulerImplForTest web_view_scheduler(scheduler_.get());
2961
2962 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
2963 DoMainFrame();
2964 SimulateExpensiveTasks(timer_task_runner_);
2965 SimulateCompositorGestureStart(TouchEventPolicy::DONT_SEND_TOUCH_START);
2966
2967 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
2968 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
2969 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
2970 begin_frame_args.on_critical_path = true;
2971 scheduler_->WillBeginFrame(begin_frame_args);
2972
2973 EXPECT_EQ(UseCase::SYNCHRONIZED_GESTURE,
2974 ForceUpdatePolicyAndGetCurrentUseCase());
2975
2976 std::vector<std::string> run_order;
2977 PostTestTasks(&run_order, "T1 T2");
2978 RunUntilIdle();
2979
2980 EXPECT_EQ(0u, run_order.size());
2981 EXPECT_EQ(0u, web_view_scheduler.console_warnings().size());
2982 }
2983
2984 namespace {
2985 void SlowCountingTask(size_t* count,
2986 base::SimpleTestTickClock* clock,
2987 int task_duration,
2988 scoped_refptr<base::SingleThreadTaskRunner> timer_queue) {
2989 clock->Advance(base::TimeDelta::FromMilliseconds(task_duration));
2990 if (++(*count) < 500) {
2991 timer_queue->PostTask(FROM_HERE, base::Bind(SlowCountingTask, count, clock,
2992 task_duration, timer_queue));
2993 }
2994 }
2995 }
2996
2997 TEST_F(RendererSchedulerImplTest,
2998 SYNCHRONIZED_GESTURE_TimerTaskThrottling_task_expensive) {
2999 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
3000
3001 base::TimeTicks first_throttled_run_time =
3002 ThrottlingHelper::ThrottledRunTime(clock_->NowTicks());
3003
3004 size_t count = 0;
3005 // With the compositor task taking 10ms, there is not enough time to run this
3006 // 7ms timer task in the 16ms frame.
3007 scheduler_->TimerTaskRunner()->PostTask(
3008 FROM_HERE, base::Bind(SlowCountingTask, &count, clock_.get(), 7,
3009 scheduler_->TimerTaskRunner()));
3010
3011 for (int i = 0; i < 1000; i++) {
3012 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
3013 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
3014 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
3015 begin_frame_args.on_critical_path = true;
3016 scheduler_->WillBeginFrame(begin_frame_args);
3017 scheduler_->DidHandleInputEventOnCompositorThread(
3018 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate),
3019 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
3020
3021 simulate_compositor_task_ran_ = false;
3022 compositor_task_runner_->PostTask(
3023 FROM_HERE,
3024 base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask,
3025 base::Unretained(this),
3026 base::TimeDelta::FromMilliseconds(10)));
3027
3028 mock_task_runner_->RunTasksWhile(
3029 base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending,
3030 base::Unretained(this)));
3031 EXPECT_EQ(UseCase::SYNCHRONIZED_GESTURE, CurrentUseCase()) << "i = " << i;
3032
3033 // Before the policy is updated the queue will be enabled. Subsequently it
3034 // will be disabled until the throttled queue is pumped.
3035 bool expect_queue_enabled =
3036 (i == 0) || (clock_->NowTicks() > first_throttled_run_time);
3037 EXPECT_EQ(expect_queue_enabled,
3038 scheduler_->TimerTaskRunner()->IsQueueEnabled())
3039 << "i = " << i;
3040 }
3041
3042 // Task is throttled but not completely blocked.
3043 EXPECT_EQ(12u, count);
3044 }
3045
3046 TEST_F(RendererSchedulerImplTest,
3047 SYNCHRONIZED_GESTURE_TimerTaskThrottling_TimersSuspended) {
3048 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
3049
3050 base::TimeTicks first_throttled_run_time =
3051 ThrottlingHelper::ThrottledRunTime(clock_->NowTicks());
3052
3053 size_t count = 0;
3054 // With the compositor task taking 10ms, there is not enough time to run this
3055 // 7ms timer task in the 16ms frame.
3056 scheduler_->TimerTaskRunner()->PostTask(
3057 FROM_HERE, base::Bind(SlowCountingTask, &count, clock_.get(), 7,
3058 scheduler_->TimerTaskRunner()));
3059
3060 bool suspended = false;
3061 for (int i = 0; i < 1000; i++) {
3062 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
3063 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
3064 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
3065 begin_frame_args.on_critical_path = true;
3066 scheduler_->WillBeginFrame(begin_frame_args);
3067 scheduler_->DidHandleInputEventOnCompositorThread(
3068 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate),
3069 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
3070
3071 simulate_compositor_task_ran_ = false;
3072 compositor_task_runner_->PostTask(
3073 FROM_HERE,
3074 base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask,
3075 base::Unretained(this),
3076 base::TimeDelta::FromMilliseconds(10)));
3077
3078 mock_task_runner_->RunTasksWhile(
3079 base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending,
3080 base::Unretained(this)));
3081 EXPECT_EQ(UseCase::SYNCHRONIZED_GESTURE, CurrentUseCase()) << "i = " << i;
3082
3083 // Before the policy is updated the queue will be enabled. Subsequently it
3084 // will be disabled until the throttled queue is pumped.
3085 bool expect_queue_enabled =
3086 (i == 0) || (clock_->NowTicks() > first_throttled_run_time);
3087 if (suspended)
3088 expect_queue_enabled = false;
3089 EXPECT_EQ(expect_queue_enabled,
3090 scheduler_->TimerTaskRunner()->IsQueueEnabled())
3091 << "i = " << i;
3092
3093 // After we've run any expensive tasks suspend the queue. The throttling
3094 // helper should /not/ re-enable this queue under any circumstances while
3095 // timers are suspended.
3096 if (count > 0 && !suspended) {
3097 EXPECT_EQ(2u, count);
3098 scheduler_->SuspendTimerQueue();
3099 suspended = true;
3100 }
3101 }
3102
3103 // Make sure the timer queue stayed suspended!
3104 EXPECT_EQ(2u, count);
3105 }
3106
3107 TEST_F(RendererSchedulerImplTest,
3108 SYNCHRONIZED_GESTURE_TimerTaskThrottling_task_not_expensive) {
3109 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
3110
3111 size_t count = 0;
3112 // With the compositor task taking 10ms, there is enough time to run this 6ms
3113 // timer task in the 16ms frame.
3114 scheduler_->TimerTaskRunner()->PostTask(
3115 FROM_HERE, base::Bind(SlowCountingTask, &count, clock_.get(), 6,
3116 scheduler_->TimerTaskRunner()));
3117
3118 for (int i = 0; i < 1000; i++) {
3119 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
3120 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
3121 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
3122 begin_frame_args.on_critical_path = true;
3123 scheduler_->WillBeginFrame(begin_frame_args);
3124 scheduler_->DidHandleInputEventOnCompositorThread(
3125 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate),
3126 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
3127
3128 simulate_compositor_task_ran_ = false;
3129 compositor_task_runner_->PostTask(
3130 FROM_HERE,
3131 base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask,
3132 base::Unretained(this),
3133 base::TimeDelta::FromMilliseconds(10)));
3134
3135 mock_task_runner_->RunTasksWhile(
3136 base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending,
3137 base::Unretained(this)));
3138 EXPECT_EQ(UseCase::SYNCHRONIZED_GESTURE, CurrentUseCase()) << "i = " << i;
3139 EXPECT_TRUE(scheduler_->TimerTaskRunner()->IsQueueEnabled()) << "i = " << i;
3140 }
3141
3142 // Task is not throttled.
3143 EXPECT_EQ(500u, count);
3144 }
3145
3146 TEST_F(RendererSchedulerImplTest,
3147 ExpensiveTimerTaskBlocked_SYNCHRONIZED_GESTURE_TouchStartExpected) {
3148 SimulateExpensiveTasks(timer_task_runner_);
3149 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
3150 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
3151 ForceTouchStartToBeExpectedSoon();
3152
3153 // Bump us into SYNCHRONIZED_GESTURE.
3154 scheduler_->DidHandleInputEventOnCompositorThread(
3155 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate),
3156 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
3157
3158 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
3159 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
3160 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
3161 begin_frame_args.on_critical_path = true;
3162 scheduler_->WillBeginFrame(begin_frame_args);
3163
3164 EXPECT_EQ(UseCase::SYNCHRONIZED_GESTURE,
3165 ForceUpdatePolicyAndGetCurrentUseCase());
3166
3167 EXPECT_TRUE(TimerTasksSeemExpensive());
3168 EXPECT_TRUE(TouchStartExpectedSoon());
3169 EXPECT_FALSE(scheduler_->TimerTaskRunner()->IsQueueEnabled());
3170 }
3171
3172 TEST_F(RendererSchedulerImplTest, DenyLongIdleDuringTouchStart) {
3173 scheduler_->DidHandleInputEventOnCompositorThread(
3174 FakeInputEvent(blink::WebInputEvent::TouchStart),
3175 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
3176 EXPECT_EQ(UseCase::TOUCHSTART, ForceUpdatePolicyAndGetCurrentUseCase());
3177
3178 // First check that long idle is denied during the TOUCHSTART use case.
3179 IdleHelper::Delegate* idle_delegate = scheduler_.get();
3180 base::TimeTicks now;
3181 base::TimeDelta next_time_to_check;
3182 EXPECT_FALSE(idle_delegate->CanEnterLongIdlePeriod(now, &next_time_to_check));
3183 EXPECT_GE(next_time_to_check, base::TimeDelta());
3184
3185 // Check again at a time past the TOUCHSTART expiration. We should still get a
3186 // non-negative delay to when to check again.
3187 now += base::TimeDelta::FromMilliseconds(500);
3188 EXPECT_FALSE(idle_delegate->CanEnterLongIdlePeriod(now, &next_time_to_check));
3189 EXPECT_GE(next_time_to_check, base::TimeDelta());
3190 }
3191
3192 TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_TouchStartDuringFling) {
3193 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
3194 scheduler_->DidAnimateForInputOnCompositorThread();
3195 // Note DidAnimateForInputOnCompositorThread does not by itself trigger a
3196 // policy update.
3197 EXPECT_EQ(RendererSchedulerImpl::UseCase::COMPOSITOR_GESTURE,
3198 ForceUpdatePolicyAndGetCurrentUseCase());
3199
3200 // Make sure TouchStart causes a policy change.
3201 scheduler_->DidHandleInputEventOnCompositorThread(
3202 FakeInputEvent(blink::WebInputEvent::TouchStart),
3203 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
3204 EXPECT_EQ(RendererSchedulerImpl::UseCase::TOUCHSTART,
3205 ForceUpdatePolicyAndGetCurrentUseCase());
3206 }
3207
3208 TEST_F(RendererSchedulerImplTest, SYNCHRONIZED_GESTURE_CompositingExpensive) {
3209 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
3210
3211 // With the compositor task taking 20ms, there is not enough time to run
3212 // other tasks in the same 16ms frame. To avoid starvation, compositing tasks
3213 // should therefore not get prioritized.
3214 std::vector<std::string> run_order;
3215 for (int i = 0; i < 1000; i++)
3216 PostTestTasks(&run_order, "T1");
3217
3218 for (int i = 0; i < 100; i++) {
3219 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
3220 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
3221 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
3222 begin_frame_args.on_critical_path = true;
3223 scheduler_->WillBeginFrame(begin_frame_args);
3224 scheduler_->DidHandleInputEventOnCompositorThread(
3225 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate),
3226 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
3227
3228 simulate_compositor_task_ran_ = false;
3229 compositor_task_runner_->PostTask(
3230 FROM_HERE,
3231 base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask,
3232 base::Unretained(this),
3233 base::TimeDelta::FromMilliseconds(20)));
3234
3235 mock_task_runner_->RunTasksWhile(
3236 base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending,
3237 base::Unretained(this)));
3238 EXPECT_EQ(UseCase::SYNCHRONIZED_GESTURE, CurrentUseCase()) << "i = " << i;
3239 }
3240
3241 // Timer tasks should not have been starved by the expensive compositor
3242 // tasks.
3243 EXPECT_EQ(TaskQueue::NORMAL_PRIORITY,
3244 scheduler_->CompositorTaskRunner()->GetQueuePriority());
3245 EXPECT_EQ(1000u, run_order.size());
3246 }
3247
3248 TEST_F(RendererSchedulerImplTest, MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
3249 SimulateMainThreadGestureStart(TouchEventPolicy::SEND_TOUCH_START,
3250 blink::WebInputEvent::GestureScrollBegin);
3251
3252 // With the compositor task taking 20ms, there is not enough time to run
3253 // other tasks in the same 16ms frame. To avoid starvation, compositing tasks
3254 // should therefore not get prioritized.
3255 std::vector<std::string> run_order;
3256 for (int i = 0; i < 1000; i++)
3257 PostTestTasks(&run_order, "T1");
3258
3259 for (int i = 0; i < 100; i++) {
3260 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
3261 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
3262 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
3263 begin_frame_args.on_critical_path = true;
3264 scheduler_->WillBeginFrame(begin_frame_args);
3265 scheduler_->DidHandleInputEventOnCompositorThread(
3266 FakeInputEvent(blink::WebInputEvent::TouchMove),
3267 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
3268
3269 simulate_compositor_task_ran_ = false;
3270 compositor_task_runner_->PostTask(
3271 FROM_HERE,
3272 base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask,
3273 base::Unretained(this),
3274 base::TimeDelta::FromMilliseconds(20)));
3275
3276 mock_task_runner_->RunTasksWhile(
3277 base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending,
3278 base::Unretained(this)));
3279 EXPECT_EQ(UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING, CurrentUseCase())
3280 << "i = " << i;
3281 }
3282
3283 // Timer tasks should not have been starved by the expensive compositor
3284 // tasks.
3285 EXPECT_EQ(TaskQueue::NORMAL_PRIORITY,
3286 scheduler_->CompositorTaskRunner()->GetQueuePriority());
3287 EXPECT_EQ(1000u, run_order.size());
3288 }
3289
3290 TEST_F(RendererSchedulerImplTest, MAIN_THREAD_GESTURE) {
3291 SimulateMainThreadGestureStart(TouchEventPolicy::DONT_SEND_TOUCH_START,
3292 blink::WebInputEvent::GestureScrollBegin);
3293
3294 // With the compositor task taking 20ms, there is not enough time to run
3295 // other tasks in the same 16ms frame. However because this is a main thread
3296 // gesture instead of custom main thread input handling, we allow the timer
3297 // tasks to be starved.
3298 std::vector<std::string> run_order;
3299 for (int i = 0; i < 1000; i++)
3300 PostTestTasks(&run_order, "T1");
3301
3302 for (int i = 0; i < 100; i++) {
3303 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
3304 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
3305 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
3306 begin_frame_args.on_critical_path = true;
3307 scheduler_->WillBeginFrame(begin_frame_args);
3308 scheduler_->DidHandleInputEventOnCompositorThread(
3309 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate),
3310 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
3311
3312 simulate_compositor_task_ran_ = false;
3313 compositor_task_runner_->PostTask(
3314 FROM_HERE,
3315 base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask,
3316 base::Unretained(this),
3317 base::TimeDelta::FromMilliseconds(20)));
3318
3319 mock_task_runner_->RunTasksWhile(
3320 base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending,
3321 base::Unretained(this)));
3322 EXPECT_EQ(UseCase::MAIN_THREAD_GESTURE, CurrentUseCase()) << "i = " << i;
3323 }
3324
3325 EXPECT_EQ(TaskQueue::HIGH_PRIORITY,
3326 scheduler_->CompositorTaskRunner()->GetQueuePriority());
3327 EXPECT_EQ(279u, run_order.size());
3328 }
3329
3330 class MockRAILModeObserver : public RendererScheduler::RAILModeObserver {
3331 public:
3332 MOCK_METHOD1(OnRAILModeChanged, void(v8::RAILMode rail_mode));
3333 };
3334
3335 TEST_F(RendererSchedulerImplTest, TestResponseRAILMode) {
3336 MockRAILModeObserver observer;
3337 scheduler_->SetRAILModeObserver(&observer);
3338 EXPECT_CALL(observer, OnRAILModeChanged(v8::PERFORMANCE_RESPONSE));
3339
3340 scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
3341 ForceTouchStartToBeExpectedSoon();
3342 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
3343 EXPECT_EQ(v8::PERFORMANCE_RESPONSE, RAILMode());
3344 scheduler_->SetRAILModeObserver(nullptr);
3345 }
3346
3347 TEST_F(RendererSchedulerImplTest, TestAnimateRAILMode) {
3348 MockRAILModeObserver observer;
3349 scheduler_->SetRAILModeObserver(&observer);
3350 EXPECT_CALL(observer, OnRAILModeChanged(v8::PERFORMANCE_ANIMATION)).Times(0);
3351
3352 EXPECT_FALSE(BeginFrameNotExpectedSoon());
3353 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
3354 EXPECT_EQ(v8::PERFORMANCE_ANIMATION, RAILMode());
3355 scheduler_->SetRAILModeObserver(nullptr);
3356 }
3357
3358 TEST_F(RendererSchedulerImplTest, TestIdleRAILMode) {
3359 MockRAILModeObserver observer;
3360 scheduler_->SetRAILModeObserver(&observer);
3361 EXPECT_CALL(observer, OnRAILModeChanged(v8::PERFORMANCE_ANIMATION));
3362 EXPECT_CALL(observer, OnRAILModeChanged(v8::PERFORMANCE_IDLE));
3363
3364 scheduler_->SetAllRenderWidgetsHidden(true);
3365 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
3366 EXPECT_EQ(v8::PERFORMANCE_IDLE, RAILMode());
3367 scheduler_->SetAllRenderWidgetsHidden(false);
3368 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
3369 EXPECT_EQ(v8::PERFORMANCE_ANIMATION, RAILMode());
3370 scheduler_->SetRAILModeObserver(nullptr);
3371 }
3372
3373 TEST_F(RendererSchedulerImplTest, UnthrottledTaskRunner) {
3374 // Ensure neither suspension nor timer task throttling affects an unthrottled
3375 // task runner.
3376 SimulateCompositorGestureStart(TouchEventPolicy::SEND_TOUCH_START);
3377 scoped_refptr<TaskQueue> unthrottled_task_runner =
3378 scheduler_->NewUnthrottledTaskRunner("unthrottled_tq");
3379
3380 size_t timer_count = 0;
3381 size_t unthrottled_count = 0;
3382 scheduler_->TimerTaskRunner()->PostTask(
3383 FROM_HERE, base::Bind(SlowCountingTask, &timer_count, clock_.get(), 7,
3384 scheduler_->TimerTaskRunner()));
3385 unthrottled_task_runner->PostTask(
3386 FROM_HERE, base::Bind(SlowCountingTask, &unthrottled_count, clock_.get(),
3387 7, unthrottled_task_runner));
3388 scheduler_->SuspendTimerQueue();
3389
3390 for (int i = 0; i < 1000; i++) {
3391 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
3392 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
3393 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
3394 begin_frame_args.on_critical_path = true;
3395 scheduler_->WillBeginFrame(begin_frame_args);
3396 scheduler_->DidHandleInputEventOnCompositorThread(
3397 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate),
3398 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
3399
3400 simulate_compositor_task_ran_ = false;
3401 compositor_task_runner_->PostTask(
3402 FROM_HERE,
3403 base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask,
3404 base::Unretained(this),
3405 base::TimeDelta::FromMilliseconds(10)));
3406
3407 mock_task_runner_->RunTasksWhile(
3408 base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending,
3409 base::Unretained(this)));
3410 EXPECT_EQ(UseCase::SYNCHRONIZED_GESTURE, CurrentUseCase()) << "i = " << i;
3411 }
3412
3413 EXPECT_EQ(0u, timer_count);
3414 EXPECT_EQ(500u, unthrottled_count);
3415 }
3416
3417 TEST_F(RendererSchedulerImplTest, EnableVirtualTime) {
3418 scheduler_->EnableVirtualTime();
3419
3420 scoped_refptr<TaskQueue> loading_tq =
3421 scheduler_->NewLoadingTaskRunner("test");
3422 scoped_refptr<TaskQueue> timer_tq = scheduler_->NewTimerTaskRunner("test");
3423 scoped_refptr<TaskQueue> unthrottled_tq =
3424 scheduler_->NewUnthrottledTaskRunner("test");
3425
3426 EXPECT_EQ(scheduler_->DefaultTaskRunner()->GetTimeDomain(),
3427 scheduler_->GetVirtualTimeDomain());
3428 EXPECT_EQ(scheduler_->CompositorTaskRunner()->GetTimeDomain(),
3429 scheduler_->GetVirtualTimeDomain());
3430 EXPECT_EQ(scheduler_->LoadingTaskRunner()->GetTimeDomain(),
3431 scheduler_->GetVirtualTimeDomain());
3432 EXPECT_EQ(scheduler_->TimerTaskRunner()->GetTimeDomain(),
3433 scheduler_->GetVirtualTimeDomain());
3434
3435 EXPECT_EQ(loading_tq->GetTimeDomain(), scheduler_->GetVirtualTimeDomain());
3436 EXPECT_EQ(timer_tq->GetTimeDomain(), scheduler_->GetVirtualTimeDomain());
3437 EXPECT_EQ(unthrottled_tq->GetTimeDomain(),
3438 scheduler_->GetVirtualTimeDomain());
3439
3440 EXPECT_EQ(scheduler_->NewLoadingTaskRunner("test")->GetTimeDomain(),
3441 scheduler_->GetVirtualTimeDomain());
3442 EXPECT_EQ(scheduler_->NewTimerTaskRunner("test")->GetTimeDomain(),
3443 scheduler_->GetVirtualTimeDomain());
3444 EXPECT_EQ(scheduler_->NewUnthrottledTaskRunner("test")->GetTimeDomain(),
3445 scheduler_->GetVirtualTimeDomain());
3446 }
3447
3448 } // namespace scheduler
OLDNEW
« no previous file with comments | « components/scheduler/renderer/renderer_scheduler_impl.cc ('k') | components/scheduler/renderer/renderer_web_scheduler_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698