Merge "Tcp socket metrics: define INetdEventListener callback"
diff --git a/server/TcpSocketMonitor.cpp b/server/TcpSocketMonitor.cpp
index a6d71b7..89d1be2 100644
--- a/server/TcpSocketMonitor.cpp
+++ b/server/TcpSocketMonitor.cpp
@@ -24,6 +24,7 @@
 #include <netinet/tcp.h>
 #include <linux/tcp.h>
 
+#include "Controllers.h"
 #include "DumpWriter.h"
 #include "SockDiag.h"
 #include "TcpSocketMonitor.h"
@@ -223,6 +224,28 @@
             it++;
         }
     }
+
+    const auto listener = gCtls->eventReporter.getNetdEventListener();
+    if (listener != nullptr) {
+        std::vector<int> netIds;
+        std::vector<int> sentPackets;
+        std::vector<int> lostPackets;
+        std::vector<int> rtts;
+        std::vector<int> sentAckDiffs;
+        for (auto const& stats : mNetworkStats) {
+            int32_t nSockets = stats.second.nSockets;
+            if (nSockets == 0) {
+                continue;
+            }
+            netIds.push_back(stats.first);
+            sentPackets.push_back(stats.second.sent);
+            lostPackets.push_back(stats.second.lost);
+            rtts.push_back(stats.second.rttUs / nSockets);
+            sentAckDiffs.push_back(stats.second.sentAckDiffMs / nSockets);
+        }
+        listener->onTcpSocketStatsEvent(netIds, sentPackets, lostPackets, rtts, sentAckDiffs);
+    }
+
     mLastPoll = now;
 }
 
diff --git a/server/TcpSocketMonitor.h b/server/TcpSocketMonitor.h
index f408ff0..98cd766 100644
--- a/server/TcpSocketMonitor.h
+++ b/server/TcpSocketMonitor.h
@@ -20,6 +20,7 @@
 #include <chrono>
 #include <condition_variable>
 #include <mutex>
+#include <thread>
 #include <unordered_map>
 
 #include <android-base/thread_annotations.h>
@@ -27,6 +28,9 @@
 
 #include "Fwmark.h"
 
+struct inet_diag_msg;
+struct tcp_info;
+
 namespace android {
 namespace net {
 
diff --git a/server/binder/android/net/metrics/INetdEventListener.aidl b/server/binder/android/net/metrics/INetdEventListener.aidl
index 2601038..cfb2630 100644
--- a/server/binder/android/net/metrics/INetdEventListener.aidl
+++ b/server/binder/android/net/metrics/INetdEventListener.aidl
@@ -78,4 +78,24 @@
      */
     void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader, in byte[] dstHw,
             String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs);
+
+    /**
+     * An event sent after every Netlink sock_diag poll performed by Netd. This reported batch
+     * groups TCP socket stats aggregated by network id. Per-network data are stored in a
+     * structure-of-arrays style where networkIds, sentPackets, lostPackets, rttUs, and
+     * sentAckDiffMs have the same length. Stats for the i-th network is spread across all these
+     * arrays at index i.
+     * @param networkIds an array of network ids for which there was tcp socket stats to collect in
+     *        the last sock_diag poll.
+     * @param sentPackets an array of packet sent across all TCP sockets still alive and new
+              TCP sockets since the last sock_diag poll, summed per network id.
+     * @param lostPackets, an array of packet lost across all TCP sockets still alive and new
+              TCP sockets since the last sock_diag poll, summed per network id.
+     * @param rttUs an array of smoothed round trip times in microseconds, averaged across all TCP
+              sockets since the last sock_diag poll for a given network id.
+     * @param sentAckDiffMs an array of milliseconds duration between the last packet sent and the
+              last ack received for a socket, averaged across all TCP sockets for a network id.
+     */
+    void onTcpSocketStatsEvent(in int[] networkIds, in int[] sentPackets,
+            in int[] lostPackets, in int[] rttUs, in int[] sentAckDiffMs);
 }