QuicTime integration

Merge internal change: 37669847


Review URL: https://chromiumcodereview.appspot.com/11293161

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@167124 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/net.gyp b/net/net.gyp
index 513cee8..df18e20 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -692,6 +692,8 @@
         'quic/quic_session.h',
         'quic/quic_stream_sequencer.cc',
         'quic/quic_stream_sequencer.h',
+        'quic/quic_time.cc',
+        'quic/quic_time.h',
         'quic/quic_utils.cc',
         'quic/quic_utils.h',
         'quic/reliable_quic_stream.cc',
@@ -1439,6 +1441,7 @@
         'quic/test_tools/test_task_runner.cc',
         'quic/test_tools/test_task_runner.h',
         'quic/quic_client_session_test.cc',
+        'quic/quic_clock_test.cc',
         'quic/quic_connection_helper_test.cc',
         'quic/quic_connection_test.cc',
         'quic/quic_crypto_client_stream_test.cc',
@@ -1449,6 +1452,7 @@
         'quic/quic_reliable_client_stream_test.cc',
         'quic/quic_session_test.cc',
         'quic/quic_stream_sequencer_test.cc',
+        'quic/quic_time_test.cc',
         'socket/buffered_write_stream_socket_unittest.cc',
         'socket/client_socket_pool_base_unittest.cc',
         'socket/deterministic_socket_data_unittest.cc',
diff --git a/net/quic/congestion_control/fix_rate_receiver.cc b/net/quic/congestion_control/fix_rate_receiver.cc
index 5adfc6ce..692765eb8 100644
--- a/net/quic/congestion_control/fix_rate_receiver.cc
+++ b/net/quic/congestion_control/fix_rate_receiver.cc
@@ -25,10 +25,10 @@
 }
 
 void FixRateReceiver::RecordIncomingPacket(
-    size_t bytes,
-    QuicPacketSequenceNumber sequence_number,
-    uint64 timestamp_us,
-    bool recovered) {
+    size_t /*bytes*/,
+    QuicPacketSequenceNumber /*sequence_number*/,
+    QuicTime /*timestamp*/,
+    bool /*recovered*/) {
   // Nothing to do for this simple implementation.
 }
 
diff --git a/net/quic/congestion_control/fix_rate_receiver.h b/net/quic/congestion_control/fix_rate_receiver.h
index f212217..54c6df9 100644
--- a/net/quic/congestion_control/fix_rate_receiver.h
+++ b/net/quic/congestion_control/fix_rate_receiver.h
@@ -24,7 +24,7 @@
   // Implements ReceiveAlgorithmInterface.
   virtual void RecordIncomingPacket(size_t bytes,
                                     QuicPacketSequenceNumber sequence_number,
-                                    uint64 timestamp_us,
+                                    QuicTime timestamp,
                                     bool recovered) OVERRIDE;
 
   void SetBitrate(int bytes_per_second);  // Used for testing only.
diff --git a/net/quic/congestion_control/fix_rate_sender.cc b/net/quic/congestion_control/fix_rate_sender.cc
index a667593..3161b89 100644
--- a/net/quic/congestion_control/fix_rate_sender.cc
+++ b/net/quic/congestion_control/fix_rate_sender.cc
@@ -40,7 +40,8 @@
 
 void FixRateSender::OnIncomingAck(
     QuicPacketSequenceNumber /*acked_sequence_number*/,
-    size_t bytes_acked, uint64 /*rtt_us*/) {
+    size_t bytes_acked,
+    QuicTime::Delta /*rtt*/) {
   bytes_in_flight_ -= bytes_acked;
 }
 
@@ -58,18 +59,21 @@
   }
 }
 
-int FixRateSender::TimeUntilSend(bool /*retransmit*/) {
+QuicTime::Delta FixRateSender::TimeUntilSend(bool /*retransmit*/) {
   if (CongestionWindow() > fix_rate_leaky_bucket_.BytesPending()) {
     if (CongestionWindow() <= bytes_in_flight_) {
-      return kUnknownWaitTime;  // We need an ack before we send more.
+      // We need an ack before we send more.
+      return QuicTime::Delta::Infinite();
     }
-    return paced_sender_.TimeUntilSend(0);
+    QuicTime::Delta zero_time;
+    return paced_sender_.TimeUntilSend(zero_time);
   }
-  uint64 time_remaining_us = fix_rate_leaky_bucket_.TimeRemaining();
-  if (time_remaining_us == 0) {
-    return kUnknownWaitTime;  // We need an ack before we send more.
+  QuicTime::Delta time_remaining = fix_rate_leaky_bucket_.TimeRemaining();
+  if (time_remaining.IsZero()) {
+    // We need an ack before we send more.
+    return QuicTime::Delta::Infinite();
   }
-  return paced_sender_.TimeUntilSend(time_remaining_us);
+  return paced_sender_.TimeUntilSend(time_remaining);
 }
 
 size_t FixRateSender::CongestionWindow() {
diff --git a/net/quic/congestion_control/fix_rate_sender.h b/net/quic/congestion_control/fix_rate_sender.h
index eceb1b9..c2d9f1466 100644
--- a/net/quic/congestion_control/fix_rate_sender.h
+++ b/net/quic/congestion_control/fix_rate_sender.h
@@ -11,6 +11,7 @@
 #include "base/compiler_specific.h"
 #include "net/base/net_export.h"
 #include "net/quic/quic_clock.h"
+#include "net/quic/quic_time.h"
 #include "net/quic/congestion_control/leaky_bucket.h"
 #include "net/quic/congestion_control/paced_sender.h"
 #include "net/quic/congestion_control/send_algorithm_interface.h"
@@ -26,11 +27,12 @@
       const CongestionInfo& congestion_info) OVERRIDE;
   virtual void OnIncomingAck(QuicPacketSequenceNumber acked_sequence_number,
                              size_t acked_bytes,
-                             uint64 rtt_us) OVERRIDE;
+                             QuicTime::Delta rtt) OVERRIDE;
   virtual void OnIncomingLoss(int number_of_lost_packets) OVERRIDE;
   virtual void SentPacket(QuicPacketSequenceNumber equence_number,
-                          size_t bytes, bool retransmit) OVERRIDE;
-  virtual int TimeUntilSend(bool retransmit) OVERRIDE;
+                          size_t bytes,
+                          bool retransmit) OVERRIDE;
+  virtual QuicTime::Delta TimeUntilSend(bool retransmit) OVERRIDE;
   virtual size_t AvailableCongestionWindow() OVERRIDE;
   virtual int BandwidthEstimate() OVERRIDE;
   // End implementation of SendAlgorithmInterface.
diff --git a/net/quic/congestion_control/fix_rate_test.cc b/net/quic/congestion_control/fix_rate_test.cc
index 169d4c73..6981508 100644
--- a/net/quic/congestion_control/fix_rate_test.cc
+++ b/net/quic/congestion_control/fix_rate_test.cc
@@ -1,8 +1,8 @@
 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-
-#include <cmath>
+//
+// Test for FixRate sender and receiver.
 
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
@@ -10,21 +10,24 @@
 #include "net/quic/congestion_control/fix_rate_sender.h"
 #include "net/quic/test_tools/mock_clock.h"
 #include "net/quic/quic_protocol.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace {
-  const int rtt_us = 30000;
-}
-
 namespace net {
+namespace testing {
 
 class FixRateTest : public ::testing::Test {
  protected:
+  FixRateTest()
+      : rtt_(QuicTime::Delta::FromMilliseconds(30)) {
+  }
   void SetUp() {
     sender_.reset(new FixRateSender(&clock_));
     receiver_.reset(new FixRateReceiver());
-    clock_.AdvanceTime(0.002);  // Make sure clock does not start at 0.
+    // Make sure clock does not start at 0.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
   }
+  const QuicTime::Delta rtt_;
   MockClock clock_;
   scoped_ptr<FixRateSender> sender_;
   scoped_ptr<FixRateReceiver> receiver_;
@@ -32,8 +35,9 @@
 
 TEST_F(FixRateTest, ReceiverAPI) {
   CongestionInfo info;
+  QuicTime timestamp;
   receiver_->SetBitrate(300000);  // Bytes per second.
-  receiver_->RecordIncomingPacket(1, 1, 1, false);
+  receiver_->RecordIncomingPacket(1, 1, timestamp, false);
   ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
   EXPECT_EQ(kFixRate, info.type);
   EXPECT_EQ(300000u, info.fix_rate.bitrate_in_bytes_per_second);
@@ -45,45 +49,50 @@
   info.fix_rate.bitrate_in_bytes_per_second = 300000;
   sender_->OnIncomingCongestionInfo(info);
   EXPECT_EQ(300000, sender_->BandwidthEstimate());
-  EXPECT_EQ(0, sender_->TimeUntilSend(false));
-  EXPECT_EQ(kMaxPacketSize * 2, sender_->AvailableCongestionWindow());
+  EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
+  EXPECT_EQ(kMaxPacketSize * 2u, sender_->AvailableCongestionWindow());
   sender_->SentPacket(1, kMaxPacketSize, false);
-  EXPECT_EQ(3000-kMaxPacketSize, sender_->AvailableCongestionWindow());
-  EXPECT_EQ(0, sender_->TimeUntilSend(false));
+  EXPECT_EQ(3000u - kMaxPacketSize, sender_->AvailableCongestionWindow());
+  EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
   sender_->SentPacket(2, kMaxPacketSize, false);
   sender_->SentPacket(3, 600, false);
-  EXPECT_EQ(10000, sender_->TimeUntilSend(false));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+            sender_->TimeUntilSend(false));
   EXPECT_EQ(0u, sender_->AvailableCongestionWindow());
-  clock_.AdvanceTime(0.002);
-  EXPECT_EQ(kUnknownWaitTime, sender_->TimeUntilSend(false));
-  clock_.AdvanceTime(0.008);
-  sender_->OnIncomingAck(1, kMaxPacketSize, rtt_us);
-  sender_->OnIncomingAck(2, kMaxPacketSize, rtt_us);
-  sender_->OnIncomingAck(3, 600, rtt_us);
-  EXPECT_EQ(0, sender_->TimeUntilSend(false));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), sender_->TimeUntilSend(false));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8));
+  sender_->OnIncomingAck(1, kMaxPacketSize, rtt_);
+  sender_->OnIncomingAck(2, kMaxPacketSize, rtt_);
+  sender_->OnIncomingAck(3, 600, rtt_);
+  EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
 }
 
 TEST_F(FixRateTest, FixRatePacing) {
-  const int packet_size = 1200;
+  const uint64 packet_size = 1200;
+  const uint64 bit_rate = 240000;
+  const uint64 num_packets = 200;
   CongestionInfo info;
   receiver_->SetBitrate(240000);  // Bytes per second.
   ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
   sender_->OnIncomingCongestionInfo(info);
-  double acc_advance_time = 0.0;
+  QuicTime acc_advance_time;
   QuicPacketSequenceNumber sequence_number = 0;
-  for (int i = 0; i < 100; ++i) {
-    EXPECT_EQ(0, sender_->TimeUntilSend(false));
-    EXPECT_EQ(kMaxPacketSize * 2u, sender_->AvailableCongestionWindow());
+  for (size_t i = 0; i < num_packets; i += 2) {
+    EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
+    EXPECT_EQ(kMaxPacketSize * 2, sender_->AvailableCongestionWindow());
     sender_->SentPacket(sequence_number++, packet_size, false);
-    EXPECT_EQ(0, sender_->TimeUntilSend(false));
+    EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
     sender_->SentPacket(sequence_number++, packet_size, false);
-    double advance_time = sender_->TimeUntilSend(false) / 1000000.0;
+    QuicTime::Delta advance_time = sender_->TimeUntilSend(false);
     clock_.AdvanceTime(advance_time);
-    sender_->OnIncomingAck(sequence_number - 1, packet_size, rtt_us);
-    sender_->OnIncomingAck(sequence_number - 2, packet_size, rtt_us);
-    acc_advance_time += advance_time;
+    sender_->OnIncomingAck(sequence_number - 1, packet_size, rtt_);
+    sender_->OnIncomingAck(sequence_number - 2, packet_size, rtt_);
+    acc_advance_time = acc_advance_time.Add(advance_time);
   }
-  EXPECT_EQ(1000, floor((acc_advance_time * 1000) + 0.5));
+  EXPECT_EQ(num_packets * packet_size * 1000000 / bit_rate,
+            acc_advance_time.ToMicroseconds());
 }
 
+}  // namespace testing
 }  // namespace net
diff --git a/net/quic/congestion_control/leaky_bucket.cc b/net/quic/congestion_control/leaky_bucket.cc
index 4944fdf..d3dd513 100644
--- a/net/quic/congestion_control/leaky_bucket.cc
+++ b/net/quic/congestion_control/leaky_bucket.cc
@@ -11,7 +11,6 @@
 LeakyBucket::LeakyBucket(const QuicClock* clock, int bytes_per_second)
     : clock_(clock),
       bytes_(0),
-      time_last_updated_us_(0),
       draining_rate_bytes_per_s_(bytes_per_second) {
 }
 
@@ -25,11 +24,11 @@
   bytes_ += bytes;
 }
 
-uint64 LeakyBucket::TimeRemaining() {
+QuicTime::Delta LeakyBucket::TimeRemaining() {
   Update();
-  uint64 time_remaining_us = (bytes_ * base::Time::kMicrosecondsPerSecond) /
-      draining_rate_bytes_per_s_;
-  return time_remaining_us;
+  return QuicTime::Delta::FromMicroseconds(
+      (bytes_ * base::Time::kMicrosecondsPerSecond) /
+      draining_rate_bytes_per_s_);
 }
 
 size_t LeakyBucket::BytesPending() {
@@ -38,15 +37,16 @@
 }
 
 void LeakyBucket::Update() {
-  uint64 elapsed_time_us = clock_->NowInUsec() - time_last_updated_us_;
-  size_t bytes_cleared = (elapsed_time_us * draining_rate_bytes_per_s_) /
+  QuicTime::Delta elapsed_time = clock_->Now().Subtract(time_last_updated_);
+  size_t bytes_cleared =
+      (elapsed_time.ToMicroseconds() * draining_rate_bytes_per_s_) /
       base::Time::kMicrosecondsPerSecond;
   if (bytes_cleared >= bytes_) {
     bytes_ = 0;
   } else {
     bytes_ -= bytes_cleared;
   }
-  time_last_updated_us_ = clock_->NowInUsec();
+  time_last_updated_ = clock_->Now();
 }
 
 }  // namespace net
diff --git a/net/quic/congestion_control/leaky_bucket.h b/net/quic/congestion_control/leaky_bucket.h
index 1f642ab2..4dea418 100644
--- a/net/quic/congestion_control/leaky_bucket.h
+++ b/net/quic/congestion_control/leaky_bucket.h
@@ -13,6 +13,7 @@
 #include "base/basictypes.h"
 #include "net/base/net_export.h"
 #include "net/quic/quic_clock.h"
+#include "net/quic/quic_time.h"
 
 namespace net {
 
@@ -28,7 +29,7 @@
   void Add(size_t bytes);
 
   // Time until the buffer is empty in us.
-  uint64 TimeRemaining();
+  QuicTime::Delta TimeRemaining();
 
   // Number of bytes in the buffer.
   size_t BytesPending();
@@ -38,7 +39,7 @@
 
   const QuicClock* clock_;
   size_t bytes_;
-  uint64 time_last_updated_us_;
+  QuicTime time_last_updated_;
   int draining_rate_bytes_per_s_;
 };
 
diff --git a/net/quic/congestion_control/leaky_bucket_test.cc b/net/quic/congestion_control/leaky_bucket_test.cc
index 5b4e18a..9851569 100644
--- a/net/quic/congestion_control/leaky_bucket_test.cc
+++ b/net/quic/congestion_control/leaky_bucket_test.cc
@@ -9,9 +9,8 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using ::testing::_;
-
 namespace net {
+namespace testing {
 
 class LeakyBucketTest : public ::testing::Test {
  protected:
@@ -27,29 +26,32 @@
   leaky_bucket_->SetDrainingRate(bytes_per_second);
   leaky_bucket_->Add(2000);
   EXPECT_EQ(2000u, leaky_bucket_->BytesPending());
-  EXPECT_EQ(10000u, leaky_bucket_->TimeRemaining());
-  clock_.AdvanceTime(0.005);
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+            leaky_bucket_->TimeRemaining());
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_EQ(1000u, leaky_bucket_->BytesPending());
-  EXPECT_EQ(5000u, leaky_bucket_->TimeRemaining());
-  clock_.AdvanceTime(0.005);
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(5),
+            leaky_bucket_->TimeRemaining());
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_EQ(0u, leaky_bucket_->BytesPending());
-  EXPECT_EQ(0u, leaky_bucket_->TimeRemaining());
-  clock_.AdvanceTime(0.005);
+  EXPECT_TRUE(leaky_bucket_->TimeRemaining().IsZero());
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_EQ(0u, leaky_bucket_->BytesPending());
-  EXPECT_EQ(0u, leaky_bucket_->TimeRemaining());
+  EXPECT_TRUE(leaky_bucket_->TimeRemaining().IsZero());
   leaky_bucket_->Add(2000);
-  clock_.AdvanceTime(0.011);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(11));
   EXPECT_EQ(0u, leaky_bucket_->BytesPending());
-  EXPECT_EQ(0u, leaky_bucket_->TimeRemaining());
+  EXPECT_TRUE(leaky_bucket_->TimeRemaining().IsZero());
   leaky_bucket_->Add(2000);
-  clock_.AdvanceTime(0.005);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   leaky_bucket_->Add(2000);
-  clock_.AdvanceTime(0.005);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_EQ(2000u, leaky_bucket_->BytesPending());
-  EXPECT_EQ(10000u, leaky_bucket_->TimeRemaining());
-  clock_.AdvanceTime(0.010);
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+            leaky_bucket_->TimeRemaining());
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
   EXPECT_EQ(0u, leaky_bucket_->BytesPending());
-  EXPECT_EQ(0u, leaky_bucket_->TimeRemaining());
+  EXPECT_TRUE(leaky_bucket_->TimeRemaining().IsZero());
 }
 
 TEST_F(LeakyBucketTest, ChangeDrainRate) {
@@ -57,14 +59,18 @@
   leaky_bucket_->SetDrainingRate(bytes_per_second);
   leaky_bucket_->Add(2000);
   EXPECT_EQ(2000u, leaky_bucket_->BytesPending());
-  EXPECT_EQ(10000u, leaky_bucket_->TimeRemaining());
-  clock_.AdvanceTime(0.005);
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+            leaky_bucket_->TimeRemaining());
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_EQ(1000u, leaky_bucket_->BytesPending());
-  EXPECT_EQ(5000u, leaky_bucket_->TimeRemaining());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(5),
+            leaky_bucket_->TimeRemaining());
   bytes_per_second = 100000;  // Cut drain rate in half.
   leaky_bucket_->SetDrainingRate(bytes_per_second);
   EXPECT_EQ(1000u, leaky_bucket_->BytesPending());
-  EXPECT_EQ(10000u, leaky_bucket_->TimeRemaining());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+            leaky_bucket_->TimeRemaining());
 }
 
+}  // namespace testing
 }  // namespace net
diff --git a/net/quic/congestion_control/paced_sender.cc b/net/quic/congestion_control/paced_sender.cc
index f36a94a..127cdb27 100644
--- a/net/quic/congestion_control/paced_sender.cc
+++ b/net/quic/congestion_control/paced_sender.cc
@@ -13,7 +13,7 @@
 const size_t kMinPacketBurstSize = 2;
 // Max estimated time between calls to TimeUntilSend and
 // AvailableCongestionWindow.
-const int kMaxSchedulingDelayUs = 2000;
+const int64 kMaxSchedulingDelayUs = 2000;
 
 PacedSender::PacedSender(const QuicClock* clock, int bytes_per_s)
     : leaky_bucket_(clock, bytes_per_s),
@@ -29,8 +29,8 @@
   leaky_bucket_.Add(bytes);
 }
 
-int PacedSender::TimeUntilSend(int time_until_send_us) {
-  if (time_until_send_us < kMaxSchedulingDelayUs) {
+QuicTime::Delta PacedSender::TimeUntilSend(QuicTime::Delta time_until_send) {
+  if (time_until_send.ToMicroseconds() < kMaxSchedulingDelayUs) {
     // Pace the data.
     size_t pacing_window = kMaxSchedulingDelayUs * pace_in_bytes_per_s_ /
         base::Time::kMicrosecondsPerSecond;
@@ -39,11 +39,11 @@
 
     if (pacing_window > leaky_bucket_.BytesPending()) {
       // We have not filled our pacing window yet.
-      return time_until_send_us;
+      return time_until_send;
     }
     return leaky_bucket_.TimeRemaining();
   }
-  return time_until_send_us;
+  return time_until_send;
 }
 
 size_t PacedSender::AvailableWindow(size_t available_congestion_window) {
diff --git a/net/quic/congestion_control/paced_sender.h b/net/quic/congestion_control/paced_sender.h
index e82f809..afd8773 100644
--- a/net/quic/congestion_control/paced_sender.h
+++ b/net/quic/congestion_control/paced_sender.h
@@ -11,6 +11,7 @@
 #include "net/base/net_export.h"
 #include "net/quic/congestion_control/leaky_bucket.h"
 #include "net/quic/quic_clock.h"
+#include "net/quic/quic_time.h"
 
 namespace net {
 
@@ -25,7 +26,7 @@
   void SentPacket(size_t bytes);
 
   // Return time until we can send based on the pacing.
-  int TimeUntilSend(int time_until_send_us);
+  QuicTime::Delta TimeUntilSend(QuicTime::Delta time_until_send);
 
   // Return the amount of data in bytes we can send based on the pacing.
   // available_congestion_window is the congestion algorithms available
diff --git a/net/quic/congestion_control/paced_sender_test.cc b/net/quic/congestion_control/paced_sender_test.cc
index c5b3215..70582bf8 100644
--- a/net/quic/congestion_control/paced_sender_test.cc
+++ b/net/quic/congestion_control/paced_sender_test.cc
@@ -10,8 +10,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using ::testing::_;
-
 namespace net {
 namespace testing {
 
@@ -19,28 +17,67 @@
 
 class PacedSenderTest : public ::testing::Test {
  protected:
-  void SetUp() {
-    paced_sender_.reset(new PacedSender(&clock_, kHundredKBytesPerS));
+  PacedSenderTest()
+      : paced_sender_(new PacedSender(&clock_, kHundredKBytesPerS)) {
   }
+
+  const QuicTime::Delta zero_time_;
   MockClock clock_;
   scoped_ptr<net::PacedSender> paced_sender_;
 };
 
 TEST_F(PacedSenderTest, Basic) {
   paced_sender_->UpdateBandwidthEstimate(kHundredKBytesPerS * 10);
-  EXPECT_EQ(0, paced_sender_->TimeUntilSend(0));
+  EXPECT_TRUE(paced_sender_->TimeUntilSend(zero_time_).IsZero());
   EXPECT_EQ(kMaxPacketSize * 2,
             paced_sender_->AvailableWindow(kMaxPacketSize * 4));
   paced_sender_->SentPacket(kMaxPacketSize);
-  EXPECT_EQ(0, paced_sender_->TimeUntilSend(0));
+  EXPECT_TRUE(paced_sender_->TimeUntilSend(zero_time_).IsZero());
   paced_sender_->SentPacket(kMaxPacketSize);
-  EXPECT_EQ(int(kMaxPacketSize * 2), paced_sender_->TimeUntilSend(0));
+  EXPECT_EQ(static_cast<int>(kMaxPacketSize * 2),
+            paced_sender_->TimeUntilSend(zero_time_).ToMicroseconds());
   EXPECT_EQ(0u, paced_sender_->AvailableWindow(kMaxPacketSize * 4));
-  clock_.AdvanceTime(0.0024);
-  EXPECT_EQ(0, paced_sender_->TimeUntilSend(0));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(24));
+  EXPECT_TRUE(paced_sender_->TimeUntilSend(zero_time_).IsZero());
   EXPECT_EQ(kMaxPacketSize * 2,
             paced_sender_->AvailableWindow(kMaxPacketSize * 4));
 }
 
+TEST_F(PacedSenderTest, LowRate) {
+  paced_sender_->UpdateBandwidthEstimate(kHundredKBytesPerS);
+  EXPECT_TRUE(paced_sender_->TimeUntilSend(zero_time_).IsZero());
+  size_t window = paced_sender_->AvailableWindow(kMaxPacketSize * 4);
+  EXPECT_EQ(kMaxPacketSize * 2, window);
+  paced_sender_->SentPacket(kMaxPacketSize);
+  EXPECT_TRUE(paced_sender_->TimeUntilSend(zero_time_).IsZero());
+  paced_sender_->SentPacket(kMaxPacketSize);
+  EXPECT_EQ(static_cast<int>(kMaxPacketSize * 20),
+            paced_sender_->TimeUntilSend(zero_time_).ToMicroseconds());
+  EXPECT_EQ(0u, paced_sender_->AvailableWindow(kMaxPacketSize * 4));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(24));
+  EXPECT_TRUE(paced_sender_->TimeUntilSend(zero_time_).IsZero());
+  EXPECT_EQ(kMaxPacketSize * 2,
+            paced_sender_->AvailableWindow(kMaxPacketSize * 4));
+}
+
+TEST_F(PacedSenderTest, HighRate) {
+  int bandwidth_estimate = kHundredKBytesPerS * 100;
+  paced_sender_->UpdateBandwidthEstimate(bandwidth_estimate);
+  EXPECT_TRUE(paced_sender_->TimeUntilSend(zero_time_).IsZero());
+  EXPECT_EQ(bandwidth_estimate / 500u,
+            paced_sender_->AvailableWindow(kMaxPacketSize * 100));
+  for (int i = 0; i < 16; ++i) {
+    paced_sender_->SentPacket(kMaxPacketSize);
+    EXPECT_TRUE(paced_sender_->TimeUntilSend(zero_time_).IsZero());
+  }
+  paced_sender_->SentPacket(kMaxPacketSize);
+  EXPECT_EQ(0u, paced_sender_->AvailableWindow(kMaxPacketSize * 100));
+  EXPECT_EQ(2040, paced_sender_->TimeUntilSend(zero_time_).ToMicroseconds());
+  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(20400));
+  EXPECT_TRUE(paced_sender_->TimeUntilSend(zero_time_).IsZero());
+  EXPECT_EQ(bandwidth_estimate / 500u,
+            paced_sender_->AvailableWindow(kMaxPacketSize * 100));
+}
+
 }  // namespace testing
 }  // namespace net
diff --git a/net/quic/congestion_control/quic_receipt_metrics_collector.cc b/net/quic/congestion_control/quic_receipt_metrics_collector.cc
index b99efc4..db97750 100644
--- a/net/quic/congestion_control/quic_receipt_metrics_collector.cc
+++ b/net/quic/congestion_control/quic_receipt_metrics_collector.cc
@@ -25,9 +25,9 @@
 void QuicReceiptMetricsCollector::RecordIncomingPacket(
     size_t bytes,
     QuicPacketSequenceNumber sequence_number,
-    uint64 timestamp_us,
+    QuicTime timestamp,
     bool revived) {
-  receive_algorithm_->RecordIncomingPacket(bytes, sequence_number, timestamp_us,
+  receive_algorithm_->RecordIncomingPacket(bytes, sequence_number, timestamp,
                                            revived);
 }
 
diff --git a/net/quic/congestion_control/quic_receipt_metrics_collector.h b/net/quic/congestion_control/quic_receipt_metrics_collector.h
index 5dff7d0..b627067 100644
--- a/net/quic/congestion_control/quic_receipt_metrics_collector.h
+++ b/net/quic/congestion_control/quic_receipt_metrics_collector.h
@@ -42,7 +42,7 @@
   // FEC packet.
   virtual void RecordIncomingPacket(size_t bytes,
                                     QuicPacketSequenceNumber sequence_number,
-                                    uint64 timestamp_us,
+                                    QuicTime timestamp,
                                     bool revived);
 
   // TODO(pwestin) Keep track of the number of FEC recovered packets.
diff --git a/net/quic/congestion_control/quic_receipt_metrics_collector_test.cc b/net/quic/congestion_control/quic_receipt_metrics_collector_test.cc
index 1388130..06fa05e3 100644
--- a/net/quic/congestion_control/quic_receipt_metrics_collector_test.cc
+++ b/net/quic/congestion_control/quic_receipt_metrics_collector_test.cc
@@ -23,7 +23,8 @@
 TEST_F(QuicReceiptMetricsCollectorTest, FixedRateReceiverAPI) {
   SetUpCongestionType(kFixRate);
   CongestionInfo info;
-  receiver_->RecordIncomingPacket(1, 1, 1, false);
+  QuicTime timestamp;
+  receiver_->RecordIncomingPacket(1, 1, timestamp, false);
   ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
   EXPECT_EQ(kFixRate, info.type);
 }
diff --git a/net/quic/congestion_control/quic_send_scheduler.cc b/net/quic/congestion_control/quic_send_scheduler.cc
index 5a621528..c500a70 100644
--- a/net/quic/congestion_control/quic_send_scheduler.cc
+++ b/net/quic/congestion_control/quic_send_scheduler.cc
@@ -24,6 +24,7 @@
     : clock_(clock),
       current_estimated_bandwidth_(-1),
       max_estimated_bandwidth_(-1),
+      last_sent_packet_(QuicTime::FromMicroseconds(0)),
       current_packet_bucket_(-1),
       first_packet_bucket_(-1),
       send_algorithm_(SendAlgorithmInterface::Create(clock, type)) {
@@ -36,9 +37,8 @@
 }
 
 int QuicSendScheduler::UpdatePacketHistory() {
-  uint64 now_us = clock_->NowInUsec();
-  int timestamp_scaled = now_us / kBitrateSmoothingPeriod;
-
+  int timestamp_scaled = clock_->Now().ToMicroseconds() /
+      kBitrateSmoothingPeriod;
   int bucket = timestamp_scaled % kBitrateSmoothingBuckets;
   if (!HasSentPacket()) {
     // First packet.
@@ -69,8 +69,8 @@
   packet_history_[bucket] += bytes;
   send_algorithm_->SentPacket(sequence_number, bytes, retransmit);
   if (!retransmit) {
-    pending_packets_[sequence_number] = new PendingPacket(bytes,
-                                                          clock_->NowInUsec());
+    pending_packets_[sequence_number] =
+        new PendingPacket(bytes, clock_->Now());
   }
   DLOG(INFO) << "Sent sequence number:" << sequence_number;
 }
@@ -84,7 +84,7 @@
   //   from pending_packets_.
   // * Remove all missing packets.
   // * Send each ACK in the list to send_algorithm_.
-  uint64 last_timestamp_us = 0;
+  QuicTime last_timestamp(QuicTime::FromMicroseconds(0));
   std::map<QuicPacketSequenceNumber, size_t> acked_packets;
 
   PendingPacketsMap::iterator it, it_upper;
@@ -99,7 +99,7 @@
       // Not missing, hence implicitly acked.
       scoped_ptr<PendingPacket> pending_packet_cleaner(it->second);
       acked_packets[sequence_number] = pending_packet_cleaner->BytesSent();
-      last_timestamp_us = pending_packet_cleaner->SendTimestamp();
+      last_timestamp = pending_packet_cleaner->SendTimestamp();
       pending_packets_.erase(it++);  // Must be incremented post to work.
     } else {
       ++it;
@@ -107,7 +107,7 @@
   }
   // We calculate the RTT based on the highest ACKed sequence number, the lower
   // sequence numbers will include the ACK aggregation delay.
-  uint64 rtt_us = clock_->NowInUsec() - last_timestamp_us;
+  QuicTime::Delta rtt = clock_->Now().Subtract(last_timestamp);
 
   std::map<QuicPacketSequenceNumber, size_t>::iterator it_acked_packets;
   for (it_acked_packets = acked_packets.begin();
@@ -115,12 +115,12 @@
       ++it_acked_packets) {
     send_algorithm_->OnIncomingAck(it_acked_packets->first,
                                    it_acked_packets->second,
-                                   rtt_us);
+                                   rtt);
     DLOG(INFO) << "ACKed sequence number:" << it_acked_packets->first;
   }
 }
 
-int QuicSendScheduler::TimeUntilSend(bool retransmit) {
+QuicTime::Delta QuicSendScheduler::TimeUntilSend(bool retransmit) {
   return send_algorithm_->TimeUntilSend(retransmit);
 }
 
diff --git a/net/quic/congestion_control/quic_send_scheduler.h b/net/quic/congestion_control/quic_send_scheduler.h
index 85ae524..3733007fe 100644
--- a/net/quic/congestion_control/quic_send_scheduler.h
+++ b/net/quic/congestion_control/quic_send_scheduler.h
@@ -19,6 +19,7 @@
 #include "net/quic/congestion_control/quic_receipt_metrics_collector.h"
 #include "net/quic/congestion_control/send_algorithm_interface.h"
 #include "net/quic/quic_clock.h"
+#include "net/quic/quic_time.h"
 
 namespace net {
 
@@ -32,16 +33,16 @@
  public:
   class PendingPacket {
    public:
-    PendingPacket(size_t bytes, uint64 timestamp_us)
+    PendingPacket(size_t bytes, QuicTime timestamp)
         : bytes_sent_(bytes),
-          send_timestamp_us_(timestamp_us) {
+          send_timestamp_(timestamp) {
     }
     size_t BytesSent() { return bytes_sent_; }
-    uint64 SendTimestamp() { return send_timestamp_us_; }
+    QuicTime& SendTimestamp() { return send_timestamp_; }
 
    private:
     size_t bytes_sent_;
-    uint64 send_timestamp_us_;
+    QuicTime send_timestamp_;
   };
   typedef std::map<QuicPacketSequenceNumber, PendingPacket*> PendingPacketsMap;
 
@@ -67,7 +68,7 @@
   // TimeUntilSend again until we receive an OnIncomingAckFrame event.
   // Note 2: Send algorithms may or may not use |retransmit| in their
   // calculations.
-  virtual int TimeUntilSend(bool retransmit);
+  virtual QuicTime::Delta TimeUntilSend(bool retransmit);
 
   // Returns the current available congestion window in bytes, the number of
   // bytes that can be sent now.
@@ -90,6 +91,7 @@
   const QuicClock* clock_;
   int current_estimated_bandwidth_;
   int max_estimated_bandwidth_;
+  QuicTime last_sent_packet_;
   // To keep track of the real sent bitrate we keep track of the last sent bytes
   // by keeping an array containing the number of bytes sent in a short timespan
   // kBitrateSmoothingPeriod; multiple of these buckets kBitrateSmoothingBuckets
diff --git a/net/quic/congestion_control/quic_send_scheduler_test.cc b/net/quic/congestion_control/quic_send_scheduler_test.cc
index 9af97a4d..ddfda158 100644
--- a/net/quic/congestion_control/quic_send_scheduler_test.cc
+++ b/net/quic/congestion_control/quic_send_scheduler_test.cc
@@ -2,18 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "net/quic/congestion_control/quic_send_scheduler.h"
-
-#include <cmath>
-
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "net/quic/congestion_control/quic_receipt_metrics_collector.h"
+#include "net/quic/congestion_control/quic_send_scheduler.h"
 #include "net/quic/test_tools/mock_clock.h"
 #include "net/quic/quic_protocol.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace net {
+namespace testing {
 
 class QuicSendSchedulerTest : public ::testing::Test {
  protected:
@@ -31,15 +30,17 @@
   ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 30000;
   sender_->OnIncomingAckFrame(ack);
   EXPECT_EQ(-1, sender_->PeakSustainedBandwidth());
-  EXPECT_EQ(0, sender_->TimeUntilSend(false));
+  EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
   EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
   sender_->SentPacket(1, kMaxPacketSize, false);
-  EXPECT_EQ(0u, sender_->AvailableCongestionWindow());
-  EXPECT_EQ(40000, sender_->TimeUntilSend(false));
-  clock_.AdvanceTime(0.035);
-  EXPECT_EQ(kUnknownWaitTime, sender_->TimeUntilSend(false));
-  clock_.AdvanceTime(0.005);
-  EXPECT_EQ(kUnknownWaitTime, sender_->TimeUntilSend(false));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
+            sender_->TimeUntilSend(false));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(35));
+  EXPECT_EQ(QuicTime::Delta::Infinite(),
+            sender_->TimeUntilSend(false));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_EQ(QuicTime::Delta::Infinite(),
+            sender_->TimeUntilSend(false));
 }
 
 TEST_F(QuicSendSchedulerTest, FixedRatePacing) {
@@ -49,32 +50,31 @@
   ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 100000;
   ack.received_info.largest_received = 0;
   sender_->OnIncomingAckFrame(ack);
-  double acc_advance_time = 0.0;
+  QuicTime acc_advance_time;
   for (int i = 0; i < 100; ++i) {
-    EXPECT_EQ(0, sender_->TimeUntilSend(false));
+    EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
     EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
     sender_->SentPacket(i, kMaxPacketSize, false);
-    double advance_time = sender_->TimeUntilSend(false) / 1000000.0;
+    QuicTime::Delta advance_time = sender_->TimeUntilSend(false);
     clock_.AdvanceTime(advance_time);
-    acc_advance_time += advance_time;
+    acc_advance_time = acc_advance_time.Add(advance_time);
     // Ack the packet we sent.
     ack.received_info.largest_received = i;
     sender_->OnIncomingAckFrame(ack);
   }
-  EXPECT_EQ(1200, floor((acc_advance_time * 1000) + 0.5));
+  EXPECT_EQ(QuicTime::FromMilliseconds(1200), acc_advance_time);
 }
 
-// TODO(rch): fix this on linux32
-TEST_F(QuicSendSchedulerTest, DISABLED_AvailableCongestionWindow) {
+TEST_F(QuicSendSchedulerTest, AvailableCongestionWindow) {
   SetUpCongestionType(kFixRate);
   QuicAckFrame ack;
   ack.congestion_info.type = kFixRate;
   ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 100000;
   sender_->OnIncomingAckFrame(ack);
-  EXPECT_EQ(0, sender_->TimeUntilSend(false));
+  EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
   EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
   for (int i = 1; i <= 12; i++) {
-    EXPECT_EQ(0, sender_->TimeUntilSend(false));
+    EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
     sender_->SentPacket(i, 100, false);
     EXPECT_EQ(kMaxPacketSize - (i * 100), sender_->AvailableCongestionWindow());
   }
@@ -91,9 +91,9 @@
   ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 100000;
   sender_->OnIncomingAckFrame(ack);
   for (int i = 0; i < 100; ++i) {
-    double advance_time = sender_->TimeUntilSend(false) / 1000000.0;
+    QuicTime::Delta advance_time = sender_->TimeUntilSend(false);
     clock_.AdvanceTime(advance_time);
-    EXPECT_EQ(0, sender_->TimeUntilSend(false));
+    EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
     EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
     sender_->SentPacket(i, 1000, false);
     // Ack the packet we sent.
@@ -112,8 +112,8 @@
   ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 100000;
   sender_->OnIncomingAckFrame(ack);
   for (int i = 0; i < 100; ++i) {
-    clock_.AdvanceTime(0.010);
-    EXPECT_EQ(0, sender_->TimeUntilSend(false));
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+    EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
     EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
     sender_->SentPacket(i, 1000, false);
     // Ack the packet we sent.
@@ -123,17 +123,17 @@
   EXPECT_EQ(100000, sender_->BandwidthEstimate());
   EXPECT_EQ(100000, sender_->PeakSustainedBandwidth());
   EXPECT_EQ(100000, sender_->SentBandwidth());
-  clock_.AdvanceTime(1.0);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
   EXPECT_EQ(50000, sender_->SentBandwidth());
-  clock_.AdvanceTime(2.1);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2100));
   EXPECT_EQ(100000, sender_->BandwidthEstimate());
   EXPECT_EQ(100000, sender_->PeakSustainedBandwidth());
   EXPECT_EQ(0, sender_->SentBandwidth());
   for (int i = 0; i < 150; ++i) {
-    EXPECT_EQ(0, sender_->TimeUntilSend(false));
+    EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
     EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
     sender_->SentPacket(i + 100, 1000, false);
-    clock_.AdvanceTime(0.010);
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
     // Ack the packet we sent.
     ack.received_info.largest_received = i + 100;
     sender_->OnIncomingAckFrame(ack);
@@ -151,23 +151,24 @@
   ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 1000000;
   ack.received_info.largest_received = 0;
   sender_->OnIncomingAckFrame(ack);
-  double acc_advance_time = 0.0;
+  QuicTime acc_advance_time;
   for (int i = 0; i < 100;) {
-    EXPECT_EQ(0, sender_->TimeUntilSend(false));
+    EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
     EXPECT_EQ(kMaxPacketSize * 2, sender_->AvailableCongestionWindow());
     sender_->SentPacket(i++, kMaxPacketSize, false);
-    EXPECT_EQ(0, sender_->TimeUntilSend(false));
+    EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
     sender_->SentPacket(i++, kMaxPacketSize, false);
-    double advance_time = sender_->TimeUntilSend(false) / 1000000.0;
+    QuicTime::Delta advance_time = sender_->TimeUntilSend(false);
     clock_.AdvanceTime(advance_time);
-    acc_advance_time += advance_time;
+    acc_advance_time = acc_advance_time.Add(advance_time);
     // Ack the packets we sent.
     ack.received_info.largest_received = i - 2;
     sender_->OnIncomingAckFrame(ack);
     ack.received_info.largest_received = i - 1;
     sender_->OnIncomingAckFrame(ack);
   }
-  EXPECT_EQ(120, floor((acc_advance_time * 1000) + 0.5));
+  EXPECT_EQ(QuicTime::FromMilliseconds(120), acc_advance_time);
 }
 
+}  // namespace testing
 }  // namespace net
diff --git a/net/quic/congestion_control/receive_algorithm_interface.h b/net/quic/congestion_control/receive_algorithm_interface.h
index e8a1dbc..e0c0713 100644
--- a/net/quic/congestion_control/receive_algorithm_interface.h
+++ b/net/quic/congestion_control/receive_algorithm_interface.h
@@ -11,6 +11,7 @@
 #include "net/base/net_export.h"
 #include "net/quic/quic_clock.h"
 #include "net/quic/quic_protocol.h"
+#include "net/quic/quic_time.h"
 
 namespace net {
 
@@ -28,12 +29,12 @@
   // Should be called for each incoming packet.
   // bytes: is the packet size in bytes including IP headers.
   // sequence_number: is the unique sequence number from the QUIC packet header.
-  // timestamp_us: is the sent timestamp from the QUIC packet header.
+  // timestamp: is the sent timestamp from the QUIC packet header.
   // revived: is set if the packet is lost and then recovered with help of FEC
   // (Forward Error Correction) packet(s).
   virtual void RecordIncomingPacket(size_t bytes,
                                     QuicPacketSequenceNumber sequence_number,
-                                    uint64 timestamp_us,
+                                    QuicTime timestamp,
                                     bool revived) = 0;
 };
 
diff --git a/net/quic/congestion_control/send_algorithm_interface.h b/net/quic/congestion_control/send_algorithm_interface.h
index b263354..b42e678 100644
--- a/net/quic/congestion_control/send_algorithm_interface.h
+++ b/net/quic/congestion_control/send_algorithm_interface.h
@@ -11,11 +11,11 @@
 #include "net/base/net_export.h"
 #include "net/quic/quic_clock.h"
 #include "net/quic/quic_protocol.h"
+#include "net/quic/quic_time.h"
 
 namespace net {
 
 const int kNoValidEstimate = -1;
-const int kUnknownWaitTime = -1;
 
 class NET_EXPORT_PRIVATE SendAlgorithmInterface {
  public:
@@ -31,7 +31,7 @@
   // Called for each received ACK, with sequence number from remote peer.
   virtual void OnIncomingAck(QuicPacketSequenceNumber acked_sequence_number,
                              size_t acked_bytes,
-                             uint64 rtt_us) = 0;
+                             QuicTime::Delta rtt) = 0;
 
   virtual void OnIncomingLoss(int number_of_lost_packets) = 0;
 
@@ -44,7 +44,7 @@
   // Calculate the time until we can send the next packet.
   // Usage: When this returns 0, CongestionWindow returns the number of bytes
   // of the congestion window.
-  virtual int TimeUntilSend(bool retransmit) = 0;
+  virtual QuicTime::Delta TimeUntilSend(bool retransmit) = 0;
 
   // The current available congestion window in bytes.
   virtual size_t AvailableCongestionWindow() = 0;
diff --git a/net/quic/quic_clock.cc b/net/quic/quic_clock.cc
index 909ddd5..e6bd5e2 100644
--- a/net/quic/quic_clock.cc
+++ b/net/quic/quic_clock.cc
@@ -13,9 +13,8 @@
 
 QuicClock::~QuicClock() {}
 
-uint64 QuicClock::NowInUsec() const {
-  base::TimeDelta delta = base::Time::Now() - base::Time::UnixEpoch();
-  return delta.InMicroseconds();
+QuicTime QuicClock::Now() const {
+  return QuicTime(base::TimeTicks::Now());
 }
 
 }  // namespace net
diff --git a/net/quic/quic_clock.h b/net/quic/quic_clock.h
index c585c73c..5bc5f97 100644
--- a/net/quic/quic_clock.h
+++ b/net/quic/quic_clock.h
@@ -7,6 +7,7 @@
 
 #include "base/basictypes.h"
 #include "net/base/net_export.h"
+#include "net/quic/quic_time.h"
 
 namespace net {
 
@@ -19,9 +20,8 @@
   QuicClock();
   virtual ~QuicClock();
 
-  // Returns the approximate current time as the number of microseconds
-  // since the Unix epoch.
-  virtual uint64 NowInUsec() const;
+  // Returns the approximate current time as a QuicTime object.
+  virtual QuicTime Now() const;
 };
 
 }  // namespace net
diff --git a/net/quic/quic_clock_test.cc b/net/quic/quic_clock_test.cc
new file mode 100644
index 0000000..f47567e
--- /dev/null
+++ b/net/quic/quic_clock_test.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/quic_clock.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace test {
+
+TEST(QuicClockTest, Now) {
+  QuicClock clock;
+
+  QuicTime start(base::TimeTicks::Now());
+  QuicTime now = clock.Now();
+  QuicTime end(base::TimeTicks::Now());
+
+  EXPECT_LE(start, now);
+  EXPECT_GE(now, end);
+}
+
+}  // namespace test
+
+}  // namespace net
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index 8ab8deb..7933c03 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -21,13 +21,6 @@
 using std::vector;
 using std::set;
 
-/*
-DEFINE_int32(fake_packet_loss_percentage, 0,
-            "The percentage of packets to drop.");
-DEFINE_int32(negotiated_timeout_us, net::kDefaultTimeout,
-             "The default timeout for connections being closed");
-*/
-
 namespace net {
 
 // An arbitrary number we'll probably want to tune.
@@ -53,18 +46,17 @@
       least_packet_awaiting_ack_(0),
       write_blocked_(false),
       packet_creator_(guid_, &framer_),
-      timeout_us_(kDefaultTimeout),
-      time_of_last_packet_us_(clock_->NowInUsec()),
+      timeout_(QuicTime::Delta::FromMicroseconds(kDefaultTimeoutUs)),
+      time_of_last_packet_(clock_->Now()),
       collector_(new QuicReceiptMetricsCollector(clock_, kFixRate)),
       scheduler_(new QuicSendScheduler(clock_, kFixRate)),
       connected_(true) {
   helper_->SetConnection(this);
-  helper_->SetTimeoutAlarm(timeout_us_);
+  helper_->SetTimeoutAlarm(timeout_);
   framer_.set_visitor(this);
   memset(&last_header_, 0, sizeof(last_header_));
   outgoing_ack_.sent_info.least_unacked = 0;
   outgoing_ack_.received_info.largest_received = 0;
-  outgoing_ack_.received_info.time_received = 0;
   outgoing_ack_.congestion_info.type = kNone;
   /*
   if (FLAGS_fake_packet_loss_percentage > 0) {
@@ -92,8 +84,8 @@
 
 void QuicConnection::OnPacket(const IPEndPoint& self_address,
                               const IPEndPoint& peer_address) {
-  time_of_last_packet_us_ = clock_->NowInUsec();
-  DVLOG(1) << "last packet: " << time_of_last_packet_us_;
+  time_of_last_packet_ = clock_->Now();
+  DVLOG(1) << "last packet: " << time_of_last_packet_.ToMicroseconds();
 
   // TODO(alyssar, rch) handle migration!
   self_address_ = self_address;
@@ -154,16 +146,17 @@
   if (queued_packets_.empty()) {
     return;
   }
-    int delay = scheduler_->TimeUntilSend(false);
-    if (delay == 0) {
-      helper_->UnregisterSendAlarmIfRegistered();
-      if (!write_blocked_) {
-        OnCanWrite();
-      }
-    } else {
-      helper_->SetSendAlarm(delay);
+
+  QuicTime::Delta delay = scheduler_->TimeUntilSend(false);
+  if (delay.IsZero()) {
+    helper_->UnregisterSendAlarmIfRegistered();
+    if (!write_blocked_) {
+      OnCanWrite();
     }
+  } else {
+    helper_->SetSendAlarm(delay);
   }
+}
 
 bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
   if (incoming_ack.received_info.largest_received >
@@ -310,7 +303,7 @@
                << " frames for " << last_header_.guid;
     collector_->RecordIncomingPacket(last_size_,
                                      last_header_.packet_sequence_number,
-                                     clock_->NowInUsec(),
+                                     clock_->Now(),
                                      last_packet_revived_);
   } else {
     DLOG(INFO) << "Got revived packet with " << frames_.size();
@@ -410,7 +403,7 @@
       outgoing_ack_.received_info.missing_packets.insert(i);
     }
     outgoing_ack_.received_info.largest_received = sequence_number;
-    outgoing_ack_.received_info.time_received = clock_->NowInUsec();
+    outgoing_ack_.received_info.time_received = clock_->Now();
   } else {
     // We've gotten one of the out of order packets - remove it from our
     // "missing packets" list.
@@ -459,9 +452,10 @@
       return false;
     }
 
-    int delay = scheduler_->TimeUntilSend(should_resend);
+    QuicTime::Delta delay = scheduler_->TimeUntilSend(should_resend);
     // If the scheduler requires a delay, then we can not send this packet now.
-    if (delay > 0) {
+    if (!delay.IsZero() && !delay.IsInfinite()) {
+      // TODO(pwestin): we need to handle delay.IsInfinite() seperately.
       helper_->SetSendAlarm(delay);
       queued_packets_.push_back(
           QueuedPacket(sequence_number, packet, should_resend, is_retransmit));
@@ -469,7 +463,7 @@
     }
   }
   if (should_resend) {
-    helper_->SetResendAlarm(sequence_number, kDefaultResendTimeMs * 1000);
+    helper_->SetResendAlarm(sequence_number, DefaultResendTime());
     // The second case should never happen in the real world, but does here
     // because we sometimes send out of order to validate corner cases.
     if (outgoing_ack_.sent_info.least_unacked == 0 ||
@@ -484,7 +478,7 @@
   }
 
   // Just before we send the packet to the wire, update the transmission time.
-  framer_.WriteTransmissionTime(clock_->NowInUsec(), packet);
+  framer_.WriteTransmissionTime(clock_->Now(), packet);
 
   scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(*packet));
   int error;
@@ -502,8 +496,8 @@
     }
   }
 
-  time_of_last_packet_us_ = clock_->NowInUsec();
-  DVLOG(1) << "last packet: " << time_of_last_packet_us_;
+  time_of_last_packet_ = clock_->Now();
+  DVLOG(1) << "last packet: " << time_of_last_packet_.ToMicroseconds();
 
   scheduler_->SentPacket(sequence_number, packet->length(), is_retransmit);
   if (!should_resend) delete packet;
@@ -595,16 +589,16 @@
 }
 
 bool QuicConnection::CheckForTimeout() {
-  uint64 now_in_us = clock_->NowInUsec();
-  uint64 delta_in_us = now_in_us - time_of_last_packet_us_;
-  DVLOG(1) << "last_packet " << time_of_last_packet_us_
-           << " now:" << now_in_us
-           << " delta:" << delta_in_us;
-  if (delta_in_us >= timeout_us_) {
+  QuicTime now = clock_->Now();
+  QuicTime::Delta delta = now.Subtract(time_of_last_packet_);
+  DVLOG(1) << "last_packet " << time_of_last_packet_.ToMicroseconds()
+           << " now:" << now.ToMicroseconds()
+           << " delta:" << delta.ToMicroseconds();
+  if (delta >= timeout_) {
     SendConnectionClose(QUIC_CONNECTION_TIMED_OUT);
     return true;
   }
-  helper_->SetTimeoutAlarm(timeout_us_ - delta_in_us);
+  helper_->SetTimeoutAlarm(timeout_.Subtract(delta));
   return false;
 }
 
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index ac65703..7dd7fa6f 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -81,17 +81,17 @@
   // invoke MaybeResendPacket when the alarm fires.  Implementations must also
   // handle the case where |this| is deleted before the alarm fires.
   virtual void SetResendAlarm(QuicPacketSequenceNumber sequence_number,
-                              uint64 delay_in_us) = 0;
+                              QuicTime::Delta delay) = 0;
 
   // Sets an alarm to send packets after |delay_in_us|.  Implementations must
   // invoke OnCanWrite when the alarm fires.  Implementations must also
   // handle the case where |this| is deleted before the alarm fires.
-  virtual void SetSendAlarm(uint64 delay_in_us) = 0;
+  virtual void SetSendAlarm(QuicTime::Delta delay) = 0;
 
   // Sets An alarm which fires when the connection may have timed out.
   // Implementations must call CheckForTimeout() and then reregister the alarm
   // if the connection has not yet timed out.
-  virtual void SetTimeoutAlarm(uint64 delay_in_us) = 0;
+  virtual void SetTimeoutAlarm(QuicTime::Delta delay) = 0;
 
   // Returns true if a send alarm is currently set.
   virtual bool IsSendAlarmSet() = 0;
@@ -234,6 +234,11 @@
       QuicPacket*> UnackedPacketMap;
   typedef std::map<QuicFecGroupNumber, QuicFecGroup*> FecGroupMap;
 
+  // The amount of time we wait before resending a packet.
+  static const QuicTime::Delta DefaultResendTime() {
+    return QuicTime::Delta::FromMilliseconds(500);
+  }
+
   // Sets up a packet with an QuicAckFrame and sends it out.
   void SendAck();
 
@@ -293,11 +298,10 @@
   QuicConnectionVisitorInterface* visitor_;
   QuicPacketCreator packet_creator_;
 
-  // The number of usec of idle network before we kill of this connection.
-  uint64 timeout_us_;
-  // The time (since the epoch) that we got or tried to send a packet for this
-  // connection.
-  uint64 time_of_last_packet_us_;
+  // Network idle time before we kill of this connection.
+  const QuicTime::Delta timeout_;
+  // The time that we got or tried to send a packet for this connection.
+  QuicTime time_of_last_packet_;
 
   scoped_ptr<QuicReceiptMetricsCollector> collector_;
 
diff --git a/net/quic/quic_connection_helper.cc b/net/quic/quic_connection_helper.cc
index 0348f9e..40d5dcf 100644
--- a/net/quic/quic_connection_helper.cc
+++ b/net/quic/quic_connection_helper.cc
@@ -56,33 +56,33 @@
 
 void QuicConnectionHelper::SetResendAlarm(
     QuicPacketSequenceNumber sequence_number,
-    uint64 delay_in_us) {
+    QuicTime::Delta delay) {
   // TODO(rch): Coalesce these alarms.
   task_runner_->PostDelayedTask(
       FROM_HERE,
       base::Bind(&QuicConnectionHelper::OnResendAlarm,
                  weak_factory_.GetWeakPtr(), sequence_number),
-      base::TimeDelta::FromMicroseconds(delay_in_us));
+      base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
 }
 
-void QuicConnectionHelper::SetSendAlarm(uint64 delay_in_us) {
+void QuicConnectionHelper::SetSendAlarm(QuicTime::Delta delay) {
   DCHECK(!send_alarm_registered_);
   send_alarm_registered_ = true;
   task_runner_->PostDelayedTask(
       FROM_HERE,
       base::Bind(&QuicConnectionHelper::OnSendAlarm,
                  weak_factory_.GetWeakPtr()),
-      base::TimeDelta::FromMicroseconds(delay_in_us));
+      base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
 }
 
-void QuicConnectionHelper::SetTimeoutAlarm(uint64 delay_in_us) {
+void QuicConnectionHelper::SetTimeoutAlarm(QuicTime::Delta delay) {
   DCHECK(!timeout_alarm_registered_);
   timeout_alarm_registered_ = true;
   task_runner_->PostDelayedTask(
       FROM_HERE,
       base::Bind(&QuicConnectionHelper::OnTimeoutAlarm,
                  weak_factory_.GetWeakPtr()),
-      base::TimeDelta::FromMicroseconds(delay_in_us));
+      base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
 }
 
 bool QuicConnectionHelper::IsSendAlarmSet() {
diff --git a/net/quic/quic_connection_helper.h b/net/quic/quic_connection_helper.h
index 7468760..2bd5f90 100644
--- a/net/quic/quic_connection_helper.h
+++ b/net/quic/quic_connection_helper.h
@@ -16,6 +16,7 @@
 #include "net/base/ip_endpoint.h"
 #include "net/quic/quic_clock.h"
 #include "net/quic/quic_protocol.h"
+#include "net/quic/quic_time.h"
 #include "net/udp/datagram_client_socket.h"
 
 namespace base {
@@ -30,6 +31,7 @@
   QuicConnectionHelper(base::TaskRunner* task_runner,
                        QuicClock* clock,
                        DatagramClientSocket* socket);
+
   virtual ~QuicConnectionHelper();
 
   // QuicConnectionHelperInterface
@@ -40,9 +42,9 @@
                                 bool resend,
                                 int* error) OVERRIDE;
   virtual void SetResendAlarm(QuicPacketSequenceNumber sequence_number,
-                              uint64 delay_in_us) OVERRIDE;
-  virtual void SetSendAlarm(uint64 delay_in_us) OVERRIDE;
-  virtual void SetTimeoutAlarm(uint64 delay_in_us) OVERRIDE;
+                              QuicTime::Delta delay) OVERRIDE;
+  virtual void SetSendAlarm(QuicTime::Delta delay) OVERRIDE;
+  virtual void SetTimeoutAlarm(QuicTime::Delta delay) OVERRIDE;
   virtual bool IsSendAlarmSet() OVERRIDE;
   virtual void UnregisterSendAlarmIfRegistered() OVERRIDE;
 
diff --git a/net/quic/quic_connection_helper_test.cc b/net/quic/quic_connection_helper_test.cc
index b965563..3a076a6 100644
--- a/net/quic/quic_connection_helper_test.cc
+++ b/net/quic/quic_connection_helper_test.cc
@@ -106,6 +106,8 @@
         frame1_(1, false, 0, data1) {
     connection_.set_visitor(&visitor_);
     connection_.SetScheduler(scheduler_);
+    EXPECT_CALL(*scheduler_, TimeUntilSend(_)).WillRepeatedly(testing::Return(
+        QuicTime::Delta()));
   }
 
   QuicPacket* ConstructDataPacket(QuicPacketSequenceNumber number,
@@ -151,12 +153,12 @@
 }
 
 TEST_F(QuicConnectionHelperTest, SetSendAlarm) {
-  helper_->SetSendAlarm(0);
+  helper_->SetSendAlarm(QuicTime::Delta());
   EXPECT_TRUE(helper_->IsSendAlarmSet());
 }
 
 TEST_F(QuicConnectionHelperTest, UnregisterSendAlarmIfRegistered) {
-  helper_->SetSendAlarm(0);
+  helper_->SetSendAlarm(QuicTime::Delta());
   helper_->UnregisterSendAlarmIfRegistered() ;
   EXPECT_FALSE(helper_->IsSendAlarmSet());
 }
@@ -177,24 +179,24 @@
 TEST_F(QuicConnectionHelperTest, InitialTimeout) {
   // Verify that a single task was posted.
   EXPECT_EQ(1u, runner_->tasks()->size());
-  EXPECT_EQ(base::TimeDelta::FromMicroseconds(kDefaultTimeout),
+  EXPECT_EQ(base::TimeDelta::FromMicroseconds(kDefaultTimeoutUs),
             runner_->GetTask(0).delta);
 
   // After we run the next task, we should close the connection.
   EXPECT_CALL(visitor_, ConnectionClose(QUIC_CONNECTION_TIMED_OUT, false));
 
   runner_->RunNextTask();
-  EXPECT_EQ(kDefaultTimeout, clock_.NowInUsec());
+  EXPECT_EQ(QuicTime::FromMicroseconds(kDefaultTimeoutUs), clock_.Now());
   EXPECT_FALSE(connection_.connected());
 }
 
 TEST_F(QuicConnectionHelperTest, TimeoutAfterSend) {
   EXPECT_TRUE(connection_.connected());
-  EXPECT_EQ(0u, clock_.NowInUsec());
+  EXPECT_EQ(0u, clock_.Now().ToMicroseconds());
 
   // When we send a packet, the timeout will change to 5000 + kDefaultTimeout.
-  clock_.AdvanceTimeInMicroseconds(5000);
-  EXPECT_EQ(5000u, clock_.NowInUsec());
+  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(5000));
+  EXPECT_EQ(5000u, clock_.Now().ToMicroseconds());
 
   // Send an ack so we don't set the resend alarm.
   connection_.SendAck();
@@ -203,19 +205,20 @@
   // network event at t=5000.  The alarm will reregister.
   runner_->RunNextTask();
 
-  EXPECT_EQ(kDefaultTimeout, clock_.NowInUsec());
+  EXPECT_EQ(QuicTime::FromMicroseconds(kDefaultTimeoutUs), clock_.Now());
 
   // This time, we should time out.
   EXPECT_CALL(visitor_, ConnectionClose(QUIC_CONNECTION_TIMED_OUT, false));
   runner_->RunNextTask();
-  EXPECT_EQ(kDefaultTimeout + 5000, clock_.NowInUsec());
+  EXPECT_EQ(uint64(kDefaultTimeoutUs + 5000), clock_.Now().ToMicroseconds());
   EXPECT_FALSE(connection_.connected());
 }
 
 TEST_F(QuicConnectionHelperTest, SendSchedulerDelayThenSend) {
   // Test that if we send a packet with a delay, it ends up queued.
   scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta::FromMicroseconds(1)));
 
   bool should_resend = true;
   bool force = false;
@@ -225,7 +228,8 @@
 
   // Advance the clock to fire the alarm, and configure the scheduler
   // to permit the packet to be sent.
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(0));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta()));
   runner_->RunNextTask();
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
 }
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index 3f2d7f7..862c806 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -64,7 +64,7 @@
   }
 
   MOCK_METHOD4(RecordIncomingPacket,
-               void(size_t, QuicPacketSequenceNumber, uint64, bool));
+               void(size_t, QuicPacketSequenceNumber, QuicTime, bool));
 
  private:
   MockClock clock_;
@@ -77,8 +77,6 @@
  public:
   TestConnectionHelper(MockClock* clock)
       : clock_(clock),
-        send_alarm_(0),
-        timeout_alarm_(0),
         blocked_(false) {
   }
 
@@ -108,31 +106,31 @@
   }
 
   virtual void SetResendAlarm(QuicPacketSequenceNumber sequence_number,
-                              uint64 delay_in_us) {
-    resend_alarms_[sequence_number] = clock_->NowInUsec() + delay_in_us;
+                              QuicTime::Delta delay) {
+    resend_alarms_[sequence_number] = clock_->Now().Add(delay);
   }
 
-  virtual void SetSendAlarm(uint64 delay_in_us) {
-    send_alarm_ = clock_->NowInUsec() + delay_in_us;
+  virtual void SetSendAlarm(QuicTime::Delta delay) {
+    send_alarm_ = clock_->Now().Add(delay);
   }
 
-  virtual void SetTimeoutAlarm(uint64 delay_in_us) {
-    timeout_alarm_ = clock_->NowInUsec() + delay_in_us;
+  virtual void SetTimeoutAlarm(QuicTime::Delta delay) {
+    timeout_alarm_ = clock_->Now().Add(delay);
   }
 
   virtual bool IsSendAlarmSet() {
-    return send_alarm_ > clock_->NowInUsec();
+    return send_alarm_ > clock_->Now();
   }
 
   virtual void UnregisterSendAlarmIfRegistered() {
-    send_alarm_ = 0;
+    send_alarm_ = QuicTime();
   }
 
-  const map<QuicPacketSequenceNumber, uint64>& resend_alarms() const {
+  const map<QuicPacketSequenceNumber, QuicTime>& resend_alarms() const {
     return resend_alarms_;
   }
 
-  uint64 timeout_alarm() const { return timeout_alarm_; }
+  QuicTime timeout_alarm() const { return timeout_alarm_; }
 
   QuicPacketHeader* header() { return &header_; }
 
@@ -142,9 +140,9 @@
 
  private:
   MockClock* clock_;
-  map<QuicPacketSequenceNumber, uint64> resend_alarms_;
-  uint64 send_alarm_;
-  uint64 timeout_alarm_;
+  map<QuicPacketSequenceNumber, QuicTime> resend_alarms_;
+  QuicTime send_alarm_;
+  QuicTime timeout_alarm_;
   QuicPacketHeader header_;
   QuicAckFrame frame_;
   bool blocked_;
@@ -199,7 +197,8 @@
         accept_packet_(true) {
     connection_.set_visitor(&visitor_);
     connection_.SetScheduler(scheduler_);
-    EXPECT_CALL(*scheduler_, TimeUntilSend(_)).WillRepeatedly(Return(0));
+    EXPECT_CALL(*scheduler_, TimeUntilSend(_)).WillRepeatedly(Return(
+        QuicTime::Delta()));
   }
 
   QuicAckFrame* last_frame() {
@@ -282,7 +281,7 @@
   }
 
   void SendAckPacket(QuicPacketSequenceNumber least_unacked) {
-    QuicAckFrame frame(0, 0, least_unacked);
+    QuicAckFrame frame(0, QuicTime(), least_unacked);
     SendAckPacket(&frame);
   }
 
@@ -399,7 +398,7 @@
   // Now send non-resending information, that we're not going to resend 3.
   // The far end should stop waiting for it.
   QuicPacketSequenceNumber largest_received = 0;
-  QuicTransmissionTime time_received = 0;
+  QuicTime time_received;
   QuicPacketSequenceNumber least_unacked = 1;
   QuicAckFrame frame(largest_received, time_received, least_unacked);
   frame.sent_info.non_retransmiting.insert(3);
@@ -444,7 +443,7 @@
   // The far end should stop waiting for it.
   // In sending the ack, we also have sent packet 1, so we'll stop waiting for
   // that as well.
-  QuicAckFrame frame(0, 0, 1);
+  QuicAckFrame frame(0, QuicTime(), 1);
   frame.sent_info.non_retransmiting.insert(4);
   SendAckPacket(&frame);
   // Force an ack to be sent.
@@ -475,7 +474,7 @@
   // packet the peer will not retransmit.  It indicates this by sending 'least
   // awaiting' is 4.  The connection should then realize 1 will not be
   // retransmitted, and will remove it from the missing list.
-  QuicAckFrame frame(0, 0, 4);
+  QuicAckFrame frame(0, QuicTime(), 4);
   SendAckPacket(&frame);
   // Force an ack to be sent.
   connection_.SendAck();
@@ -499,13 +498,13 @@
 
   // Start out saying the least unacked is 2
   creator_.set_sequence_number(5);
-  QuicAckFrame frame(0, 0, 2);
+  QuicAckFrame frame(0, QuicTime(), 2);
   SendAckPacket(&frame);
 
   // Change it to 1, but lower the sequence number to fake out-of-order packets.
   // This should be fine.
   creator_.set_sequence_number(1);
-  QuicAckFrame frame2(0, 0, 1);
+  QuicAckFrame frame2(0, QuicTime(), 1);
   SendAckPacket(&frame2);
 
   // Now claim it's one, but set the ordering so it was sent "after" the first
@@ -518,7 +517,7 @@
 TEST_F(QuicConnectionTest, AckUnsentData) {
   // Ack a packet which has not been sent.
   EXPECT_CALL(visitor_, ConnectionClose(QUIC_INVALID_ACK_DATA, false));
-  QuicAckFrame frame(1, 0, 0);
+  QuicAckFrame frame(1, QuicTime(), 0);
   SendAckPacket(&frame);
 }
 
@@ -526,12 +525,12 @@
   ProcessPacket(1);
 
   creator_.set_sequence_number(1);
-  QuicAckFrame frame1(1, 0, 1);
+  QuicAckFrame frame1(1, QuicTime(), 1);
   SendAckPacket(&frame1);
 
   // Send an ack with least_unacked == 0, which indicates that all packets
   // we have sent have been acked.
-  QuicAckFrame frame2(1, 0, 0);
+  QuicAckFrame frame2(1, QuicTime(), 0);
   SendAckPacket(&frame2);
 }
 
@@ -543,7 +542,7 @@
   connection_.SendStreamData(1, "foo", 0, false, NULL);
 
   EXPECT_CALL(visitor_, ConnectionClose(QUIC_PACKET_TOO_LARGE, false));
-  QuicAckFrame frame(1, 0, 0);
+  QuicAckFrame frame(1, QuicTime(), 0);
   for (int i = 0; i < 5001; ++i) {
     frame.received_info.missing_packets.insert(i);
   }
@@ -555,7 +554,7 @@
   connection_.SendStreamData(1, "foo", 0, false, NULL);
 
   EXPECT_CALL(visitor_, ConnectionClose(QUIC_PACKET_TOO_LARGE, false));
-  QuicAckFrame frame(1, 0, 0);
+  QuicAckFrame frame(1, QuicTime(), 0);
   for (int i = 0; i < 5001; ++i) {
     frame.sent_info.non_retransmiting.insert(i);
   }
@@ -588,7 +587,7 @@
 
   // Client acks up to packet 3
   EXPECT_CALL(visitor_, OnAck(ContainerEq(expected_acks)));
-  QuicAckFrame frame(3, 0, 0);
+  QuicAckFrame frame(3, QuicTime(), 0);
   SendAckPacket(&frame);
   connection_.SendAck();  // Packet 6
 
@@ -603,7 +602,7 @@
 
   // Client acks up to packet 4, the last packet
   EXPECT_CALL(visitor_, OnAck(ContainerEq(expected_acks)));
-  QuicAckFrame frame2(6, 0, 0);
+  QuicAckFrame frame2(6, QuicTime(), 0);
   SendAckPacket(&frame2);
   connection_.SendAck();  // Packet 7
 
@@ -639,7 +638,7 @@
   EXPECT_EQ(6u, last_packet);
 
   // Client will acks packets 1, [!2], 3, 4, 5
-  QuicAckFrame frame1(5, 0, 0);
+  QuicAckFrame frame1(5, QuicTime(), 0);
   frame1.received_info.missing_packets.insert(2);
 
   // The connection should pass up acks for 1, 4, 5.  2 is not acked, and 3 was
@@ -653,7 +652,7 @@
   SendAckPacket(&frame1);
 
   // Now the client implicitly acks 2, and explicitly acks 6
-  QuicAckFrame frame2(6, 0, 0);
+  QuicAckFrame frame2(6, QuicTime(), 0);
   expected_acks.clear();
   // Both acks should be passed up.
   expected_acks.insert(2);
@@ -699,19 +698,22 @@
 TEST_F(QuicConnectionTest, TestResend) {
   // TODO(rch): make this work
   // FLAGS_fake_packet_loss_percentage = 100;
-  const uint64 kDefaultResendTimeMs = 500u;
+  const QuicTime::Delta kDefaultResendTime =
+      QuicTime::Delta::FromMilliseconds(500);
+
+  QuicTime default_resend_time = clock_.Now().Add(kDefaultResendTime);
 
   connection_.SendStreamData(1, "foo", 0, false, NULL);
   EXPECT_EQ(1u, last_header()->packet_sequence_number);
   EXPECT_EQ(0u, last_header()->transmission_time);
   EXPECT_EQ(1u, helper_->resend_alarms().size());
-  EXPECT_EQ(kDefaultResendTimeMs * 1000,
+  EXPECT_EQ(default_resend_time,
             helper_->resend_alarms().find(1)->second);
   // Simulate the resend alarm firing
-  clock_.AdvanceTimeInMicroseconds(kDefaultResendTimeMs * 1000);
+  clock_.AdvanceTime(kDefaultResendTime);
   connection_.MaybeResendPacket(1);
   EXPECT_EQ(2u, last_header()->packet_sequence_number);
-  EXPECT_EQ(kDefaultResendTimeMs * 1000,
+  EXPECT_EQ(default_resend_time.ToMicroseconds(),
             last_header()->transmission_time);
 }
 
@@ -785,10 +787,12 @@
   EXPECT_TRUE(connection_.connected());
   EXPECT_CALL(visitor_, ConnectionClose(QUIC_CONNECTION_TIMED_OUT, false));
 
-  EXPECT_EQ(kDefaultTimeout, helper_->timeout_alarm());
+  QuicTime default_timeout = clock_.Now().Add(
+      QuicTime::Delta::FromMicroseconds(kDefaultTimeoutUs));
+  EXPECT_EQ(default_timeout, helper_->timeout_alarm());
 
   // Simulate the timeout alarm firing
-  clock_.AdvanceTimeInMicroseconds(kDefaultTimeout);
+  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(kDefaultTimeoutUs));
   EXPECT_TRUE(connection_.CheckForTimeout());
   EXPECT_FALSE(connection_.connected());
 }
@@ -796,25 +800,31 @@
 TEST_F(QuicConnectionTest, TimeoutAfterSend) {
   EXPECT_TRUE(connection_.connected());
 
+  QuicTime default_timeout = clock_.Now().Add(
+      QuicTime::Delta::FromMicroseconds(kDefaultTimeoutUs));
+
   // When we send a packet, the timeout will change to 5000 + kDefaultTimeout.
-  clock_.AdvanceTimeInMicroseconds(5000);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+
   // Send an ack so we don't set the resend alarm.
   connection_.SendAck();
-
-  EXPECT_EQ(kDefaultTimeout, helper_->timeout_alarm());
+  EXPECT_EQ(default_timeout, helper_->timeout_alarm());
 
   // The original alarm will fire.  We should not time out because we had a
   // network event at t=5000.  The alarm will reregister.
-  clock_.AdvanceTimeInMicroseconds(kDefaultTimeout - 5000);
-  EXPECT_EQ(kDefaultTimeout, clock_.NowInUsec());
+  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(
+      kDefaultTimeoutUs - 5000));
+  EXPECT_EQ(default_timeout, clock_.Now());
   EXPECT_FALSE(connection_.CheckForTimeout());
   EXPECT_TRUE(connection_.connected());
-  EXPECT_EQ(kDefaultTimeout + 5000, helper_->timeout_alarm());
+  EXPECT_EQ(default_timeout.Add(QuicTime::Delta::FromMilliseconds(5)),
+            helper_->timeout_alarm());
 
   // This time, we should time out.
   EXPECT_CALL(visitor_, ConnectionClose(QUIC_CONNECTION_TIMED_OUT, false));
-  clock_.AdvanceTimeInMicroseconds(5000);
-  EXPECT_EQ(kDefaultTimeout + 5000, clock_.NowInUsec());
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_EQ(default_timeout.Add(QuicTime::Delta::FromMilliseconds(5)),
+            clock_.Now());
   EXPECT_TRUE(connection_.CheckForTimeout());
   EXPECT_FALSE(connection_.connected());
 }
@@ -823,7 +833,8 @@
 TEST_F(QuicConnectionTest, SendScheduler) {
   // Test that if we send a packet without delay, it is not queued.
   scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(0));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta()));
   connection_.SendPacket(1, packet.get(), true, false, false);
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
 }
@@ -831,7 +842,8 @@
 TEST_F(QuicConnectionTest, SendSchedulerDelay) {
   // Test that if we send a packet with a delay, it ends up queued.
   scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta::FromMicroseconds(1)));
   EXPECT_CALL(*scheduler_, SentPacket(1, _, _)).Times(0);
   connection_.SendPacket(1, packet.get(), true, false, false);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
@@ -848,7 +860,8 @@
 TEST_F(QuicConnectionTest, SendSchedulerEAGAIN) {
   scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0));
   helper_->set_blocked(true);
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(0));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta()));
   EXPECT_CALL(*scheduler_, SentPacket(1, _, _)).Times(0);
   connection_.SendPacket(1, packet.get(), true, false, false);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
@@ -857,14 +870,16 @@
 TEST_F(QuicConnectionTest, SendSchedulerDelayThenSend) {
   // Test that if we send a packet with a delay, it ends up queued.
   scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta::FromMicroseconds(1)));
   connection_.SendPacket(1, packet.get(), true, false, false);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 
   // Advance the clock to fire the alarm, and configure the scheduler
   // to permit the packet to be sent.
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(0));
-  clock_.AdvanceTimeInMicroseconds(1);
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta()));
+  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(1));
   connection_.OnCanWrite();
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
 }
@@ -872,25 +887,27 @@
 TEST_F(QuicConnectionTest, SendSchedulerDelayThenRetransmit) {
   // Test that if we send a retransmit with a delay, it ends up queued.
   scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta::FromMicroseconds(1)));
   connection_.SendPacket(1, packet.get(), true, false, true);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 
   // Advance the clock to fire the alarm, and configure the scheduler
   // to permit the packet to be sent.
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(0));
-  clock_.AdvanceTimeInMicroseconds(1);
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta()));
 
   // Ensure the scheduler is notified this is a retransmit.
   EXPECT_CALL(*scheduler_, SentPacket(1, _, true));
-  clock_.AdvanceTimeInMicroseconds(1);
+  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(1));
   connection_.OnCanWrite();
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
 }
 
 TEST_F(QuicConnectionTest, SendSchedulerDelayAndQueue) {
   scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta::FromMicroseconds(1)));
   connection_.SendPacket(1, packet.get(), true, false, false);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 
@@ -901,17 +918,18 @@
 
 TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndSend) {
   scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(10));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta::FromMicroseconds(10)));
   connection_.SendPacket(1, packet.get(), true, false, false);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 
   // Now send non-retransmitting information, that we're not going to resend 3.
   // The far end should stop waiting for it.
-  QuicAckFrame frame(0, 0, 1);
+  QuicAckFrame frame(0, QuicTime(), 1);
   frame.sent_info.non_retransmiting.insert(3);
   EXPECT_CALL(*scheduler_, OnIncomingAckFrame(testing::_));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true))
-      .WillRepeatedly(testing::Return(0));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillRepeatedly(testing::Return(
+      QuicTime::Delta()));
   SendAckPacket(&frame);
 
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -921,16 +939,18 @@
 
 TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndHold) {
   scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(10));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta::FromMicroseconds(10)));
   connection_.SendPacket(1, packet.get(), true, false, false);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 
   // Now send non-resending information, that we're not going to resend 3.
   // The far end should stop waiting for it.
-  QuicAckFrame frame(0, 0, 1);
+  QuicAckFrame frame(0, QuicTime(), 1);
   frame.sent_info.non_retransmiting.insert(3);
   EXPECT_CALL(*scheduler_, OnIncomingAckFrame(testing::_));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta::FromMicroseconds(1)));
   SendAckPacket(&frame);
 
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
@@ -938,7 +958,8 @@
 
 TEST_F(QuicConnectionTest, SendSchedulerDelayThenOnCanWrite) {
   scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0));
-  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(10));
+  EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(
+      QuicTime::Delta::FromMicroseconds(10)));
   connection_.SendPacket(1, packet.get(), true, false, false);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index ab47407f..51d1bc7 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -371,11 +371,13 @@
     set_detailed_error("Unable to read largest received.");
     return false;
   }
-
-  if (!reader_->ReadUInt64(&frame->received_info.time_received)) {
+  uint64 time_received;
+  if (!reader_->ReadUInt64(&time_received)) {
     set_detailed_error("Unable to read time received.");
     return false;
   }
+  frame->received_info.time_received =
+      QuicTime::FromMicroseconds(time_received);
 
   uint8 num_unacked_packets;
   if (!reader_->ReadBytes(&num_unacked_packets, 1)) {
@@ -531,10 +533,10 @@
   return true;
 }
 
-void QuicFramer::WriteTransmissionTime(QuicTransmissionTime time,
+void QuicFramer::WriteTransmissionTime(QuicTime time,
                                        QuicPacket* packet) {
   QuicDataWriter::WriteUint64ToBuffer(
-      time, packet->mutable_data() + kTransmissionTimeOffset);
+      time.ToMicroseconds(), packet->mutable_data() + kTransmissionTimeOffset);
 }
 
 void QuicFramer::WriteSequenceNumber(QuicPacketSequenceNumber sequence_number,
@@ -677,7 +679,9 @@
   if (!writer->WriteUInt48(frame.received_info.largest_received)) {
     return false;
   }
-  if (!writer->WriteUInt64(frame.received_info.time_received)) {
+
+  if (!writer->WriteUInt64(
+      frame.received_info.time_received.ToMicroseconds())) {
     return false;
   }
 
diff --git a/net/quic/quic_framer.h b/net/quic/quic_framer.h
index 7bb4a2f..4154b38 100644
--- a/net/quic/quic_framer.h
+++ b/net/quic/quic_framer.h
@@ -140,7 +140,7 @@
                           const QuicFecData& fec,
                           QuicPacket** packet);
 
-  void WriteTransmissionTime(QuicTransmissionTime time, QuicPacket* packet);
+  void WriteTransmissionTime(QuicTime time, QuicPacket* packet);
 
   void WriteSequenceNumber(QuicPacketSequenceNumber sequence_number,
                            QuicPacket* packet);
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc
index dc54659..6d10271 100644
--- a/net/quic/quic_framer_test.cc
+++ b/net/quic/quic_framer_test.cc
@@ -553,7 +553,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -568,7 +568,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
     // unacked packet sequence number
@@ -607,7 +607,7 @@
   const QuicAckFrame& frame = *visitor_.ack_frames_[0];
   EXPECT_EQ(GG_UINT64_C(0x0123456789ABC),
             frame.received_info.largest_received);
-  EXPECT_EQ(GG_UINT64_C(0xF0E1D2C3B4A59687),
+  EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687)),
             frame.received_info.time_received);
 
   const hash_set<QuicPacketSequenceNumber>* sequence_nums =
@@ -667,7 +667,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -682,7 +682,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
     // unacked packet sequence number
@@ -725,7 +725,7 @@
   const QuicAckFrame& frame = *visitor_.ack_frames_[0];
   EXPECT_EQ(GG_UINT64_C(0x0123456789ABC),
             frame.received_info.largest_received);
-  EXPECT_EQ(GG_UINT64_C(0xF0E1D2C3B4A59687),
+  EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687)),
             frame.received_info.time_received);
 
   const hash_set<QuicPacketSequenceNumber>* sequence_nums =
@@ -774,7 +774,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -789,7 +789,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
     // unacked packet sequence number
@@ -834,7 +834,7 @@
   const QuicAckFrame& frame = *visitor_.ack_frames_[0];
   EXPECT_EQ(GG_UINT64_C(0x0123456789ABC),
             frame.received_info.largest_received);
-  EXPECT_EQ(GG_UINT64_C(0xF0E1D2C3B4A59687),
+  EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687)),
             frame.received_info.time_received);
 
   const hash_set<QuicPacketSequenceNumber>* sequence_nums =
@@ -885,7 +885,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -900,7 +900,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
     // unacked packet sequence number
@@ -941,7 +941,7 @@
   const QuicAckFrame& frame = *visitor_.ack_frames_[0];
   EXPECT_EQ(GG_UINT64_C(0x0123456789ABC),
             frame.received_info.largest_received);
-  EXPECT_EQ(GG_UINT64_C(0xF0E1D2C3B4A59687),
+  EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687)),
             frame.received_info.time_received);
 
   const hash_set<QuicPacketSequenceNumber>* sequence_nums =
@@ -987,7 +987,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -1002,7 +1002,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
     // unacked packet sequence number
@@ -1045,7 +1045,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -1116,7 +1116,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -1145,7 +1145,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
     // unacked packet sequence number
@@ -1194,7 +1194,7 @@
   const QuicAckFrame& frame = *visitor_.ack_frames_[0];
   EXPECT_EQ(GG_UINT64_C(0x0123456789ABC),
             frame.received_info.largest_received);
-  EXPECT_EQ(GG_UINT64_C(0xF0E1D2C3B4A59687),
+  EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687)),
             frame.received_info.time_received);
 
   const hash_set<QuicPacketSequenceNumber>* sequence_nums =
@@ -1244,7 +1244,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags (FEC)
     0x01,
     // fec group
@@ -1280,7 +1280,7 @@
   QuicPacketHeader header;
   header.guid = GG_UINT64_C(0xFEDCBA9876543210);
   header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
-  header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  header.transmission_time = GG_UINT64_C(0x07E1D2C3B4A59687);
   header.flags = PACKET_FLAGS_NONE;
   header.fec_group = 0;
 
@@ -1306,7 +1306,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -1345,13 +1345,14 @@
   QuicPacketHeader header;
   header.guid = GG_UINT64_C(0xFEDCBA9876543210);
   header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
-  header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  header.transmission_time = GG_UINT64_C(0x07E1D2C3B4A59687);
   header.flags = PACKET_FLAGS_NONE;
   header.fec_group = 0;
 
   QuicAckFrame ack_frame;
   ack_frame.received_info.largest_received = GG_UINT64_C(0x0123456789ABC);
-  ack_frame.received_info.time_received = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  ack_frame.received_info.time_received =
+      QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687));
   ack_frame.received_info.missing_packets.insert(
       GG_UINT64_C(0x0123456789ABB));
   ack_frame.received_info.missing_packets.insert(
@@ -1381,7 +1382,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -1396,7 +1397,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
 #if defined(OS_WIN)
@@ -1458,13 +1459,14 @@
   QuicPacketHeader header;
   header.guid = GG_UINT64_C(0xFEDCBA9876543210);
   header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
-  header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  header.transmission_time = GG_UINT64_C(0x07E1D2C3B4A59687);
   header.flags = PACKET_FLAGS_NONE;
   header.fec_group = 0;
 
   QuicAckFrame ack_frame;
   ack_frame.received_info.largest_received = GG_UINT64_C(0x0123456789ABC);
-  ack_frame.received_info.time_received = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  ack_frame.received_info.time_received =
+      QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687));
   ack_frame.received_info.missing_packets.insert(
       GG_UINT64_C(0x0123456789ABB));
   ack_frame.received_info.missing_packets.insert(
@@ -1496,7 +1498,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -1511,7 +1513,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
 #if defined(OS_WIN)
@@ -1577,13 +1579,14 @@
   QuicPacketHeader header;
   header.guid = GG_UINT64_C(0xFEDCBA9876543210);
   header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
-  header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  header.transmission_time = GG_UINT64_C(0x07E1D2C3B4A59687);
   header.flags = PACKET_FLAGS_NONE;
   header.fec_group = 0;
 
   QuicAckFrame ack_frame;
   ack_frame.received_info.largest_received = GG_UINT64_C(0x0123456789ABC);
-  ack_frame.received_info.time_received = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  ack_frame.received_info.time_received =
+      QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687));
   ack_frame.received_info.missing_packets.insert(
       GG_UINT64_C(0x0123456789ABB));
   ack_frame.received_info.missing_packets.insert(
@@ -1617,7 +1620,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -1632,7 +1635,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
 #if defined(OS_WIN)
@@ -1700,13 +1703,14 @@
   QuicPacketHeader header;
   header.guid = GG_UINT64_C(0xFEDCBA9876543210);
   header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
-  header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  header.transmission_time = GG_UINT64_C(0x07E1D2C3B4A59687);
   header.flags = PACKET_FLAGS_NONE;
   header.fec_group = 0;
 
   QuicAckFrame ack_frame;
   ack_frame.received_info.largest_received = GG_UINT64_C(0x0123456789ABC);
-  ack_frame.received_info.time_received = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  ack_frame.received_info.time_received =
+      QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687));
   ack_frame.received_info.missing_packets.insert(
       GG_UINT64_C(0x0123456789ABB));
   ack_frame.received_info.missing_packets.insert(
@@ -1738,7 +1742,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -1753,7 +1757,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
 #if defined(OS_WIN)
@@ -1817,13 +1821,14 @@
   QuicPacketHeader header;
   header.guid = GG_UINT64_C(0xFEDCBA9876543210);
   header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
-  header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  header.transmission_time = GG_UINT64_C(0x07E1D2C3B4A59687);
   header.flags = PACKET_FLAGS_NONE;
   header.fec_group = 0;
 
   QuicAckFrame ack_frame;
   ack_frame.received_info.largest_received = GG_UINT64_C(0x0123456789ABC);
-  ack_frame.received_info.time_received = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  ack_frame.received_info.time_received =
+      QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687));
   ack_frame.received_info.missing_packets.insert(
       GG_UINT64_C(0x0123456789ABB));
   ack_frame.received_info.missing_packets.insert(
@@ -1853,7 +1858,7 @@
   QuicPacketHeader header;
   header.guid = GG_UINT64_C(0xFEDCBA9876543210);
   header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
-  header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  header.transmission_time = GG_UINT64_C(0x07E1D2C3B4A59687);
   header.flags = PACKET_FLAGS_NONE;
   header.fec_group = 0;
 
@@ -1872,7 +1877,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -1917,7 +1922,7 @@
   QuicPacketHeader header;
   header.guid = GG_UINT64_C(0xFEDCBA9876543210);
   header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
-  header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  header.transmission_time = GG_UINT64_C(0x07E1D2C3B4A59687);
   header.flags = PACKET_FLAGS_NONE;
   header.fec_group = 0;
 
@@ -1927,7 +1932,8 @@
 
   QuicAckFrame* ack_frame = &close_frame.ack_frame;
   ack_frame->received_info.largest_received = GG_UINT64_C(0x0123456789ABC);
-  ack_frame->received_info.time_received = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  ack_frame->received_info.time_received =
+      QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687));
   ack_frame->received_info.missing_packets.insert(
       GG_UINT64_C(0x0123456789ABB));
   ack_frame->received_info.missing_packets.insert(
@@ -1959,7 +1965,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x00,
     // fec group
@@ -1986,7 +1992,7 @@
     0x34, 0x12,
     // time delta
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // num_unacked_packets
     0x02,
 #if defined(OS_WIN)
@@ -2054,7 +2060,7 @@
   QuicPacketHeader header;
   header.guid = GG_UINT64_C(0xFEDCBA9876543210);
   header.packet_sequence_number = (GG_UINT64_C(0x123456789ABC));
-  header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687);
+  header.transmission_time = GG_UINT64_C(0x07E1D2C3B4A59687);
   header.flags = PACKET_FLAGS_FEC;
   header.fec_group = 1;
 
@@ -2073,7 +2079,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x01,
     // fec group
@@ -2108,7 +2114,7 @@
     0x34, 0x12,
     // transmission time
     0x87, 0x96, 0xA5, 0xB4,
-    0xC3, 0xD2, 0xE1, 0xF0,
+    0xC3, 0xD2, 0xE1, 0x07,
     // flags
     0x01,
     // fec group
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc
index 4ca2d3e..0a2538b 100644
--- a/net/quic/quic_protocol.cc
+++ b/net/quic/quic_protocol.cc
@@ -32,7 +32,7 @@
 
 ostream& operator<<(ostream& os, const QuicAckFrame& s) {
   os << "largest_received: " << s.received_info.largest_received
-     << " time: " << s.received_info.time_received
+     << " time: " << s.received_info.time_received.ToMicroseconds()
      << " missing: ";
   for (hash_set<QuicPacketSequenceNumber>::const_iterator it =
            s.received_info.missing_packets.begin();
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index b91377a..85f78c6 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -15,6 +15,7 @@
 #include "base/logging.h"
 #include "base/string_piece.h"
 #include "net/base/net_export.h"
+#include "net/quic/quic_time.h"
 #include "net/quic/uint128.h"
 
 namespace net {
@@ -63,7 +64,7 @@
 
 typedef std::pair<QuicPacketSequenceNumber, QuicPacket*> PacketPair;
 
-const uint64 kDefaultTimeout = 600000000;  // 10 minutes
+const int64 kDefaultTimeoutUs = 600000000;  // 10 minutes.
 
 enum QuicFrameType {
   STREAM_FRAME = 0,
@@ -172,7 +173,7 @@
   // The highest packet sequence number we've received from the peer.
   QuicPacketSequenceNumber largest_received;
   // The time at which we received the above packet.
-  QuicTransmissionTime time_received;
+  QuicTime time_received;
   // The set of packets which we're expecting and have not received.
   // This includes any packets between the lowest and largest_received
   // which we have neither seen nor been informed are non-retransmitting.
@@ -243,7 +244,7 @@
 struct NET_EXPORT_PRIVATE QuicAckFrame {
   QuicAckFrame() {}
   QuicAckFrame(QuicPacketSequenceNumber largest_received,
-               QuicTransmissionTime time_received,
+               QuicTime time_received,
                QuicPacketSequenceNumber least_unacked) {
     received_info.largest_received = largest_received;
     received_info.time_received = time_received;
diff --git a/net/quic/quic_time.cc b/net/quic/quic_time.cc
new file mode 100644
index 0000000..b4c195a
--- /dev/null
+++ b/net/quic/quic_time.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/quic_time.h"
+
+#include "base/logging.h"
+
+namespace net {
+
+// Highest number of microseconds that DateTimeOffset can hold.
+const uint64 kQuicInfiniteTimeUs = GG_UINT64_C(0x7fffffffffffffff) / 10;
+
+QuicTime::Delta::Delta()
+    : delta_(base::TimeDelta::FromMicroseconds(0)) {
+}
+
+QuicTime::Delta::Delta(base::TimeDelta delta)
+    : delta_(delta) {
+}
+
+QuicTime::Delta QuicTime::Delta::Infinite() {
+  return QuicTime::Delta::FromMicroseconds(kQuicInfiniteTimeUs);
+}
+
+bool QuicTime::Delta::IsZero() const {
+  return delta_.InMicroseconds() == 0;
+}
+
+bool QuicTime::Delta::IsInfinite() const {
+  return static_cast<uint64>(delta_.InMicroseconds()) == kQuicInfiniteTimeUs;
+}
+
+QuicTime::Delta QuicTime::Delta::FromMilliseconds(int64 ms) {
+  return QuicTime::Delta(base::TimeDelta::FromMilliseconds(ms));
+}
+
+QuicTime::Delta QuicTime::Delta::FromMicroseconds(int64 us) {
+  return QuicTime::Delta(base::TimeDelta::FromMicroseconds(us));
+}
+
+int64 QuicTime::Delta::ToMilliseconds() const {
+  return delta_.InMilliseconds();
+}
+
+int64 QuicTime::Delta::ToMicroseconds() const {
+  return delta_.InMicroseconds();
+}
+
+QuicTime::Delta QuicTime::Delta::Add(const Delta& delta) const {
+  return QuicTime::Delta::FromMicroseconds(ToMicroseconds() +
+                                           delta.ToMicroseconds());
+}
+
+QuicTime::Delta QuicTime::Delta::Subtract(const Delta& delta) const {
+  return QuicTime::Delta::FromMicroseconds(ToMicroseconds() -
+                                           delta.ToMicroseconds());
+}
+
+
+QuicTime::QuicTime() {
+}
+
+QuicTime::QuicTime(base::TimeTicks ticks)
+    : ticks_(ticks) {
+}
+
+QuicTime QuicTime::FromMilliseconds(uint64 time_ms) {
+  // DateTime use 100 ns as resolution make sure we don't pass down too high
+  // values.
+  DCHECK(time_ms < kQuicInfiniteTimeUs / 1000);
+  return QuicTime(base::TimeTicks() +
+                  base::TimeDelta::FromMilliseconds(time_ms));
+}
+
+QuicTime QuicTime::FromMicroseconds(uint64 time_us) {
+  // DateTime use 100 ns as resolution make sure we don't pass down too high
+  // values.
+  DCHECK(time_us < kQuicInfiniteTimeUs);
+  return QuicTime(base::TimeTicks() +
+                  base::TimeDelta::FromMicroseconds(time_us));
+}
+
+uint64 QuicTime::ToMilliseconds() const {
+  return (ticks_ - base::TimeTicks()).InMilliseconds();
+}
+
+uint64 QuicTime::ToMicroseconds() const {
+  return (ticks_ - base::TimeTicks()).InMicroseconds();
+}
+
+bool QuicTime::IsInitialized() const {
+  return ticks_ != base::TimeTicks();
+}
+
+QuicTime QuicTime::Add(const Delta& delta) const {
+  return QuicTime(ticks_ + delta.delta_);
+}
+
+QuicTime QuicTime::Subtract(const Delta& delta) const {
+  return QuicTime(ticks_ - delta.delta_);
+}
+
+QuicTime::Delta QuicTime::Subtract(const QuicTime& other) const {
+  return QuicTime::Delta(ticks_ - other.ticks_);
+}
+
+}  // namespace gfe_quic
diff --git a/net/quic/quic_time.h b/net/quic/quic_time.h
new file mode 100644
index 0000000..becb3b2
--- /dev/null
+++ b/net/quic/quic_time.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// QuicTime represents one point in time, stored in microsecond resolution.
+// This class wrapps the classes DateTimeO and DateTimeOffset.
+
+#ifndef NET_QUIC_QUIC_TIME_H_
+#define NET_QUIC_QUIC_TIME_H_
+
+#include "base/basictypes.h"
+#include "base/time.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+class NET_EXPORT_PRIVATE QuicTime {
+ public:
+  // A QuicTime::Delta represents the signed difference between two points in
+  // time, stored in microsecond resolution.
+  class NET_EXPORT_PRIVATE Delta {
+   public:
+    // Default constructor initiates to 0.
+    Delta();
+
+    explicit Delta(base::TimeDelta delta);
+
+    // Create a object with infinite offset time.
+    static Delta Infinite();
+
+    // Converts a number of milliseconds to a time offset.
+    static Delta FromMilliseconds(int64 ms);
+
+    // Converts a number of microseconds to a time offset.
+    static Delta FromMicroseconds(int64 us);
+
+    // Converts the time offset to a rounded number of milliseconds.
+    int64 ToMilliseconds() const;
+
+    // Converts the time offset to a rounded number of microseconds.
+    int64 ToMicroseconds() const;
+
+    Delta Add(const Delta& delta) const;
+
+    Delta Subtract(const Delta& delta) const;
+
+    bool IsZero() const;
+
+    bool IsInfinite() const;
+
+   private:
+    base::TimeDelta delta_;
+
+    friend class QuicTime;
+  };
+
+  // Default constructor initiates to 0.
+  QuicTime();
+
+  explicit QuicTime(base::TimeTicks ticks);
+
+  // Create a new QuicTime holding the time_ms.
+  static QuicTime FromMilliseconds(uint64 time_ms);
+
+  // Create a new QuicTime holding the time_us.
+  static QuicTime FromMicroseconds(uint64 time_us);
+
+  uint64 ToMilliseconds() const;
+
+  uint64 ToMicroseconds() const;
+
+  bool IsInitialized() const;
+
+  QuicTime Add(const Delta& delta) const;
+
+  QuicTime Subtract(const Delta& delta) const;
+
+  Delta Subtract(const QuicTime& other) const;
+
+ private:
+  base::TimeTicks ticks_;
+
+  friend class QuicClock;
+  friend class QuicClockTest;
+};
+
+// Non-member relational operators for QuicTime::Delta.
+inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return lhs.ToMicroseconds() == rhs.ToMicroseconds();
+}
+inline bool operator!=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(lhs == rhs);
+}
+inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return lhs.ToMicroseconds() < rhs.ToMicroseconds();
+}
+inline bool operator>(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return rhs < lhs;
+}
+inline bool operator<=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(rhs < lhs);
+}
+inline bool operator>=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(lhs < rhs);
+}
+// Non-member relational operators for QuicTime.
+inline bool operator==(QuicTime lhs, QuicTime rhs) {
+  return lhs.ToMicroseconds() == rhs.ToMicroseconds();
+}
+inline bool operator!=(QuicTime lhs, QuicTime rhs) {
+  return !(lhs == rhs);
+}
+inline bool operator<(QuicTime lhs, QuicTime rhs) {
+  return lhs.ToMicroseconds() < rhs.ToMicroseconds();
+}
+inline bool operator>(QuicTime lhs, QuicTime rhs) {
+  return rhs < lhs;
+}
+inline bool operator<=(QuicTime lhs, QuicTime rhs) {
+  return !(rhs < lhs);
+}
+inline bool operator>=(QuicTime lhs, QuicTime rhs) {
+  return !(lhs < rhs);
+}
+
+}  // namespace net
+
+#endif  // NET_QUIC_QUIC_TIME_H_
diff --git a/net/quic/quic_time_test.cc b/net/quic/quic_time_test.cc
new file mode 100644
index 0000000..99b7fab
--- /dev/null
+++ b/net/quic/quic_time_test.cc
@@ -0,0 +1,106 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/quic_time.h"
+#include "net/quic/test_tools/mock_clock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace testing {
+
+class QuicTimeDeltaTest : public ::testing::Test {
+ protected:
+};
+
+TEST_F(QuicTimeDeltaTest, Zero) {
+  EXPECT_TRUE(QuicTime::Delta().IsZero());
+  EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsZero());
+}
+
+TEST_F(QuicTimeDeltaTest, Infinite) {
+  EXPECT_TRUE(QuicTime::Delta::Infinite().IsInfinite());
+  EXPECT_FALSE(QuicTime::Delta().IsInfinite());
+  EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsInfinite());
+}
+
+TEST_F(QuicTimeDeltaTest, FromTo) {
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
+            QuicTime::Delta::FromMicroseconds(1000));
+  EXPECT_EQ(1, QuicTime::Delta::FromMicroseconds(1000).ToMilliseconds());
+  EXPECT_EQ(1000, QuicTime::Delta::FromMilliseconds(1).ToMicroseconds());
+}
+
+TEST_F(QuicTimeDeltaTest, Add) {
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2000),
+            QuicTime::Delta().Add(QuicTime::Delta::FromMilliseconds(2)));
+}
+
+TEST_F(QuicTimeDeltaTest, Subtract) {
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1000),
+            QuicTime::Delta::FromMilliseconds(2).Subtract(
+                QuicTime::Delta::FromMilliseconds(1)));
+}
+
+class QuicTimeTest : public ::testing::Test {
+ protected:
+  MockClock clock_;
+};
+
+TEST_F(QuicTimeTest, Initialized) {
+  EXPECT_FALSE(QuicTime().IsInitialized());
+  EXPECT_TRUE(QuicTime::FromMilliseconds(1).IsInitialized());
+}
+
+TEST_F(QuicTimeTest, FromTo) {
+  EXPECT_EQ(QuicTime::FromMilliseconds(1),
+            QuicTime::FromMicroseconds(1000));
+  EXPECT_EQ(1u, QuicTime::FromMicroseconds(1000).ToMilliseconds());
+  EXPECT_EQ(1000u, QuicTime::FromMilliseconds(1).ToMicroseconds());
+}
+
+TEST_F(QuicTimeTest, Add) {
+  QuicTime time_1 = QuicTime::FromMilliseconds(1);
+  QuicTime time_2 = QuicTime::FromMilliseconds(1);
+
+  time_1 = time_1.Subtract(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicTime::Delta diff = time_2.Subtract(time_1);
+
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), diff);
+  EXPECT_EQ(1000, diff.ToMicroseconds());
+  EXPECT_EQ(1, diff.ToMilliseconds());
+}
+
+TEST_F(QuicTimeTest, Subtract) {
+  QuicTime time_1 = QuicTime::FromMilliseconds(1);
+  QuicTime time_2 = QuicTime::FromMilliseconds(2);
+
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), time_2.Subtract(time_1));
+}
+
+TEST_F(QuicTimeTest, SubtractDelta) {
+  QuicTime time = QuicTime::FromMilliseconds(2);
+  EXPECT_EQ(QuicTime::FromMilliseconds(1),
+            time.Subtract(QuicTime::Delta::FromMilliseconds(1)));
+}
+
+TEST_F(QuicTimeTest, MockClock) {
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicTime now = clock_.Now();
+  QuicTime time = QuicTime::FromMicroseconds(1000);
+
+  EXPECT_EQ(now, time);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  now = clock_.Now();
+
+  EXPECT_NE(now, time);
+
+  time = time.Add(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(now, time);
+}
+
+}  // namespace testing
+}  // namespace net
diff --git a/net/quic/test_tools/mock_clock.cc b/net/quic/test_tools/mock_clock.cc
index e8db8f8..557d8db 100644
--- a/net/quic/test_tools/mock_clock.cc
+++ b/net/quic/test_tools/mock_clock.cc
@@ -6,19 +6,25 @@
 
 namespace net {
 
-MockClock::MockClock() : now_(0) {
+MockClock::MockClock() {
 }
 
 MockClock::~MockClock() {
 }
 
-uint64 MockClock::NowInUsec() const {
+void MockClock::AdvanceTime(QuicTime::Delta delta) {
+  CHECK_LE(0, delta.ToMicroseconds());
+  now_ = now_.Add(delta);
+}
+
+QuicTime MockClock::Now() const {
   return now_;
 }
 
-base::TimeTicks MockClock::Now() const {
-  base::TimeTicks now;
-  return now + base::TimeDelta::FromMicroseconds(now_);
+base::TimeTicks MockClock::NowInTicks() const {
+  base::TimeTicks ticks;
+  return ticks + base::TimeDelta::FromMicroseconds(
+      now_.Subtract(QuicTime()).ToMicroseconds());
 }
 
 }  // namespace net
diff --git a/net/quic/test_tools/mock_clock.h b/net/quic/test_tools/mock_clock.h
index 693e9b2..bbaf343 100644
--- a/net/quic/test_tools/mock_clock.h
+++ b/net/quic/test_tools/mock_clock.h
@@ -19,27 +19,16 @@
 
   virtual ~MockClock();
 
-  virtual uint64 NowInUsec() const OVERRIDE;
+  void AdvanceTime(QuicTime::Delta delta);
 
-  base::TimeTicks Now() const;
+  virtual QuicTime Now() const OVERRIDE;
 
-  void AdvanceTimeInMicroseconds(uint64 delta_in_us) {
-    now_ += delta_in_us;
-  }
+  base::TimeTicks NowInTicks() const;
 
-  void AdvanceTimeByDelta(base::TimeDelta delta) {
-    CHECK_LE(0, delta.InMicroseconds());
-    now_ += delta.InMicroseconds();
-  }
-
-  void AdvanceTime(WallTime delta) {
-    CHECK_LE(0, delta);;
-    uint64 delta_us = delta * base::Time::kMicrosecondsPerSecond;
-    now_ += delta_us;
-  }
+  void AdvanceTime(QuicTime delta);
 
  private:
-  uint64 now_;
+  QuicTime now_;
 };
 
 }  // namespace net
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index b7dcb6e..59f26320 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -116,7 +116,7 @@
   MockScheduler();
   virtual ~MockScheduler();
 
-  MOCK_METHOD1(TimeUntilSend, int(bool));
+  MOCK_METHOD1(TimeUntilSend, QuicTime::Delta(bool));
   MOCK_METHOD1(OnIncomingAckFrame, void(const QuicAckFrame&));
   MOCK_METHOD3(SentPacket, void(QuicPacketSequenceNumber, size_t, bool));
 
@@ -137,9 +137,9 @@
                                       bool resend,
                                       int* error));
   MOCK_METHOD2(SetResendAlarm, void(QuicPacketSequenceNumber sequence_number,
-                                    uint64 delay_in_us));
-  MOCK_METHOD1(SetSendAlarm, void(uint64 delay_in_us));
-  MOCK_METHOD1(SetTimeoutAlarm, void(uint64 delay_in_us));
+                                    QuicTime::Delta delay));
+  MOCK_METHOD1(SetSendAlarm, void(QuicTime::Delta delay));
+  MOCK_METHOD1(SetTimeoutAlarm, void(QuicTime::Delta delay));
   MOCK_METHOD0(IsSendAlarmSet, bool());
   MOCK_METHOD0(UnregisterSendAlarmIfRegistered, void());
  private:
diff --git a/net/quic/test_tools/test_task_runner.cc b/net/quic/test_tools/test_task_runner.cc
index ee619c9f..a2521fa 100644
--- a/net/quic/test_tools/test_task_runner.cc
+++ b/net/quic/test_tools/test_task_runner.cc
@@ -46,7 +46,8 @@
                                      const base::Closure& closure,
                                      base::TimeDelta delta) {
   EXPECT_GE(delta, base::TimeDelta());
-  tasks_.push_back(PostedTask(location, closure, delta, clock_->Now() + delta));
+  tasks_.push_back(PostedTask(location, closure, delta,
+                              clock_->NowInTicks() + delta));
   return false;
 }
 
@@ -75,7 +76,8 @@
   // and then run the task.
   std::vector<PostedTask>::iterator next = FindNextTask();
   DCHECK(next != tasks_.end());
-  clock_->AdvanceTimeByDelta(next->time - clock_->Now());
+  clock_->AdvanceTime(QuicTime::Delta::FromMicroseconds(
+      (next->time - clock_->NowInTicks()).InMicroseconds()));
   PostedTask task = *next;
   tasks_.erase(next);
   task.closure.Run();