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

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

Powered by Google App Engine
This is Rietveld 408576698