Switch scheduler over to Duration

This patch prepares us to switch to using integers when handing off the
animation time from the engine to the framework.
diff --git a/examples/rendering/spinning_flex.dart b/examples/rendering/spinning_flex.dart
index db2055c..1e72aac 100644
--- a/examples/rendering/spinning_flex.dart
+++ b/examples/rendering/spinning_flex.dart
@@ -9,7 +9,7 @@
 
 import 'solid_color_box.dart';
 
-double timeBase;
+Duration timeBase;
 RenderTransform transformBox;
 
 void main() {
@@ -34,10 +34,10 @@
   scheduler.addPersistentFrameCallback(rotate);
 }
 
-void rotate(double timeStamp) {
+void rotate(Duration timeStamp) {
   if (timeBase == null)
     timeBase = timeStamp;
-  double delta = (timeStamp - timeBase) / 1000; // radians
+  double delta = (timeStamp - timeBase).inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND; // radians
 
   transformBox.setIdentity();
   transformBox.translate(transformBox.size.width / 2.0, transformBox.size.height / 2.0);
diff --git a/examples/widgets/spinning_mixed.dart b/examples/widgets/spinning_mixed.dart
index 9317390..f44b0e0 100644
--- a/examples/widgets/spinning_mixed.dart
+++ b/examples/widgets/spinning_mixed.dart
@@ -54,13 +54,13 @@
   );
 }
 
-double timeBase;
+Duration timeBase;
 RenderTransform transformBox;
 
-void rotate(double timeStamp) {
+void rotate(Duration timeStamp) {
   if (timeBase == null)
     timeBase = timeStamp;
-  double delta = (timeStamp - timeBase) / 1000; // radians
+  double delta = (timeStamp - timeBase).inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND; // radians
 
   transformBox.setIdentity();
   transformBox.translate(transformBox.size.width / 2.0, transformBox.size.height / 2.0);
diff --git a/packages/flutter/lib/src/animation/animated_simulation.dart b/packages/flutter/lib/src/animation/animated_simulation.dart
index 0710dfc..6c2f8af 100644
--- a/packages/flutter/lib/src/animation/animated_simulation.dart
+++ b/packages/flutter/lib/src/animation/animated_simulation.dart
@@ -7,10 +7,7 @@
 import 'package:newton/newton.dart';
 import 'package:sky/src/animation/scheduler.dart';
 
-const double _kSecondsPerMillisecond = 1000.0;
-
-// TODO(abarth): Change from double to Duration.
-typedef _TickerCallback(double timeStamp);
+typedef _TickerCallback(Duration timeStamp);
 
 /// Calls its callback once per animation frame
 class Ticker {
@@ -56,7 +53,7 @@
   /// Whether this ticker has scheduled a call to onTick
   bool get isTicking => _completer != null;
 
-  void _tick(double timeStamp) {
+  void _tick(Duration timeStamp) {
     assert(isTicking);
     assert(_animationId != null);
     _animationId = null;
@@ -86,7 +83,7 @@
   Ticker _ticker;
 
   Simulation _simulation;
-  double _startTime;
+  Duration _startTime;
 
   double _value = 0.0;
   /// The current value of the simulation
@@ -119,11 +116,12 @@
   /// Whether this object is currently ticking a simulation
   bool get isAnimating => _ticker.isTicking;
 
-  void _tick(double timeStamp) {
+  void _tick(Duration timeStamp) {
     if (_startTime == null)
       _startTime = timeStamp;
 
-    double timeInSeconds = (timeStamp - _startTime) / _kSecondsPerMillisecond;
+    double timeInMicroseconds = (timeStamp - _startTime).inMicroseconds.toDouble();
+    double timeInSeconds =  timeInMicroseconds / Duration.MICROSECONDS_PER_SECOND;
     _value = _simulation.x(timeInSeconds);
     final bool isLastTick = _simulation.isDone(timeInSeconds);
 
diff --git a/packages/flutter/lib/src/animation/scheduler.dart b/packages/flutter/lib/src/animation/scheduler.dart
index 999ba89..bfa585e 100644
--- a/packages/flutter/lib/src/animation/scheduler.dart
+++ b/packages/flutter/lib/src/animation/scheduler.dart
@@ -14,7 +14,7 @@
 /// scheduler's epoch. Use timeStamp to determine how far to advance animation
 /// timelines so that all the animations in the system are synchronized to a
 /// common time base.
-typedef void SchedulerCallback(double timeStamp);
+typedef void SchedulerCallback(Duration timeStamp);
 
 /// Schedules callbacks to run in concert with the engine's animation system
 class Scheduler {
@@ -35,8 +35,10 @@
   /// This function first calls all the callbacks registered by
   /// [requestAnimationFrame] and then calls all the callbacks registered by
   /// [addPersistentFrameCallback], which typically drive the rendering pipeline.
-  void beginFrame(double timeStamp) {
-    timeStamp /= timeDilation;
+  void beginFrame(double timeStampMS) {
+    timeStampMS /= timeDilation;
+
+    Duration timeStamp = new Duration(microseconds: (timeStampMS * Duration.MICROSECONDS_PER_MILLISECOND).round());
 
     _haveScheduledVisualUpdate = false;
 
diff --git a/packages/flutter/lib/src/rendering/binding.dart b/packages/flutter/lib/src/rendering/binding.dart
index 59bf21b..bf9e31a 100644
--- a/packages/flutter/lib/src/rendering/binding.dart
+++ b/packages/flutter/lib/src/rendering/binding.dart
@@ -78,7 +78,7 @@
   }
 
   /// Pump the rendering pipeline to generate a frame for the given time stamp
-  void beginFrame(double timeStamp) {
+  void beginFrame(Duration timeStamp) {
     RenderObject.flushLayout();
     _renderView.updateCompositingBits();
     RenderObject.flushPaint();
diff --git a/packages/flutter/lib/src/widgets/binding.dart b/packages/flutter/lib/src/widgets/binding.dart
index 792c6a1..59056df 100644
--- a/packages/flutter/lib/src/widgets/binding.dart
+++ b/packages/flutter/lib/src/widgets/binding.dart
@@ -35,7 +35,7 @@
     );
   }
 
-  void beginFrame(double timeStamp) {
+  void beginFrame(Duration timeStamp) {
     buildDirtyElements();
     super.beginFrame(timeStamp);
     Element.finalizeTree();
diff --git a/packages/flutter_sprites/lib/sprite_box.dart b/packages/flutter_sprites/lib/sprite_box.dart
index 07e6d31..3abf3be 100644
--- a/packages/flutter_sprites/lib/sprite_box.dart
+++ b/packages/flutter_sprites/lib/sprite_box.dart
@@ -47,7 +47,7 @@
   }
 
   // Tracking of frame rate and updates
-  double _lastTimeStamp;
+  Duration _lastTimeStamp;
   double _frameRate = 0.0;
 
   double get frameRate => _frameRate;
@@ -349,13 +349,14 @@
     scheduler.requestAnimationFrame(_tick);
   }
 
-  void _tick(double timeStamp) {
+  void _tick(Duration timeStamp) {
     if (!attached)
       return;
 
     // Calculate delta and frame rate
-    if (_lastTimeStamp == null) _lastTimeStamp = timeStamp;
-    double delta = (timeStamp - _lastTimeStamp) / 1000;
+    if (_lastTimeStamp == null)
+      _lastTimeStamp = timeStamp;
+    double delta = (timeStamp - _lastTimeStamp).inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND;
     _lastTimeStamp = timeStamp;
 
     _frameRate = 1.0/delta;
diff --git a/packages/unit/test/animation/scheduler_test.dart b/packages/unit/test/animation/scheduler_test.dart
index 380de02..62f9379 100644
--- a/packages/unit/test/animation/scheduler_test.dart
+++ b/packages/unit/test/animation/scheduler_test.dart
@@ -8,18 +8,18 @@
     bool firstCallbackRan = false;
     bool secondCallbackRan = false;
 
-    void firstCallback(double timeStamp) {
+    void firstCallback(Duration timeStamp) {
       expect(firstCallbackRan, isFalse);
       expect(secondCallbackRan, isFalse);
-      expect(timeStamp, equals(16.0));
+      expect(timeStamp.inMilliseconds, equals(16));
       firstCallbackRan = true;
       scheduler.cancelAnimationFrame(secondId);
     }
 
-    void secondCallback(double timeStamp) {
+    void secondCallback(Duration timeStamp) {
       expect(firstCallbackRan, isTrue);
       expect(secondCallbackRan, isFalse);
-      expect(timeStamp, equals(16.0));
+      expect(timeStamp.inMilliseconds, equals(16));
       secondCallbackRan = true;
     }