Wifi Metrics: dumpsys arg for clean output

Modify the way dumpsys works in wifi so that
'dumpsys wifi wifiMetricsProto clean'
outputs only serialized base64 encoded wifi metrics proto bytes.

BUG=31556602
Test: Created new unit test

Change-Id: Id1aa319a03a5e2bcffb1276057cb770679015abd
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 643060b..11daa29 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -902,9 +902,11 @@
     }
 
     public static final String PROTO_DUMP_ARG = "wifiMetricsProto";
+    public static final String CLEAN_DUMP_ARG = "clean";
+
     /**
      * Dump all WifiMetrics. Collects some metrics from ConfigStore, Settings and WifiManager
-     * at this time
+     * at this time.
      *
      * @param fd unused
      * @param pw PrintWriter for writing dump to
@@ -912,9 +914,8 @@
      */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         synchronized (mLock) {
-            pw.println("WifiMetrics:");
             if (args.length > 0 && PROTO_DUMP_ARG.equals(args[0])) {
-                //Dump serialized WifiLog proto
+                // Dump serialized WifiLog proto
                 consolidateProto(true);
                 for (ConnectionEvent event : mConnectionEventList) {
                     if (mCurrentConnectionEvent != event) {
@@ -925,10 +926,18 @@
                 }
                 byte[] wifiMetricsProto = WifiMetricsProto.WifiLog.toByteArray(mWifiLogProto);
                 String metricsProtoDump = Base64.encodeToString(wifiMetricsProto, Base64.DEFAULT);
-                pw.println(metricsProtoDump);
-                pw.println("EndWifiMetrics");
+                if (args.length > 1 && CLEAN_DUMP_ARG.equals(args[1])) {
+                    // Output metrics proto bytes (base64) and nothing else
+                    pw.print(metricsProtoDump);
+                } else {
+                    // Tag the start and end of the metrics proto bytes
+                    pw.println("WifiMetrics:");
+                    pw.println(metricsProtoDump);
+                    pw.println("EndWifiMetrics");
+                }
                 clear();
             } else {
+                pw.println("WifiMetrics:");
                 pw.println("mConnectionEvents:");
                 for (ConnectionEvent event : mConnectionEventList) {
                     String eventLine = event.toString();
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index f47e751..1988c21 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -2305,6 +2305,13 @@
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (args.length > 1 && WifiMetrics.PROTO_DUMP_ARG.equals(args[0])
+                && WifiMetrics.CLEAN_DUMP_ARG.equals(args[1])) {
+            // Dump only wifi metrics serialized proto bytes (base64)
+            updateWifiMetrics();
+            mWifiMetrics.dump(fd, pw, args);
+            return;
+        }
         super.dump(fd, pw, args);
         mSupplicantStateTracker.dump(fd, pw, args);
         pw.println("mLinkProperties " + mLinkProperties);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index cf8204b..5cd1466 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -106,6 +106,25 @@
         mDeserializedWifiMetrics = WifiMetricsProto.WifiLog.parseFrom(protoBytes);
     }
 
+    /**
+     * Gets the 'clean dump' proto bytes from mWifiMetrics & deserializes it into
+     * mDeserializedWifiMetrics
+     */
+    public void cleanDumpProtoAndDeserialize() throws Exception {
+        ByteArrayOutputStream stream = new ByteArrayOutputStream();
+        PrintWriter writer = new PrintWriter(stream);
+        String[] args = new String[0];
+
+        when(mClock.elapsedRealtime()).thenReturn(TEST_RECORD_DURATION_MILLIS);
+        //Test proto dump, by passing in proto arg option
+        args = new String[]{WifiMetrics.PROTO_DUMP_ARG, WifiMetrics.CLEAN_DUMP_ARG};
+        mWifiMetrics.dump(null, writer, args);
+        writer.flush();
+        String protoByteString = stream.toString();
+        byte[] protoBytes = Base64.decode(protoByteString, Base64.DEFAULT);
+        mDeserializedWifiMetrics = WifiMetricsProto.WifiLog.parseFrom(protoBytes);
+    }
+
     /** Verifies that dump() includes the expected header */
     @Test
     public void stateDumpIncludesHeader() throws Exception {
@@ -583,6 +602,20 @@
         assertEquals(mDeserializedWifiMetrics.connectionEvent.length, 2);
     }
 
+    /**
+     * Tests that after setting metrics values they can be serialized and deserialized with the
+     *   $ adb shell dumpsys wifi wifiMetricsProto clean
+     */
+    @Test
+    public void testClearMetricsDump() throws Exception {
+        setAndIncrementMetrics();
+        startAndEndConnectionEventSucceeds();
+        cleanDumpProtoAndDeserialize();
+        assertDeserializedMetricsCorrect();
+        assertEquals("mDeserializedWifiMetrics.connectionEvent.length",
+                2, mDeserializedWifiMetrics.connectionEvent.length);
+    }
+
     private void assertStringContains(
             String actualString, String expectedSubstring) {
         assertTrue("Expected text not found in: " + actualString,