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