DO NOT MERGE IpConnectivityMetrics: rate limit ApfProgramEvents

This patch uses the previously introduced TokenBucket to rate limit
ApfProgramEvents, still allowing for burst of ApfProgramEvents when a
new interface is set up (due to ipv4 provisioning, multicast lock, ipv6 RAs
triggering new APF program events in short amounts of time).

Test: new test in IpConnectivityMetricsTest
Bug: 1550402

(cherry picked from commit e1c173d2240a8eedf7685c9371087dc047a6931f)

Change-Id: Ibe41e9a76db36ea502697a5f19fc0d91c40a3087
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
index 2936e39..da2c0d9 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
+import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.ApfStats;
 import android.net.metrics.DefaultNetworkEvent;
 import android.net.metrics.DhcpClientEvent;
@@ -112,6 +113,27 @@
         assertEquals("", output3);
     }
 
+    public void testRateLimiting() {
+        final IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
+        final ApfProgramEvent ev = new ApfProgramEvent(0, 0, 0, 0, 0);
+        final long fakeTimestamp = 1;
+
+        int attempt = 100; // More than burst quota, but less than buffer size.
+        for (int i = 0; i < attempt; i++) {
+            logger.log(ev);
+        }
+
+        String output1 = getdump("flush");
+        assertFalse("".equals(output1));
+
+        for (int i = 0; i < attempt; i++) {
+            assertFalse("expected event to be dropped", logger.log(fakeTimestamp, ev));
+        }
+
+        String output2 = getdump("flush");
+        assertEquals("", output2);
+    }
+
     public void testEndToEndLogging() {
         IpConnectivityLog logger = new IpConnectivityLog(mService.impl);