tracing_service_impl: Use virtual interface for clock

So that we can mock it in tests.

Change-Id: If9eefdf9315ac60970928daf72e054fea935fa03
diff --git a/Android.bp b/Android.bp
index 0b974a1..8e9dace 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14895,6 +14895,7 @@
 filegroup {
     name: "perfetto_src_tracing_service_service",
     srcs: [
+        "src/tracing/service/clock.cc",
         "src/tracing/service/metatrace_writer.cc",
         "src/tracing/service/packet_stream_validator.cc",
         "src/tracing/service/trace_buffer.cc",
diff --git a/BUILD b/BUILD
index bbd999c..84cd949 100644
--- a/BUILD
+++ b/BUILD
@@ -3930,6 +3930,9 @@
 perfetto_filegroup(
     name = "src_tracing_service_service",
     srcs = [
+        "src/tracing/service/clock.cc",
+        "src/tracing/service/clock.h",
+        "src/tracing/service/dependencies.h",
         "src/tracing/service/histogram.h",
         "src/tracing/service/metatrace_writer.cc",
         "src/tracing/service/metatrace_writer.h",
diff --git a/src/tracing/service/BUILD.gn b/src/tracing/service/BUILD.gn
index f2eaa0e..b6c8750 100644
--- a/src/tracing/service/BUILD.gn
+++ b/src/tracing/service/BUILD.gn
@@ -38,6 +38,9 @@
     "../core",
   ]
   sources = [
+    "clock.cc",
+    "clock.h",
+    "dependencies.h",
     "histogram.h",
     "metatrace_writer.cc",
     "metatrace_writer.h",
diff --git a/src/tracing/service/clock.cc b/src/tracing/service/clock.cc
new file mode 100644
index 0000000..350115a
--- /dev/null
+++ b/src/tracing/service/clock.cc
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/tracing/service/clock.h"
+
+namespace perfetto::tracing_service {
+
+Clock::~Clock() = default;
+
+ClockImpl::~ClockImpl() = default;
+
+base::TimeNanos ClockImpl::GetBootTimeNs() {
+  return base::GetBootTimeNs();
+}
+
+base::TimeNanos ClockImpl::GetWallTimeNs() {
+  return base::GetWallTimeNs();
+}
+
+}  // namespace perfetto::tracing_service
diff --git a/src/tracing/service/clock.h b/src/tracing/service/clock.h
new file mode 100644
index 0000000..9fc9ef4
--- /dev/null
+++ b/src/tracing/service/clock.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_SERVICE_CLOCK_H_
+#define SRC_TRACING_SERVICE_CLOCK_H_
+
+#include "perfetto/base/time.h"
+
+namespace perfetto::tracing_service {
+
+class Clock {
+ public:
+  virtual ~Clock();
+  virtual base::TimeNanos GetBootTimeNs() = 0;
+  virtual base::TimeNanos GetWallTimeNs() = 0;
+
+  base::TimeMillis GetBootTimeMs() {
+    return std::chrono::duration_cast<base::TimeMillis>(GetBootTimeNs());
+  }
+  base::TimeMillis GetWallTimeMs() {
+    return std::chrono::duration_cast<base::TimeMillis>(GetWallTimeNs());
+  }
+
+  base::TimeSeconds GetBootTimeS() {
+    return std::chrono::duration_cast<base::TimeSeconds>(GetBootTimeNs());
+  }
+  base::TimeSeconds GetWallTimeS() {
+    return std::chrono::duration_cast<base::TimeSeconds>(GetWallTimeNs());
+  }
+};
+
+class ClockImpl : public Clock {
+ public:
+  ~ClockImpl() override;
+  base::TimeNanos GetBootTimeNs() override;
+  base::TimeNanos GetWallTimeNs() override;
+};
+
+}  // namespace perfetto::tracing_service
+
+#endif  // SRC_TRACING_SERVICE_CLOCK_H_
diff --git a/src/tracing/service/dependencies.h b/src/tracing/service/dependencies.h
new file mode 100644
index 0000000..cb2475c
--- /dev/null
+++ b/src/tracing/service/dependencies.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_SERVICE_DEPENDENCIES_H_
+#define SRC_TRACING_SERVICE_DEPENDENCIES_H_
+
+#include <memory>
+
+#include "src/tracing/service/clock.h"
+
+namespace perfetto::tracing_service {
+
+// Dependencies of TracingServiceImpl. Can point to real implementations or to
+// mocks in tests.
+struct Dependencies {
+  std::unique_ptr<Clock> clock;
+};
+
+}  // namespace perfetto::tracing_service
+
+#endif  // SRC_TRACING_SERVICE_DEPENDENCIES_H_
diff --git a/src/tracing/service/tracing_service_impl.cc b/src/tracing/service/tracing_service_impl.cc
index b01ec8b..487a34d 100644
--- a/src/tracing/service/tracing_service_impl.cc
+++ b/src/tracing/service/tracing_service_impl.cc
@@ -19,6 +19,7 @@
 #include <limits.h>
 #include <string.h>
 
+#include <algorithm>
 #include <cinttypes>
 #include <cstdint>
 #include <limits>
@@ -26,10 +27,6 @@
 #include <string>
 #include <unordered_set>
 
-#include "perfetto/base/time.h"
-#include "perfetto/ext/base/clock_snapshots.h"
-#include "perfetto/ext/tracing/core/client_identity.h"
-
 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
     !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
 #include <sys/uio.h>
@@ -50,12 +47,11 @@
 #include <sys/stat.h>
 #endif
 
-#include <algorithm>
-
 #include "perfetto/base/build_config.h"
 #include "perfetto/base/status.h"
 #include "perfetto/base/task_runner.h"
 #include "perfetto/ext/base/android_utils.h"
+#include "perfetto/ext/base/clock_snapshots.h"
 #include "perfetto/ext/base/file_utils.h"
 #include "perfetto/ext/base/metatrace.h"
 #include "perfetto/ext/base/string_utils.h"
@@ -66,6 +62,7 @@
 #include "perfetto/ext/base/version.h"
 #include "perfetto/ext/base/watchdog.h"
 #include "perfetto/ext/tracing/core/basic_types.h"
+#include "perfetto/ext/tracing/core/client_identity.h"
 #include "perfetto/ext/tracing/core/consumer.h"
 #include "perfetto/ext/tracing/core/observable_events.h"
 #include "perfetto/ext/tracing/core/producer.h"
@@ -336,21 +333,25 @@
     std::unique_ptr<SharedMemory::Factory> shm_factory,
     base::TaskRunner* task_runner,
     InitOpts init_opts) {
-  return std::unique_ptr<TracingService>(
-      new TracingServiceImpl(std::move(shm_factory), task_runner, init_opts));
+  tracing_service::Dependencies deps;
+  deps.clock = std::make_unique<tracing_service::ClockImpl>();
+  return std::unique_ptr<TracingService>(new TracingServiceImpl(
+      std::move(shm_factory), task_runner, std::move(deps), init_opts));
 }
 
 TracingServiceImpl::TracingServiceImpl(
     std::unique_ptr<SharedMemory::Factory> shm_factory,
     base::TaskRunner* task_runner,
+    tracing_service::Dependencies deps,
     InitOpts init_opts)
     : task_runner_(task_runner),
+      clock_(std::move(deps.clock)),
       init_opts_(init_opts),
       shm_factory_(std::move(shm_factory)),
       uid_(base::GetCurrentUserId()),
       buffer_ids_(kMaxTraceBufferID),
       trigger_probability_rand_(
-          static_cast<uint32_t>(base::GetWallTimeNs().count())),
+          static_cast<uint32_t>(clock_->GetWallTimeMs().count())),
       weak_ptr_factory_(this) {
   PERFETTO_DCHECK(task_runner_);
 }
@@ -835,7 +836,7 @@
   if (cfg.enable_extra_guardrails()) {
     // unique_session_name can be empty
     const std::string& name = cfg.unique_session_name();
-    int64_t now_s = base::GetBootTimeS().count();
+    int64_t now_s = clock_->GetBootTimeS().count();
 
     // Remove any entries where the time limit has passed so this map doesn't
     // grow indefinitely:
@@ -1254,6 +1255,14 @@
   }
 }
 
+uint32_t TracingServiceImpl::DelayToNextWritePeriodMs(
+    const TracingSession& session) {
+  PERFETTO_DCHECK(session.write_period_ms > 0);
+  return session.write_period_ms -
+         static_cast<uint32_t>(clock_->GetWallTimeMs().count() %
+                               session.write_period_ms);
+}
+
 void TracingServiceImpl::StartTracing(TracingSessionID tsid) {
   PERFETTO_DCHECK_THREAD(thread_checker_);
 
@@ -1343,7 +1352,7 @@
           if (weak_this)
             weak_this->ReadBuffersIntoFile(tsid);
         },
-        tracing_session->delay_to_next_write_period_ms());
+        DelayToNextWritePeriodMs(*tracing_session));
   }
 
   // Start the periodic flush tasks if the config specified a flush period.
@@ -1561,7 +1570,7 @@
     return;
   }
 
-  int64_t timestamp = base::GetBootTimeNs().count();
+  int64_t timestamp = clock_->GetBootTimeNs().count();
 
   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
   packet->set_timestamp(static_cast<uint64_t>(timestamp));
@@ -1671,7 +1680,7 @@
   auto* producer = GetProducer(producer_id);
   PERFETTO_DCHECK(producer);
 
-  int64_t now_ns = base::GetBootTimeNs().count();
+  int64_t now_ns = clock_->GetBootTimeNs().count();
   for (const auto& trigger_name : triggers) {
     PERFETTO_DLOG("Received ActivateTriggers request for \"%s\"",
                   trigger_name.c_str());
@@ -2023,7 +2032,7 @@
   if ((flush_flags.reason() == FlushFlags::Reason::kTraceClone ||
        flush_flags.reason() == FlushFlags::Reason::kTraceStop) &&
       !success) {
-    int64_t timestamp = base::GetBootTimeNs().count();
+    int64_t timestamp = clock_->GetBootTimeNs().count();
 
     protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
     packet->set_timestamp(static_cast<uint64_t>(timestamp));
@@ -2252,7 +2261,7 @@
         if (weak_this)
           weak_this->PeriodicFlushTask(tsid, /*post_next_only=*/false);
       },
-      flush_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
+      flush_period_ms - static_cast<uint32_t>(clock_->GetWallTimeMs().count() %
                                               flush_period_ms));
 
   if (post_next_only)
@@ -2286,7 +2295,7 @@
           weak_this->PeriodicClearIncrementalStateTask(
               tsid, /*post_next_only=*/false);
       },
-      clear_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
+      clear_period_ms - static_cast<uint32_t>(clock_->GetWallTimeMs().count() %
                                               clear_period_ms));
 
   if (post_next_only)
@@ -2422,7 +2431,7 @@
         if (weak_this)
           weak_this->ReadBuffersIntoFile(tsid);
       },
-      tracing_session->delay_to_next_write_period_ms());
+      DelayToNextWritePeriodMs(*tracing_session));
   return true;
 }
 
@@ -2650,7 +2659,7 @@
   // by the earlier call to SetFilterRoot() in EnableTracing().
   PERFETTO_DCHECK(trace_filter.config().root_msg_index() != 0);
   std::vector<protozero::MessageFilter::InputSlice> filter_input;
-  auto start = base::GetWallTimeNs();
+  auto start = clock_->GetWallTimeNs();
   for (TracePacket& packet : *packets) {
     const auto& packet_slices = packet.slices();
     const size_t input_packet_size = packet.size();
@@ -2690,7 +2699,7 @@
                               filtered_packet.size, kMaxTracePacketSliceSize,
                               &packet);
   }
-  auto end = base::GetWallTimeNs();
+  auto end = clock_->GetWallTimeNs();
   tracing_session->filter_time_taken_ns +=
       static_cast<uint64_t>((end - start).count());
 }
@@ -3449,7 +3458,7 @@
     event->timestamps.erase_front(1 + event->timestamps.size() -
                                   event->max_size);
   }
-  event->timestamps.emplace_back(base::GetBootTimeNs().count());
+  event->timestamps.emplace_back(clock_->GetBootTimeNs().count());
 }
 
 void TracingServiceImpl::MaybeSnapshotClocksIntoRingBuffer(
diff --git a/src/tracing/service/tracing_service_impl.h b/src/tracing/service/tracing_service_impl.h
index 51cad75..346f6de 100644
--- a/src/tracing/service/tracing_service_impl.h
+++ b/src/tracing/service/tracing_service_impl.h
@@ -49,6 +49,8 @@
 #include "perfetto/tracing/core/trace_config.h"
 #include "src/android_stats/perfetto_atoms.h"
 #include "src/tracing/core/id_allocator.h"
+#include "src/tracing/service/clock.h"
+#include "src/tracing/service/dependencies.h"
 
 namespace protozero {
 class MessageFilter;
@@ -312,6 +314,7 @@
 
   explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>,
                               base::TaskRunner*,
+                              tracing_service::Dependencies,
                               InitOpts = {});
   ~TracingServiceImpl() override;
 
@@ -511,13 +514,6 @@
 
     size_t num_buffers() const { return buffers_index.size(); }
 
-    uint32_t delay_to_next_write_period_ms() const {
-      PERFETTO_DCHECK(write_period_ms > 0);
-      return write_period_ms -
-             static_cast<uint32_t>(base::GetWallTimeMs().count() %
-                                   write_period_ms);
-    }
-
     uint32_t flush_timeout_ms() {
       uint32_t timeout_ms = config.flush_timeout_ms();
       return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs;
@@ -783,6 +779,7 @@
   // shared memory and trace buffers.
   void UpdateMemoryGuardrail();
 
+  uint32_t DelayToNextWritePeriodMs(const TracingSession&);
   void StartDataSourceInstance(ProducerEndpointImpl*,
                                TracingSession*,
                                DataSourceInstance*);
@@ -887,6 +884,7 @@
                                      TracingSessionID);
 
   base::TaskRunner* const task_runner_;
+  std::unique_ptr<tracing_service::Clock> clock_;
   const InitOpts init_opts_;
   std::unique_ptr<SharedMemory::Factory> shm_factory_;
   ProducerID last_producer_id_ = 0;