Consolidate the different NTP clocks into one.

WebRTC code has two ways of querying for the NTP time:
- rtc::TimeMillis() + NtpOffsetMs()
- Clock::CurrentNtpTime

`Clock::CurrentNtpTime` is not monotonic and is platform dependent.
This CL changes its implementation return `rtc::TimeMillis() +
NtpOffsetMs()`

More info is available in the attached bug.

Bug: webrtc:11327
Change-Id: I34fe4cc2d321c2b63275c93be21122c9de1ab403
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/213425
Commit-Queue: Paul Hallak <phallak@google.com>
Reviewed-by: Minyue Li <minyue@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33655}
diff --git a/system_wrappers/include/clock.h b/system_wrappers/include/clock.h
index f70a2f4..bcb7fea 100644
--- a/system_wrappers/include/clock.h
+++ b/system_wrappers/include/clock.h
@@ -32,18 +32,24 @@
 class RTC_EXPORT Clock {
  public:
   virtual ~Clock() {}
+
   // Return a timestamp relative to an unspecified epoch.
+  // TODO(bugs.webrtc.org/11327): Make this a pure virtual function.
   virtual Timestamp CurrentTime() {
     return Timestamp::Micros(TimeInMicroseconds());
   }
+
+  // TODO(bugs.webrtc.org/11327): Make the following two methods non-virtual
+  // or completely remove them.
   virtual int64_t TimeInMilliseconds() { return CurrentTime().ms(); }
   virtual int64_t TimeInMicroseconds() { return CurrentTime().us(); }
 
-  // Retrieve an NTP absolute timestamp.
+  // Retrieve an NTP absolute timestamp (with an epoch of Jan 1, 1900).
   virtual NtpTime CurrentNtpTime() = 0;
 
-  // Retrieve an NTP absolute timestamp in milliseconds.
-  virtual int64_t CurrentNtpInMilliseconds() = 0;
+  // TODO(bugs.webrtc.org/11327): Make the following method non-virtual
+  // or completely remove it.
+  virtual int64_t CurrentNtpInMilliseconds() { return CurrentNtpTime().ToMs(); }
 
   // Returns an instance of the real-time system clock implementation.
   static Clock* GetRealTimeClock();
@@ -51,21 +57,16 @@
 
 class SimulatedClock : public Clock {
  public:
+  // The constructors assume an epoch of Jan 1, 1970.
   explicit SimulatedClock(int64_t initial_time_us);
   explicit SimulatedClock(Timestamp initial_time);
-
   ~SimulatedClock() override;
 
-  // Return a timestamp relative to some arbitrary source; the source is fixed
-  // for this clock.
+  // Return a timestamp with an epoch of Jan 1, 1970.
   Timestamp CurrentTime() override;
 
-  // Retrieve an NTP absolute timestamp.
   NtpTime CurrentNtpTime() override;
 
-  // Converts an NTP timestamp to a millisecond timestamp.
-  int64_t CurrentNtpInMilliseconds() override;
-
   // Advance the simulated clock with a given number of milliseconds or
   // microseconds.
   void AdvanceTimeMilliseconds(int64_t milliseconds);
diff --git a/system_wrappers/source/clock.cc b/system_wrappers/source/clock.cc
index 8edffa6..2c3981a 100644
--- a/system_wrappers/source/clock.cc
+++ b/system_wrappers/source/clock.cc
@@ -10,6 +10,8 @@
 
 #include "system_wrappers/include/clock.h"
 
+#include "system_wrappers/include/field_trial.h"
+
 #if defined(WEBRTC_WIN)
 
 // Windows needs to be included before mmsystem.h
@@ -29,57 +31,82 @@
 #include "rtc_base/time_utils.h"
 
 namespace webrtc {
+namespace {
+
+int64_t NtpOffsetUsCalledOnce() {
+  constexpr int64_t kNtpJan1970Sec = 2208988800;
+  int64_t clock_time = rtc::TimeMicros();
+  int64_t utc_time = rtc::TimeUTCMicros();
+  return utc_time - clock_time + kNtpJan1970Sec * rtc::kNumMicrosecsPerSec;
+}
+
+NtpTime TimeMicrosToNtp(int64_t time_us) {
+  static int64_t ntp_offset_us = NtpOffsetUsCalledOnce();
+
+  int64_t time_ntp_us = time_us + ntp_offset_us;
+  RTC_DCHECK_GE(time_ntp_us, 0);  // Time before year 1900 is unsupported.
+
+  // Convert seconds to uint32 through uint64 for a well-defined cast.
+  // A wrap around, which will happen in 2036, is expected for NTP time.
+  uint32_t ntp_seconds =
+      static_cast<uint64_t>(time_ntp_us / rtc::kNumMicrosecsPerSec);
+
+  // Scale fractions of the second to NTP resolution.
+  constexpr int64_t kNtpFractionsInSecond = 1LL << 32;
+  int64_t us_fractions = time_ntp_us % rtc::kNumMicrosecsPerSec;
+  uint32_t ntp_fractions =
+      us_fractions * kNtpFractionsInSecond / rtc::kNumMicrosecsPerSec;
+
+  return NtpTime(ntp_seconds, ntp_fractions);
+}
+
+void GetSecondsAndFraction(const timeval& time,
+                           uint32_t* seconds,
+                           double* fraction) {
+  *seconds = time.tv_sec + kNtpJan1970;
+  *fraction = time.tv_usec / 1e6;
+
+  while (*fraction >= 1) {
+    --*fraction;
+    ++*seconds;
+  }
+  while (*fraction < 0) {
+    ++*fraction;
+    --*seconds;
+  }
+}
+
+}  // namespace
 
 class RealTimeClock : public Clock {
+ public:
+  RealTimeClock()
+      : use_system_independent_ntp_time_(!field_trial::IsEnabled(
+            "WebRTC-SystemIndependentNtpTimeKillSwitch")) {}
+
   Timestamp CurrentTime() override {
     return Timestamp::Micros(rtc::TimeMicros());
   }
-  // Return a timestamp in milliseconds relative to some arbitrary source; the
-  // source is fixed for this clock.
-  int64_t TimeInMilliseconds() override { return rtc::TimeMillis(); }
 
-  // Return a timestamp in microseconds relative to some arbitrary source; the
-  // source is fixed for this clock.
-  int64_t TimeInMicroseconds() override { return rtc::TimeMicros(); }
-
-  // Retrieve an NTP absolute timestamp.
   NtpTime CurrentNtpTime() override {
-    timeval tv = CurrentTimeVal();
-    double microseconds_in_seconds;
-    uint32_t seconds;
-    Adjust(tv, &seconds, &microseconds_in_seconds);
-    uint32_t fractions = static_cast<uint32_t>(
-        microseconds_in_seconds * kMagicNtpFractionalUnit + 0.5);
-    return NtpTime(seconds, fractions);
-  }
-
-  // Retrieve an NTP absolute timestamp in milliseconds.
-  int64_t CurrentNtpInMilliseconds() override {
-    timeval tv = CurrentTimeVal();
-    uint32_t seconds;
-    double microseconds_in_seconds;
-    Adjust(tv, &seconds, &microseconds_in_seconds);
-    return 1000 * static_cast<int64_t>(seconds) +
-           static_cast<int64_t>(1000.0 * microseconds_in_seconds + 0.5);
+    return use_system_independent_ntp_time_ ? TimeMicrosToNtp(rtc::TimeMicros())
+                                            : SystemDependentNtpTime();
   }
 
  protected:
   virtual timeval CurrentTimeVal() = 0;
 
-  static void Adjust(const timeval& tv,
-                     uint32_t* adjusted_s,
-                     double* adjusted_us_in_s) {
-    *adjusted_s = tv.tv_sec + kNtpJan1970;
-    *adjusted_us_in_s = tv.tv_usec / 1e6;
+ private:
+  NtpTime SystemDependentNtpTime() {
+    uint32_t seconds;
+    double fraction;
+    GetSecondsAndFraction(CurrentTimeVal(), &seconds, &fraction);
 
-    if (*adjusted_us_in_s >= 1) {
-      *adjusted_us_in_s -= 1;
-      ++*adjusted_s;
-    } else if (*adjusted_us_in_s < -1) {
-      *adjusted_us_in_s += 1;
-      --*adjusted_s;
-    }
+    return NtpTime(seconds, static_cast<uint32_t>(
+                                fraction * kMagicNtpFractionalUnit + 0.5));
   }
+
+  bool use_system_independent_ntp_time_;
 };
 
 #if defined(WINUWP)
@@ -257,10 +284,6 @@
   return NtpTime(seconds, fractions);
 }
 
-int64_t SimulatedClock::CurrentNtpInMilliseconds() {
-  return TimeInMilliseconds() + 1000 * static_cast<int64_t>(kNtpJan1970);
-}
-
 void SimulatedClock::AdvanceTimeMilliseconds(int64_t milliseconds) {
   AdvanceTime(TimeDelta::Millis(milliseconds));
 }