Change unit of I/O statistics to MiB

I/O in bytes are too large and it may cause overflow. Moreover, data with
large numbers are grouped in the same bucket of the histogram. This adds
difficulty to the analysis. Changing unit of I/O to MiB so that we can
have a better data distribution.

Bug: 28658632
Change-Id: Id9913d71e62b36ce5d5d2e57676953f4dbd0c7c9
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 4abbf0e..6c21398 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -687,12 +687,13 @@
         }
     }
 
-    // Read last_install; then report time for update and I/O to tron.
+    // Read last_install; then report time (in seconds) and I/O (in MiB) for
+    // this update to tron.
     // Only report on the reboots immediately after an OTA update.
     private static void parseLastInstallLog(Context context) {
         try (BufferedReader in = new BufferedReader(new FileReader(LAST_INSTALL_FILE))) {
             String line = null;
-            int bytesWritten = -1, bytesStashed = -1;
+            int bytesWrittenInMiB = -1, bytesStashedInMiB = -1;
             int timeTotal = -1;
             while ((line = in.readLine()) != null) {
                 // Here is an example of lines in last_install:
@@ -705,20 +706,35 @@
                     continue;
                 }
                 String numString = line.substring(numIndex + 1).trim();
-                int parsedNum;
+                long parsedNum;
                 try {
-                    parsedNum = Integer.parseInt(numString);
+                    parsedNum = Long.parseLong(numString);
                 } catch (NumberFormatException ignored) {
                     Log.e(TAG, "Failed to parse numbers in " + line);
                     continue;
                 }
 
+                final int MiB = 1024 * 1024;
+                int scaled;
+                try {
+                    if (line.startsWith("bytes")) {
+                        scaled = Math.toIntExact(parsedNum / MiB);
+                    } else {
+                        scaled = Math.toIntExact(parsedNum);
+                    }
+                } catch (ArithmeticException ignored) {
+                    Log.e(TAG, "Number overflows in " + line);
+                    continue;
+                }
+
                 if (line.startsWith("time")) {
-                    timeTotal = parsedNum;
+                    timeTotal = scaled;
                 } else if (line.startsWith("bytes_written")) {
-                    bytesWritten = (bytesWritten == -1) ? parsedNum : bytesWritten + parsedNum;
+                    bytesWrittenInMiB = (bytesWrittenInMiB == -1) ? scaled :
+                            bytesWrittenInMiB + scaled;
                 } else if (line.startsWith("bytes_stashed")) {
-                    bytesStashed = (bytesStashed == -1) ? parsedNum : bytesStashed + parsedNum;
+                    bytesStashedInMiB = (bytesStashedInMiB == -1) ? scaled :
+                            bytesStashedInMiB + scaled;
                 }
             }
 
@@ -726,15 +742,15 @@
             if (timeTotal != -1) {
                 MetricsLogger.histogram(context, "ota_time_total", timeTotal);
             }
-            if (bytesWritten != -1) {
-                MetricsLogger.histogram(context, "ota_bytes_written", bytesWritten);
+            if (bytesWrittenInMiB != -1) {
+                MetricsLogger.histogram(context, "ota_written_in_MiBs", bytesWrittenInMiB);
             }
-            if (bytesStashed != -1) {
-                MetricsLogger.histogram(context, "ota_bytes_stashed", bytesStashed);
+            if (bytesStashedInMiB != -1) {
+                MetricsLogger.histogram(context, "ota_stashed_in_MiBs", bytesStashedInMiB);
             }
 
-        } catch (IOException ignored) {
-            Log.e(TAG, "Failed to read lines in last_install", ignored);
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to read lines in last_install", e);
         }
     }