Move NetworkTracePoller to a new file

This finishes the split of NetworkTraceHandler into separate DataSource
and Polling parts by moving the Polling part to its own file.

Despite being a large diff, all this change did was copy the
NetworkTraceHandler files to their NetworkTracePoller counterparts and
delete the irrelevant sections in each file. The actual content of the
classes and functions should be identical.

Bug: 246985031
Test: atest libnetworkstats_test
Change-Id: Ibc9d945658e89f969fa3d1551863ccd26fd51a78
diff --git a/service-t/native/libs/libnetworkstats/Android.bp b/service-t/native/libs/libnetworkstats/Android.bp
index aa1ee41..f2c569f 100644
--- a/service-t/native/libs/libnetworkstats/Android.bp
+++ b/service-t/native/libs/libnetworkstats/Android.bp
@@ -26,6 +26,7 @@
     srcs: [
         "BpfNetworkStats.cpp",
         "NetworkTraceHandler.cpp",
+        "NetworkTracePoller.cpp",
     ],
     shared_libs: [
         "libbase",
@@ -61,7 +62,7 @@
     header_libs: ["bpf_connectivity_headers"],
     srcs: [
         "BpfNetworkStatsTest.cpp",
-        "NetworkTraceHandlerTest.cpp",
+        "NetworkTracePollerTest.cpp",
     ],
     cflags: [
         "-Wall",
diff --git a/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp b/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
index be4ffe3..8e70950 100644
--- a/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
+++ b/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
@@ -33,6 +33,7 @@
 
 namespace android {
 namespace bpf {
+using ::android::bpf::internal::NetworkTracePoller;
 using ::perfetto::protos::pbzero::NetworkPacketEvent;
 using ::perfetto::protos::pbzero::NetworkPacketTraceConfig;
 using ::perfetto::protos::pbzero::TracePacket;
@@ -82,18 +83,6 @@
   mStarted = false;
 }
 
-void NetworkTracePoller::SchedulePolling() {
-  // Schedules another run of ourselves to recursively poll periodically.
-  mTaskRunner->PostDelayedTask(
-      [this]() {
-        mMutex.lock();
-        SchedulePolling();
-        ConsumeAllLocked();
-        mMutex.unlock();
-      },
-      mPollMs);
-}
-
 // static class method
 void NetworkTraceHandler::Fill(const PacketTrace& src, TracePacket& dst) {
   dst.set_timestamp(src.timestampNs);
@@ -118,91 +107,5 @@
   }
 }
 
-bool NetworkTracePoller::Start(uint32_t pollMs) {
-  ALOGD("Starting datasource");
-
-  std::scoped_lock<std::mutex> lock(mMutex);
-  if (mSessionCount > 0) {
-    if (mPollMs != pollMs) {
-      // Nothing technical prevents mPollMs from changing, it's just unclear
-      // what the right behavior is. Taking the min of active values could poll
-      // too frequently giving some sessions too much data. Taking the max could
-      // be too infrequent. For now, do nothing.
-      ALOGI("poll_ms can't be changed while running, ignoring poll_ms=%d",
-            pollMs);
-    }
-    mSessionCount++;
-    return true;
-  }
-
-  auto status = mConfigurationMap.init(PACKET_TRACE_ENABLED_MAP_PATH);
-  if (!status.ok()) {
-    ALOGW("Failed to bind config map: %s", status.error().message().c_str());
-    return false;
-  }
-
-  auto rb = BpfRingbuf<PacketTrace>::Create(PACKET_TRACE_RINGBUF_PATH);
-  if (!rb.ok()) {
-    ALOGW("Failed to create ringbuf: %s", rb.error().message().c_str());
-    return false;
-  }
-
-  mRingBuffer = std::move(*rb);
-
-  auto res = mConfigurationMap.writeValue(0, true, BPF_ANY);
-  if (!res.ok()) {
-    ALOGW("Failed to enable tracing: %s", res.error().message().c_str());
-    return false;
-  }
-
-  // Start a task runner to run ConsumeAll every mPollMs milliseconds.
-  mTaskRunner = perfetto::Platform::GetDefaultPlatform()->CreateTaskRunner({});
-  mPollMs = pollMs;
-  SchedulePolling();
-
-  mSessionCount++;
-  return true;
-}
-
-bool NetworkTracePoller::Stop() {
-  ALOGD("Stopping datasource");
-
-  std::scoped_lock<std::mutex> lock(mMutex);
-  if (mSessionCount == 0) return false;  // This should never happen
-
-  // If this isn't the last session, don't clean up yet.
-  if (--mSessionCount > 0) return true;
-
-  auto res = mConfigurationMap.writeValue(0, false, BPF_ANY);
-  if (!res.ok()) {
-    ALOGW("Failed to disable tracing: %s", res.error().message().c_str());
-  }
-
-  mTaskRunner.reset();
-  mRingBuffer.reset();
-
-  return res.ok();
-}
-
-bool NetworkTracePoller::ConsumeAll() {
-  std::scoped_lock<std::mutex> lock(mMutex);
-  return ConsumeAllLocked();
-}
-
-bool NetworkTracePoller::ConsumeAllLocked() {
-  if (mRingBuffer == nullptr) {
-    ALOGW("Tracing is not active");
-    return false;
-  }
-
-  base::Result<int> ret = mRingBuffer->ConsumeAll(mCallback);
-  if (!ret.ok()) {
-    ALOGW("Failed to poll ringbuf: %s", ret.error().message().c_str());
-    return false;
-  }
-
-  return true;
-}
-
 }  // namespace bpf
 }  // namespace android
diff --git a/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp b/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp
new file mode 100644
index 0000000..34dbf9e
--- /dev/null
+++ b/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#define LOG_TAG "NetworkTrace"
+
+#include "netdbpf/NetworkTracePoller.h"
+
+#include <bpf/BpfUtils.h>
+#include <log/log.h>
+#include <perfetto/tracing/platform.h>
+#include <perfetto/tracing/tracing.h>
+
+namespace android {
+namespace bpf {
+namespace internal {
+
+void NetworkTracePoller::SchedulePolling() {
+  // Schedules another run of ourselves to recursively poll periodically.
+  mTaskRunner->PostDelayedTask(
+      [this]() {
+        mMutex.lock();
+        SchedulePolling();
+        ConsumeAllLocked();
+        mMutex.unlock();
+      },
+      mPollMs);
+}
+
+bool NetworkTracePoller::Start(uint32_t pollMs) {
+  ALOGD("Starting datasource");
+
+  std::scoped_lock<std::mutex> lock(mMutex);
+  if (mSessionCount > 0) {
+    if (mPollMs != pollMs) {
+      // Nothing technical prevents mPollMs from changing, it's just unclear
+      // what the right behavior is. Taking the min of active values could poll
+      // too frequently giving some sessions too much data. Taking the max could
+      // be too infrequent. For now, do nothing.
+      ALOGI("poll_ms can't be changed while running, ignoring poll_ms=%d",
+            pollMs);
+    }
+    mSessionCount++;
+    return true;
+  }
+
+  auto status = mConfigurationMap.init(PACKET_TRACE_ENABLED_MAP_PATH);
+  if (!status.ok()) {
+    ALOGW("Failed to bind config map: %s", status.error().message().c_str());
+    return false;
+  }
+
+  auto rb = BpfRingbuf<PacketTrace>::Create(PACKET_TRACE_RINGBUF_PATH);
+  if (!rb.ok()) {
+    ALOGW("Failed to create ringbuf: %s", rb.error().message().c_str());
+    return false;
+  }
+
+  mRingBuffer = std::move(*rb);
+
+  auto res = mConfigurationMap.writeValue(0, true, BPF_ANY);
+  if (!res.ok()) {
+    ALOGW("Failed to enable tracing: %s", res.error().message().c_str());
+    return false;
+  }
+
+  // Start a task runner to run ConsumeAll every mPollMs milliseconds.
+  mTaskRunner = perfetto::Platform::GetDefaultPlatform()->CreateTaskRunner({});
+  mPollMs = pollMs;
+  SchedulePolling();
+
+  mSessionCount++;
+  return true;
+}
+
+bool NetworkTracePoller::Stop() {
+  ALOGD("Stopping datasource");
+
+  std::scoped_lock<std::mutex> lock(mMutex);
+  if (mSessionCount == 0) return false;  // This should never happen
+
+  // If this isn't the last session, don't clean up yet.
+  if (--mSessionCount > 0) return true;
+
+  auto res = mConfigurationMap.writeValue(0, false, BPF_ANY);
+  if (!res.ok()) {
+    ALOGW("Failed to disable tracing: %s", res.error().message().c_str());
+  }
+
+  mTaskRunner.reset();
+  mRingBuffer.reset();
+
+  return res.ok();
+}
+
+bool NetworkTracePoller::ConsumeAll() {
+  std::scoped_lock<std::mutex> lock(mMutex);
+  return ConsumeAllLocked();
+}
+
+bool NetworkTracePoller::ConsumeAllLocked() {
+  if (mRingBuffer == nullptr) {
+    ALOGW("Tracing is not active");
+    return false;
+  }
+
+  base::Result<int> ret = mRingBuffer->ConsumeAll(mCallback);
+  if (!ret.ok()) {
+    ALOGW("Failed to poll ringbuf: %s", ret.error().message().c_str());
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace internal
+}  // namespace bpf
+}  // namespace android
diff --git a/service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp b/service-t/native/libs/libnetworkstats/NetworkTracePollerTest.cpp
similarity index 98%
rename from service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp
rename to service-t/native/libs/libnetworkstats/NetworkTracePollerTest.cpp
index 543be21..28ec208 100644
--- a/service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp
+++ b/service-t/native/libs/libnetworkstats/NetworkTracePollerTest.cpp
@@ -28,7 +28,7 @@
 
 #include <vector>
 
-#include "netdbpf/NetworkTraceHandler.h"
+#include "netdbpf/NetworkTracePoller.h"
 
 using ::testing::AllOf;
 using ::testing::AnyOf;
@@ -39,6 +39,7 @@
 
 namespace android {
 namespace bpf {
+namespace internal {
 // Use uint32 max to cause the handler to never Loop. Instead, the tests will
 // manually drive things by calling ConsumeAll explicitly.
 constexpr uint32_t kNeverPoll = std::numeric_limits<uint32_t>::max();
@@ -218,5 +219,6 @@
       << PacketPrinter{packets};
 }
 
+}  // namespace internal
 }  // namespace bpf
 }  // namespace android
diff --git a/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTraceHandler.h b/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTraceHandler.h
index 3f244b3..1266237 100644
--- a/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTraceHandler.h
+++ b/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTraceHandler.h
@@ -22,9 +22,7 @@
 #include <string>
 #include <unordered_map>
 
-#include "android-base/thread_annotations.h"
-#include "bpf/BpfMap.h"
-#include "bpf/BpfRingbuf.h"
+#include "netdbpf/NetworkTracePoller.h"
 
 // For PacketTrace struct definition
 #include "netd.h"
@@ -32,53 +30,6 @@
 namespace android {
 namespace bpf {
 
-// NetworkTracePoller is responsible for interactions with the BPF ring buffer
-// including polling. This class is an internal helper for NetworkTraceHandler,
-// it is not meant to be used elsewhere.
-class NetworkTracePoller {
- public:
-  // Testonly: initialize with a callback capable of intercepting data.
-  NetworkTracePoller(std::function<void(const PacketTrace&)> callback)
-      : mCallback(std::move(callback)) {}
-
-  // Starts tracing with the given poll interval.
-  bool Start(uint32_t pollMs) EXCLUDES(mMutex);
-
-  // Stops tracing and release any held state.
-  bool Stop() EXCLUDES(mMutex);
-
-  // Consumes all available events from the ringbuffer.
-  bool ConsumeAll() EXCLUDES(mMutex);
-
- private:
-  void SchedulePolling() REQUIRES(mMutex);
-  bool ConsumeAllLocked() REQUIRES(mMutex);
-
-  std::mutex mMutex;
-
-  // Records the number of successfully started active sessions so that only the
-  // first active session attempts setup and only the last cleans up. Note that
-  // the session count will remain zero if Start fails. It is expected that Stop
-  // will not be called for any trace session where Start fails.
-  int mSessionCount GUARDED_BY(mMutex);
-
-  // How often to poll the ring buffer, defined by the trace config.
-  uint32_t mPollMs GUARDED_BY(mMutex);
-
-  // The function to process PacketTrace, typically a Perfetto sink.
-  std::function<void(const PacketTrace&)> mCallback GUARDED_BY(mMutex);
-
-  // The BPF ring buffer handle.
-  std::unique_ptr<BpfRingbuf<PacketTrace>> mRingBuffer GUARDED_BY(mMutex);
-
-  // The packet tracing config map (really a 1-element array).
-  BpfMap<uint32_t, bool> mConfigurationMap GUARDED_BY(mMutex);
-
-  // This must be the last member, causing it to be the first deleted. If it is
-  // not, members required for callbacks can be deleted before it's stopped.
-  std::unique_ptr<perfetto::base::TaskRunner> mTaskRunner GUARDED_BY(mMutex);
-};
-
 // NetworkTraceHandler implements the android.network_packets data source. This
 // class is registered with Perfetto and is instantiated when tracing starts and
 // destroyed when tracing ends. There is one instance per trace session.
@@ -100,7 +51,7 @@
   static void Fill(const PacketTrace& src,
                    ::perfetto::protos::pbzero::TracePacket& dst);
 
-  static NetworkTracePoller sPoller;
+  static internal::NetworkTracePoller sPoller;
   uint32_t mPollMs;
   bool mStarted;
 };
diff --git a/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTracePoller.h b/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTracePoller.h
new file mode 100644
index 0000000..b0189a7
--- /dev/null
+++ b/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTracePoller.h
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2023, 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.
+ */
+
+#pragma once
+
+#include <perfetto/base/task_runner.h>
+#include <perfetto/tracing.h>
+
+#include <string>
+#include <unordered_map>
+
+#include "android-base/thread_annotations.h"
+#include "bpf/BpfMap.h"
+#include "bpf/BpfRingbuf.h"
+
+// For PacketTrace struct definition
+#include "netd.h"
+
+namespace android {
+namespace bpf {
+namespace internal {
+
+// NetworkTracePoller is responsible for interactions with the BPF ring buffer
+// including polling. This class is an internal helper for NetworkTraceHandler,
+// it is not meant to be used elsewhere.
+class NetworkTracePoller {
+ public:
+  // Testonly: initialize with a callback capable of intercepting data.
+  NetworkTracePoller(std::function<void(const PacketTrace&)> callback)
+      : mCallback(std::move(callback)) {}
+
+  // Starts tracing with the given poll interval.
+  bool Start(uint32_t pollMs) EXCLUDES(mMutex);
+
+  // Stops tracing and release any held state.
+  bool Stop() EXCLUDES(mMutex);
+
+  // Consumes all available events from the ringbuffer.
+  bool ConsumeAll() EXCLUDES(mMutex);
+
+ private:
+  void SchedulePolling() REQUIRES(mMutex);
+  bool ConsumeAllLocked() REQUIRES(mMutex);
+
+  std::mutex mMutex;
+
+  // Records the number of successfully started active sessions so that only the
+  // first active session attempts setup and only the last cleans up. Note that
+  // the session count will remain zero if Start fails. It is expected that Stop
+  // will not be called for any trace session where Start fails.
+  int mSessionCount GUARDED_BY(mMutex);
+
+  // How often to poll the ring buffer, defined by the trace config.
+  uint32_t mPollMs GUARDED_BY(mMutex);
+
+  // The function to process PacketTrace, typically a Perfetto sink.
+  std::function<void(const PacketTrace&)> mCallback GUARDED_BY(mMutex);
+
+  // The BPF ring buffer handle.
+  std::unique_ptr<BpfRingbuf<PacketTrace>> mRingBuffer GUARDED_BY(mMutex);
+
+  // The packet tracing config map (really a 1-element array).
+  BpfMap<uint32_t, bool> mConfigurationMap GUARDED_BY(mMutex);
+
+  // This must be the last member, causing it to be the first deleted. If it is
+  // not, members required for callbacks can be deleted before it's stopped.
+  std::unique_ptr<perfetto::base::TaskRunner> mTaskRunner GUARDED_BY(mMutex);
+};
+
+}  // namespace internal
+}  // namespace bpf
+}  // namespace android