• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 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 "cc/scheduler/delay_based_time_source.h"
6 
7 #include "base/basictypes.h"
8 #include "base/test/test_simple_task_runner.h"
9 #include "cc/test/scheduler_test_common.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 
12 namespace cc {
13 namespace {
14 
Interval()15 base::TimeDelta Interval() {
16   return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond /
17                                            60);
18 }
19 
TEST(DelayBasedTimeSourceTest,TaskPostedAndTickCalled)20 TEST(DelayBasedTimeSourceTest, TaskPostedAndTickCalled) {
21   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
22       new base::TestSimpleTaskRunner;
23   FakeTimeSourceClient client;
24   scoped_refptr<FakeDelayBasedTimeSource> timer =
25       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
26   timer->SetClient(&client);
27 
28   timer->SetActive(true);
29   EXPECT_TRUE(timer->Active());
30   EXPECT_TRUE(task_runner->HasPendingTask());
31 
32   timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(16));
33   task_runner->RunPendingTasks();
34   EXPECT_TRUE(timer->Active());
35   EXPECT_TRUE(client.TickCalled());
36 }
37 
TEST(DelayBasedTimeSource,TickNotCalledWithTaskPosted)38 TEST(DelayBasedTimeSource, TickNotCalledWithTaskPosted) {
39   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
40       new base::TestSimpleTaskRunner;
41   FakeTimeSourceClient client;
42   scoped_refptr<FakeDelayBasedTimeSource> timer =
43       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
44   timer->SetClient(&client);
45   timer->SetActive(true);
46   EXPECT_TRUE(task_runner->HasPendingTask());
47   timer->SetActive(false);
48   task_runner->RunPendingTasks();
49   EXPECT_FALSE(client.TickCalled());
50 }
51 
TEST(DelayBasedTimeSource,StartTwiceEnqueuesOneTask)52 TEST(DelayBasedTimeSource, StartTwiceEnqueuesOneTask) {
53   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
54       new base::TestSimpleTaskRunner;
55   FakeTimeSourceClient client;
56   scoped_refptr<FakeDelayBasedTimeSource> timer =
57       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
58   timer->SetClient(&client);
59   timer->SetActive(true);
60   EXPECT_TRUE(task_runner->HasPendingTask());
61   task_runner->ClearPendingTasks();
62   timer->SetActive(true);
63   EXPECT_FALSE(task_runner->HasPendingTask());
64 }
65 
TEST(DelayBasedTimeSource,StartWhenRunningDoesntTick)66 TEST(DelayBasedTimeSource, StartWhenRunningDoesntTick) {
67   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
68       new base::TestSimpleTaskRunner;
69   FakeTimeSourceClient client;
70   scoped_refptr<FakeDelayBasedTimeSource> timer =
71       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
72   timer->SetClient(&client);
73   timer->SetActive(true);
74   EXPECT_TRUE(task_runner->HasPendingTask());
75   task_runner->RunPendingTasks();
76   task_runner->ClearPendingTasks();
77   timer->SetActive(true);
78   EXPECT_FALSE(task_runner->HasPendingTask());
79 }
80 
81 // At 60Hz, when the tick returns at exactly the requested next time, make sure
82 // a 16ms next delay is posted.
TEST(DelayBasedTimeSource,NextDelaySaneWhenExactlyOnRequestedTime)83 TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyOnRequestedTime) {
84   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
85       new base::TestSimpleTaskRunner;
86   FakeTimeSourceClient client;
87   scoped_refptr<FakeDelayBasedTimeSource> timer =
88       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
89   timer->SetClient(&client);
90   timer->SetActive(true);
91   // Run the first tick.
92   task_runner->RunPendingTasks();
93 
94   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
95 
96   timer->SetNow(timer->Now() + Interval());
97   task_runner->RunPendingTasks();
98 
99   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
100 }
101 
102 // At 60Hz, when the tick returns at slightly after the requested next time,
103 // make sure a 16ms next delay is posted.
TEST(DelayBasedTimeSource,NextDelaySaneWhenSlightlyAfterRequestedTime)104 TEST(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterRequestedTime) {
105   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
106       new base::TestSimpleTaskRunner;
107   FakeTimeSourceClient client;
108   scoped_refptr<FakeDelayBasedTimeSource> timer =
109       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
110   timer->SetClient(&client);
111   timer->SetActive(true);
112   // Run the first tick.
113   task_runner->RunPendingTasks();
114 
115   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
116 
117   timer->SetNow(timer->Now() + Interval() +
118                 base::TimeDelta::FromMicroseconds(1));
119   task_runner->RunPendingTasks();
120 
121   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
122 }
123 
124 // At 60Hz, when the tick returns at exactly 2*interval after the requested next
125 // time, make sure a 0ms next delay is posted.
TEST(DelayBasedTimeSource,NextDelaySaneWhenExactlyTwiceAfterRequestedTime)126 TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyTwiceAfterRequestedTime) {
127   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
128       new base::TestSimpleTaskRunner;
129   FakeTimeSourceClient client;
130   scoped_refptr<FakeDelayBasedTimeSource> timer =
131       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
132   timer->SetClient(&client);
133   timer->SetActive(true);
134   // Run the first tick.
135   task_runner->RunPendingTasks();
136 
137   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
138 
139   timer->SetNow(timer->Now() + 2 * Interval());
140   task_runner->RunPendingTasks();
141 
142   EXPECT_EQ(0, task_runner->NextPendingTaskDelay().InMilliseconds());
143 }
144 
145 // At 60Hz, when the tick returns at 2*interval and a bit after the requested
146 // next time, make sure a 16ms next delay is posted.
TEST(DelayBasedTimeSource,NextDelaySaneWhenSlightlyAfterTwiceRequestedTime)147 TEST(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterTwiceRequestedTime) {
148   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
149       new base::TestSimpleTaskRunner;
150   FakeTimeSourceClient client;
151   scoped_refptr<FakeDelayBasedTimeSource> timer =
152       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
153   timer->SetClient(&client);
154   timer->SetActive(true);
155   // Run the first tick.
156   task_runner->RunPendingTasks();
157 
158   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
159 
160   timer->SetNow(timer->Now() + 2 * Interval() +
161                 base::TimeDelta::FromMicroseconds(1));
162   task_runner->RunPendingTasks();
163 
164   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
165 }
166 
167 // At 60Hz, when the tick returns halfway to the next frame time, make sure
168 // a correct next delay value is posted.
TEST(DelayBasedTimeSource,NextDelaySaneWhenHalfAfterRequestedTime)169 TEST(DelayBasedTimeSource, NextDelaySaneWhenHalfAfterRequestedTime) {
170   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
171       new base::TestSimpleTaskRunner;
172   FakeTimeSourceClient client;
173   scoped_refptr<FakeDelayBasedTimeSource> timer =
174       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
175   timer->SetClient(&client);
176   timer->SetActive(true);
177   // Run the first tick.
178   task_runner->RunPendingTasks();
179 
180   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
181 
182   timer->SetNow(timer->Now() + Interval() +
183                 base::TimeDelta::FromMilliseconds(8));
184   task_runner->RunPendingTasks();
185 
186   EXPECT_EQ(8, task_runner->NextPendingTaskDelay().InMilliseconds());
187 }
188 
189 // If the timebase and interval are updated with a jittery source, we want to
190 // make sure we do not double tick.
TEST(DelayBasedTimeSource,SaneHandlingOfJitteryTimebase)191 TEST(DelayBasedTimeSource, SaneHandlingOfJitteryTimebase) {
192   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
193       new base::TestSimpleTaskRunner;
194   FakeTimeSourceClient client;
195   scoped_refptr<FakeDelayBasedTimeSource> timer =
196       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
197   timer->SetClient(&client);
198   timer->SetActive(true);
199   // Run the first tick.
200   task_runner->RunPendingTasks();
201 
202   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
203 
204   // Jitter timebase ~1ms late
205   timer->SetNow(timer->Now() + Interval());
206   timer->SetTimebaseAndInterval(
207       timer->Now() + base::TimeDelta::FromMilliseconds(1), Interval());
208   task_runner->RunPendingTasks();
209 
210   // Without double tick prevention, NextPendingTaskDelay would be 1.
211   EXPECT_EQ(17, task_runner->NextPendingTaskDelay().InMilliseconds());
212 
213   // Jitter timebase ~1ms early
214   timer->SetNow(timer->Now() + Interval());
215   timer->SetTimebaseAndInterval(
216       timer->Now() - base::TimeDelta::FromMilliseconds(1), Interval());
217   task_runner->RunPendingTasks();
218 
219   EXPECT_EQ(15, task_runner->NextPendingTaskDelay().InMilliseconds());
220 }
221 
TEST(DelayBasedTimeSource,HandlesSignificantTimebaseChangesImmediately)222 TEST(DelayBasedTimeSource, HandlesSignificantTimebaseChangesImmediately) {
223   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
224       new base::TestSimpleTaskRunner;
225   FakeTimeSourceClient client;
226   scoped_refptr<FakeDelayBasedTimeSource> timer =
227       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
228   timer->SetClient(&client);
229   timer->SetActive(true);
230   // Run the first tick.
231   task_runner->RunPendingTasks();
232 
233   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
234 
235   // Tick, then shift timebase by +7ms.
236   timer->SetNow(timer->Now() + Interval());
237   task_runner->RunPendingTasks();
238 
239   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
240 
241   client.Reset();
242   task_runner->ClearPendingTasks();
243   task_runner->RunPendingTasks();
244   base::TimeDelta jitter = base::TimeDelta::FromMilliseconds(7) +
245                            base::TimeDelta::FromMicroseconds(1);
246   timer->SetTimebaseAndInterval(timer->Now() + jitter, Interval());
247 
248   EXPECT_FALSE(client.TickCalled());  // Make sure pending tasks were canceled.
249   EXPECT_EQ(16 + 7, task_runner->NextPendingTaskDelay().InMilliseconds());
250 
251   // Tick, then shift timebase by -7ms.
252   timer->SetNow(timer->Now() + Interval() + jitter);
253   task_runner->RunPendingTasks();
254 
255   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
256 
257   client.Reset();
258   task_runner->ClearPendingTasks();
259   task_runner->RunPendingTasks();
260   timer->SetTimebaseAndInterval(base::TimeTicks() + Interval(), Interval());
261 
262   EXPECT_FALSE(client.TickCalled());  // Make sure pending tasks were canceled.
263   EXPECT_EQ(16 - 7, task_runner->NextPendingTaskDelay().InMilliseconds());
264 }
265 
TEST(DelayBasedTimeSource,HanldlesSignificantIntervalChangesImmediately)266 TEST(DelayBasedTimeSource, HanldlesSignificantIntervalChangesImmediately) {
267   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
268       new base::TestSimpleTaskRunner;
269   FakeTimeSourceClient client;
270   scoped_refptr<FakeDelayBasedTimeSource> timer =
271       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
272   timer->SetClient(&client);
273   timer->SetActive(true);
274   // Run the first tick.
275   task_runner->RunPendingTasks();
276 
277   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
278 
279   // Tick, then double the interval.
280   timer->SetNow(timer->Now() + Interval());
281   task_runner->RunPendingTasks();
282 
283   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
284 
285   client.Reset();
286   task_runner->ClearPendingTasks();
287   task_runner->RunPendingTasks();
288   timer->SetTimebaseAndInterval(base::TimeTicks() + Interval(), Interval() * 2);
289 
290   EXPECT_FALSE(client.TickCalled());  // Make sure pending tasks were canceled.
291   EXPECT_EQ(33, task_runner->NextPendingTaskDelay().InMilliseconds());
292 
293   // Tick, then halve the interval.
294   timer->SetNow(timer->Now() + Interval() * 2);
295   task_runner->RunPendingTasks();
296 
297   EXPECT_EQ(33, task_runner->NextPendingTaskDelay().InMilliseconds());
298 
299   client.Reset();
300   task_runner->ClearPendingTasks();
301   task_runner->RunPendingTasks();
302   timer->SetTimebaseAndInterval(base::TimeTicks() + Interval() * 3, Interval());
303 
304   EXPECT_FALSE(client.TickCalled());  // Make sure pending tasks were canceled.
305   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
306 }
307 
TEST(DelayBasedTimeSource,JitteryRuntimeWithFutureTimebases)308 TEST(DelayBasedTimeSource, JitteryRuntimeWithFutureTimebases) {
309   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
310       new base::TestSimpleTaskRunner;
311   FakeTimeSourceClient client;
312   scoped_refptr<FakeDelayBasedTimeSource> timer =
313       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
314   timer->SetClient(&client);
315   timer->SetActive(true);
316 
317   // Run the first tick.
318   task_runner->RunPendingTasks();
319   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
320 
321   base::TimeTicks future_timebase = timer->Now() + Interval() * 10;
322 
323   // 1ms jitter
324   base::TimeDelta jitter1 = base::TimeDelta::FromMilliseconds(1);
325 
326   // Tick with +1ms of jitter
327   future_timebase += Interval();
328   timer->SetTimebaseAndInterval(future_timebase, Interval());
329   timer->SetNow(timer->Now() + Interval() + jitter1);
330   task_runner->RunPendingTasks();
331   EXPECT_EQ(15, task_runner->NextPendingTaskDelay().InMilliseconds());
332 
333   // Tick with 0ms of jitter
334   future_timebase += Interval();
335   timer->SetTimebaseAndInterval(future_timebase, Interval());
336   timer->SetNow(timer->Now() + Interval() - jitter1);
337   task_runner->RunPendingTasks();
338   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
339 
340   // Tick with -1ms of jitter
341   future_timebase += Interval();
342   timer->SetTimebaseAndInterval(future_timebase, Interval());
343   timer->SetNow(timer->Now() + Interval() - jitter1);
344   task_runner->RunPendingTasks();
345   EXPECT_EQ(17, task_runner->NextPendingTaskDelay().InMilliseconds());
346 
347   // Tick with 0ms of jitter
348   future_timebase += Interval();
349   timer->SetTimebaseAndInterval(future_timebase, Interval());
350   timer->SetNow(timer->Now() + Interval() + jitter1);
351   task_runner->RunPendingTasks();
352   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
353 
354   // 8 ms jitter
355   base::TimeDelta jitter8 = base::TimeDelta::FromMilliseconds(8);
356 
357   // Tick with +8ms of jitter
358   future_timebase += Interval();
359   timer->SetTimebaseAndInterval(future_timebase, Interval());
360   timer->SetNow(timer->Now() + Interval() + jitter8);
361   task_runner->RunPendingTasks();
362   EXPECT_EQ(8, task_runner->NextPendingTaskDelay().InMilliseconds());
363 
364   // Tick with 0ms of jitter
365   future_timebase += Interval();
366   timer->SetTimebaseAndInterval(future_timebase, Interval());
367   timer->SetNow(timer->Now() + Interval() - jitter8);
368   task_runner->RunPendingTasks();
369   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
370 
371   // Tick with -8ms of jitter
372   future_timebase += Interval();
373   timer->SetTimebaseAndInterval(future_timebase, Interval());
374   timer->SetNow(timer->Now() + Interval() - jitter8);
375   task_runner->RunPendingTasks();
376   EXPECT_EQ(24, task_runner->NextPendingTaskDelay().InMilliseconds());
377 
378   // Tick with 0ms of jitter
379   future_timebase += Interval();
380   timer->SetTimebaseAndInterval(future_timebase, Interval());
381   timer->SetNow(timer->Now() + Interval() + jitter8);
382   task_runner->RunPendingTasks();
383   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
384 
385   // 15 ms jitter
386   base::TimeDelta jitter15  = base::TimeDelta::FromMilliseconds(15);
387 
388   // Tick with +15ms jitter
389   future_timebase += Interval();
390   timer->SetTimebaseAndInterval(future_timebase, Interval());
391   timer->SetNow(timer->Now() + Interval() + jitter15);
392   task_runner->RunPendingTasks();
393   EXPECT_EQ(1, task_runner->NextPendingTaskDelay().InMilliseconds());
394 
395   // Tick with 0ms of jitter
396   future_timebase += Interval();
397   timer->SetTimebaseAndInterval(future_timebase, Interval());
398   timer->SetNow(timer->Now() + Interval() - jitter15);
399   task_runner->RunPendingTasks();
400   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
401 
402   // Tick with -15ms of jitter
403   future_timebase += Interval();
404   timer->SetTimebaseAndInterval(future_timebase, Interval());
405   timer->SetNow(timer->Now() + Interval() - jitter15);
406   task_runner->RunPendingTasks();
407   EXPECT_EQ(31, task_runner->NextPendingTaskDelay().InMilliseconds());
408 
409   // Tick with 0ms of jitter
410   future_timebase += Interval();
411   timer->SetTimebaseAndInterval(future_timebase, Interval());
412   timer->SetNow(timer->Now() + Interval() + jitter15);
413   task_runner->RunPendingTasks();
414   EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
415 }
416 
TEST(DelayBasedTimeSourceTest,AchievesTargetRateWithNoNoise)417 TEST(DelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise) {
418   int num_iterations = 10;
419 
420   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
421       new base::TestSimpleTaskRunner;
422   FakeTimeSourceClient client;
423   scoped_refptr<FakeDelayBasedTimeSource> timer =
424       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
425   timer->SetClient(&client);
426   timer->SetActive(true);
427 
428   double total_frame_time = 0.0;
429   for (int i = 0; i < num_iterations; ++i) {
430     int64 delay_ms = task_runner->NextPendingTaskDelay().InMilliseconds();
431 
432     // accumulate the "delay"
433     total_frame_time += delay_ms / 1000.0;
434 
435     // Run the callback exactly when asked
436     timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(delay_ms));
437     task_runner->RunPendingTasks();
438   }
439   double average_interval =
440       total_frame_time / static_cast<double>(num_iterations);
441   EXPECT_NEAR(1.0 / 60.0, average_interval, 0.1);
442 }
443 
TEST(DelayBasedTimeSource,TestDeactivateWhilePending)444 TEST(DelayBasedTimeSource, TestDeactivateWhilePending) {
445   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
446       new base::TestSimpleTaskRunner;
447   FakeTimeSourceClient client;
448   scoped_refptr<FakeDelayBasedTimeSource> timer =
449       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
450   timer->SetClient(&client);
451   timer->SetActive(true);  // Should post a task.
452   timer->SetActive(false);
453   timer = NULL;
454   // Should run the posted task without crashing.
455   EXPECT_TRUE(task_runner->HasPendingTask());
456   task_runner->RunPendingTasks();
457 }
458 
TEST(DelayBasedTimeSource,TestDeactivateAndReactivateBeforeNextTickTime)459 TEST(DelayBasedTimeSource, TestDeactivateAndReactivateBeforeNextTickTime) {
460   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
461       new base::TestSimpleTaskRunner;
462   FakeTimeSourceClient client;
463   scoped_refptr<FakeDelayBasedTimeSource> timer =
464       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
465   timer->SetClient(&client);
466 
467   // Should run the activate task, and pick up a new timebase.
468   timer->SetActive(true);
469   task_runner->RunPendingTasks();
470 
471   // Stop the timer
472   timer->SetActive(false);
473 
474   // Task will be pending anyway, run it
475   task_runner->RunPendingTasks();
476 
477   // Start the timer again, but before the next tick time the timer previously
478   // planned on using. That same tick time should still be targeted.
479   timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(4));
480   timer->SetActive(true);
481   EXPECT_EQ(12, task_runner->NextPendingTaskDelay().InMilliseconds());
482 }
483 
TEST(DelayBasedTimeSource,TestDeactivateAndReactivateAfterNextTickTime)484 TEST(DelayBasedTimeSource, TestDeactivateAndReactivateAfterNextTickTime) {
485   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
486       new base::TestSimpleTaskRunner;
487   FakeTimeSourceClient client;
488   scoped_refptr<FakeDelayBasedTimeSource> timer =
489       FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
490   timer->SetClient(&client);
491 
492   // Should run the activate task, and pick up a new timebase.
493   timer->SetActive(true);
494   task_runner->RunPendingTasks();
495 
496   // Stop the timer.
497   timer->SetActive(false);
498 
499   // Task will be pending anyway, run it.
500   task_runner->RunPendingTasks();
501 
502   // Start the timer again, but before the next tick time the timer previously
503   // planned on using. That same tick time should still be targeted.
504   timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(20));
505   timer->SetActive(true);
506   EXPECT_EQ(13, task_runner->NextPendingTaskDelay().InMilliseconds());
507 }
508 
TEST(DelayBasedTimeSource,TestOverflow)509 TEST(DelayBasedTimeSource, TestOverflow) {
510   // int(big_now / interval) < 0, so this causes a crash if the number of
511   // intervals elapsed is attempted to be stored in an int.
512   base::TimeDelta interval = base::TimeDelta::FromInternalValue(4000);
513   base::TimeTicks big_now = base::TimeTicks::FromInternalValue(8635916564000);
514 
515   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
516       new base::TestSimpleTaskRunner;
517   FakeTimeSourceClient client;
518   scoped_refptr<FakeDelayBasedTimeSource> timer =
519       FakeDelayBasedTimeSource::Create(interval, task_runner.get());
520   timer->SetClient(&client);
521   timer->SetNow(big_now);
522   timer->SetActive(true);
523   EXPECT_EQ(0, task_runner->NextPendingTaskDelay().InMilliseconds());
524 }
525 
526 }  // namespace
527 }  // namespace cc
528