TimePoint::Now uses DartTimestampProvider (#27737)

diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index 22347dc..9a1fc03 100755
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -292,6 +292,8 @@
 FILE: ../../../flutter/fml/thread_unittests.cc
 FILE: ../../../flutter/fml/time/chrono_timestamp_provider.cc
 FILE: ../../../flutter/fml/time/chrono_timestamp_provider.h
+FILE: ../../../flutter/fml/time/dart_timestamp_provider.cc
+FILE: ../../../flutter/fml/time/dart_timestamp_provider.h
 FILE: ../../../flutter/fml/time/time_delta.h
 FILE: ../../../flutter/fml/time/time_delta_unittest.cc
 FILE: ../../../flutter/fml/time/time_point.cc
diff --git a/fml/BUILD.gn b/fml/BUILD.gn
index 2f9964a..ff05896 100644
--- a/fml/BUILD.gn
+++ b/fml/BUILD.gn
@@ -77,6 +77,8 @@
     "thread.h",
     "thread_local.cc",
     "thread_local.h",
+    "time/dart_timestamp_provider.cc",
+    "time/dart_timestamp_provider.h",
     "time/time_delta.h",
     "time/time_point.cc",
     "time/time_point.h",
diff --git a/fml/time/chrono_timestamp_provider.cc b/fml/time/chrono_timestamp_provider.cc
index 5d315fd..b6e8efd 100644
--- a/fml/time/chrono_timestamp_provider.cc
+++ b/fml/time/chrono_timestamp_provider.cc
@@ -6,8 +6,6 @@
 
 #include <chrono>
 
-#include "fml/time/time_delta.h"
-
 namespace fml {
 
 ChronoTimestampProvider::ChronoTimestampProvider() = default;
diff --git a/fml/time/chrono_timestamp_provider.h b/fml/time/chrono_timestamp_provider.h
index 0a03f36..bd0e6dd 100644
--- a/fml/time/chrono_timestamp_provider.h
+++ b/fml/time/chrono_timestamp_provider.h
@@ -8,7 +8,7 @@
 #include "flutter/fml/time/timestamp_provider.h"
 
 #include "flutter/fml/macros.h"
-#include "fml/time/time_point.h"
+#include "flutter/fml/time/time_point.h"
 
 namespace fml {
 
diff --git a/fml/time/dart_timestamp_provider.cc b/fml/time/dart_timestamp_provider.cc
new file mode 100644
index 0000000..2c5de9d
--- /dev/null
+++ b/fml/time/dart_timestamp_provider.cc
@@ -0,0 +1,38 @@
+// Copyright 2013 The Flutter 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 "flutter/fml/time/dart_timestamp_provider.h"
+
+#include "dart_tools_api.h"
+
+namespace fml {
+
+DartTimestampProvider::DartTimestampProvider() = default;
+
+DartTimestampProvider::~DartTimestampProvider() = default;
+
+int64_t DartTimestampProvider::ConvertToNanos(int64_t ticks,
+                                              int64_t frequency) {
+  int64_t nano_seconds = (ticks / frequency) * kNanosPerSecond;
+  int64_t leftover_ticks = ticks % frequency;
+  int64_t leftover_nanos = (leftover_ticks * kNanosPerSecond) / frequency;
+  return nano_seconds + leftover_nanos;
+}
+
+fml::TimePoint DartTimestampProvider::Now() {
+  const int64_t ticks = Dart_TimelineGetTicks();
+  const int64_t frequency = Dart_TimelineGetTicksFrequency();
+  // optimization for the most common case.
+  if (frequency != kNanosPerSecond) {
+    return fml::TimePoint::FromTicks(ConvertToNanos(ticks, frequency));
+  } else {
+    return fml::TimePoint::FromTicks(ticks);
+  }
+}
+
+fml::TimePoint DartTimelineTicksSinceEpoch() {
+  return DartTimestampProvider::Instance().Now();
+}
+
+}  // namespace fml
diff --git a/fml/time/dart_timestamp_provider.h b/fml/time/dart_timestamp_provider.h
new file mode 100644
index 0000000..97ab6b1
--- /dev/null
+++ b/fml/time/dart_timestamp_provider.h
@@ -0,0 +1,41 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FLUTTER_FML_TIME_DART_TIMESTAMP_PROVIDER_H_
+#define FLUTTER_FML_TIME_DART_TIMESTAMP_PROVIDER_H_
+
+#include "flutter/fml/time/timestamp_provider.h"
+
+#include "flutter/fml/macros.h"
+#include "flutter/fml/time/time_point.h"
+
+namespace fml {
+
+fml::TimePoint DartTimelineTicksSinceEpoch();
+
+/// TimestampProvider implementation that is backed by Dart_TimelineGetTicks
+class DartTimestampProvider : TimestampProvider {
+ public:
+  static DartTimestampProvider& Instance() {
+    static DartTimestampProvider instance;
+    return instance;
+  }
+
+  ~DartTimestampProvider() override;
+
+  fml::TimePoint Now() override;
+
+ private:
+  static constexpr int64_t kNanosPerSecond = 1000000000;
+
+  int64_t ConvertToNanos(int64_t ticks, int64_t frequency);
+
+  DartTimestampProvider();
+
+  FML_DISALLOW_COPY_AND_ASSIGN(DartTimestampProvider);
+};
+
+}  // namespace fml
+
+#endif  // FLUTTER_FML_TIME_DART_TIMESTAMP_PROVIDER_H_
diff --git a/fml/time/time_point.cc b/fml/time/time_point.cc
index 7c54d70..e3bd652 100644
--- a/fml/time/time_point.cc
+++ b/fml/time/time_point.cc
@@ -6,6 +6,7 @@
 
 #include "flutter/fml/build_config.h"
 #include "flutter/fml/logging.h"
+#include "flutter/fml/time/dart_timestamp_provider.h"
 
 #if defined(OS_FUCHSIA)
 #include <zircon/syscalls.h>
@@ -36,8 +37,7 @@
 }
 
 TimePoint TimePoint::Now() {
-  const int64_t nanos = NanosSinceEpoch(std::chrono::steady_clock::now());
-  return TimePoint(nanos);
+  return DartTimelineTicksSinceEpoch();
 }
 
 TimePoint TimePoint::CurrentWallTime() {
diff --git a/fml/time/time_point.h b/fml/time/time_point.h
index 456bc5c..1960234 100644
--- a/fml/time/time_point.h
+++ b/fml/time/time_point.h
@@ -39,6 +39,7 @@
     return TimePoint(ticks.ToNanoseconds());
   }
 
+  // Expects ticks in nanos.
   static constexpr TimePoint FromTicks(int64_t ticks) {
     return TimePoint(ticks);
   }
diff --git a/fml/time/time_point_unittest.cc b/fml/time/time_point_unittest.cc
index 9b4ca76..32b35ed 100644
--- a/fml/time/time_point_unittest.cc
+++ b/fml/time/time_point_unittest.cc
@@ -4,6 +4,10 @@
 
 #include "flutter/fml/time/chrono_timestamp_provider.h"
 
+#include "flutter/fml/time/dart_timestamp_provider.h"
+
+#include <thread>
+
 #include "gtest/gtest.h"
 
 namespace fml {
@@ -14,5 +18,18 @@
   EXPECT_GT(TimePoint::Max(), ChronoTicksSinceEpoch());
 }
 
+TEST(TimePoint, DartClockIsMonotonic) {
+  using namespace std::chrono_literals;
+  const auto t1 = DartTimelineTicksSinceEpoch();
+  std::this_thread::sleep_for(1us);
+  const auto t2 = DartTimelineTicksSinceEpoch();
+  std::this_thread::sleep_for(1us);
+  const auto t3 = DartTimelineTicksSinceEpoch();
+  EXPECT_LT(TimePoint::Min(), t1);
+  EXPECT_LE(t1, t2);
+  EXPECT_LE(t2, t3);
+  EXPECT_LT(t3, TimePoint::Max());
+}
+
 }  // namespace
 }  // namespace fml