Change gfx-avg-jank and gfx-max-jank to percentages

Change-Id: I07499945458620dabbd4f1cb82235b65dfd1681d
diff --git a/src/main/java/android/support/test/jank/internal/GfxMonitorImpl.java b/src/main/java/android/support/test/jank/internal/GfxMonitorImpl.java
index 15077ee..c1f7b9b 100644
--- a/src/main/java/android/support/test/jank/internal/GfxMonitorImpl.java
+++ b/src/main/java/android/support/test/jank/internal/GfxMonitorImpl.java
@@ -44,24 +44,29 @@
 
     // Patterns used for parsing dumpsys gfxinfo output
     public enum JankStat {
-        TOTAL_FRAMES(Pattern.compile("\\s*Total frames rendered: (\\d+)"), 1),
-        NUM_JANKY(Pattern.compile("\\s*Janky frames: (\\d+) \\(.*\\)"), 1),
-        FRAME_TIME_90TH(Pattern.compile("\\s*90th percentile: (\\d+)ms"), 1),
-        FRAME_TIME_95TH(Pattern.compile("\\s*95th percentile: (\\d+)ms"), 1),
-        FRAME_TIME_99TH(Pattern.compile("\\s*99th percentile: (\\d+)ms"), 1),
-        NUM_MISSED_VSYNC(Pattern.compile("\\s*Number Missed Vsync: (\\d+)"), 1),
-        NUM_HIGH_INPUT_LATENCY(Pattern.compile("\\s*Number High input latency: (\\d+)"), 1),
-        NUM_SLOW_UI_THREAD(Pattern.compile("\\s*Number Slow UI thread: (\\d+)"), 1),
-        NUM_SLOW_BITMAP_UPLOADS(Pattern.compile("\\s*Number Slow bitmap uploads: (\\d+)"), 1),
-        NUM_SLOW_DRAW(Pattern.compile("\\s*Number Slow draw: (\\d+)"), 1);
+        TOTAL_FRAMES(Pattern.compile("\\s*Total frames rendered: (\\d+)"), 1, Integer.class),
+        NUM_JANKY(Pattern.compile("\\s*Janky frames: (\\d+) \\((\\d+(\\.\\d+))%\\)"), 2,
+                Double.class),
+        FRAME_TIME_90TH(Pattern.compile("\\s*90th percentile: (\\d+)ms"), 1, Integer.class),
+        FRAME_TIME_95TH(Pattern.compile("\\s*95th percentile: (\\d+)ms"), 1, Integer.class),
+        FRAME_TIME_99TH(Pattern.compile("\\s*99th percentile: (\\d+)ms"), 1, Integer.class),
+        NUM_MISSED_VSYNC(Pattern.compile("\\s*Number Missed Vsync: (\\d+)"), 1, Integer.class),
+        NUM_HIGH_INPUT_LATENCY(Pattern.compile("\\s*Number High input latency: (\\d+)"), 1,
+                Integer.class),
+        NUM_SLOW_UI_THREAD(Pattern.compile("\\s*Number Slow UI thread: (\\d+)"), 1, Integer.class),
+        NUM_SLOW_BITMAP_UPLOADS(Pattern.compile("\\s*Number Slow bitmap uploads: (\\d+)"), 1,
+                Integer.class),
+        NUM_SLOW_DRAW(Pattern.compile("\\s*Number Slow draw: (\\d+)"), 1, Integer.class);
 
         private boolean mSuccessfulParse = false;
         private Pattern mParsePattern;
         private int mGroupIndex;
+        private Class mType;
 
-        JankStat(Pattern pattern, int groupIndex) {
+        JankStat(Pattern pattern, int groupIndex, Class type) {
             mParsePattern = pattern;
             mGroupIndex = groupIndex;
+            mType = type;
         }
 
         String parse(String line) {
@@ -81,11 +86,16 @@
         void reset() {
             mSuccessfulParse = false;
         }
+
+        Class getType() {
+            return mType;
+        }
     }
 
     // Metrics accumulated for each iteration
-    private Map<JankStat, List<Integer>> mAccumulatedStats =
-            new EnumMap<JankStat, List<Integer>>(JankStat.class);
+    private Map<JankStat, List<? extends Number>> mAccumulatedStats =
+            new EnumMap<JankStat, List<? extends Number>>(JankStat.class);
+
 
     // Used to invoke dumpsys gfxinfo
     private UiAutomation mUiAutomation;
@@ -97,7 +107,14 @@
         mProcess = process;
 
         for (JankStat stat : JankStat.values()) {
-            mAccumulatedStats.put(stat, new ArrayList<Integer>());
+            if (stat.getType().equals(Integer.class)) {
+                mAccumulatedStats.put(stat, new ArrayList<Integer>());
+            } else if (stat.getType().equals(Double.class)) {
+                mAccumulatedStats.put(stat, new ArrayList<Double>());
+            } else {
+                // Shouldn't get here
+                throw new IllegalStateException("Unsupported JankStat type");
+            }
         }
     }
 
@@ -143,7 +160,16 @@
                 if ((part = stat.parse(line)) != null) {
                     // Parse was successful. Add the numeric value to the accumulated list of values
                     // for that stat.
-                    mAccumulatedStats.get(stat).add(Integer.parseInt(part));
+                    if (stat.getType().equals(Integer.class)) {
+                        List<Integer> stats = (List<Integer>)mAccumulatedStats.get(stat);
+                        stats.add(Integer.valueOf(part));
+                    } else if (stat.getType().equals(Double.class)) {
+                        List<Double> stats = (List<Double>)mAccumulatedStats.get(stat);
+                        stats.add(Double.valueOf(part));
+                    } else {
+                        // Shouldn't get here
+                        throw new IllegalStateException("Unsupported JankStat type");
+                    }
                     break;
                 }
             }
@@ -157,56 +183,64 @@
             stat.reset();
         }
 
-        List<Integer> totalFrames = mAccumulatedStats.get(JankStat.TOTAL_FRAMES);
+        List<Integer> totalFrames = (List<Integer>)mAccumulatedStats.get(JankStat.TOTAL_FRAMES);
         return totalFrames.get(totalFrames.size()-1);
     }
 
-    private void putAvgMax(Bundle metrics, String averageKey, String maxKey,
+    private void putAvgMaxInteger(Bundle metrics, String averageKey, String maxKey,
             List<Integer> values) {
 
         metrics.putDouble(averageKey, MetricsHelper.computeAverageInt(values));
         metrics.putInt(maxKey, Collections.max(values));
     }
 
+    private void putAvgMaxDouble(Bundle metrics, String averageKey, String maxKey,
+            List<Double> values) {
+
+        metrics.putDouble(averageKey, MetricsHelper.computeAverageFloat(values));
+        metrics.putDouble(maxKey, Collections.max(values));
+    }
+
     public Bundle getMetrics() {
         Bundle metrics = new Bundle();
 
         // Store average and max jank
-        putAvgMax(metrics, GfxMonitor.KEY_AVG_NUM_JANKY, GfxMonitor.KEY_MAX_NUM_JANKY,
-                mAccumulatedStats.get(JankStat.NUM_JANKY));
+        putAvgMaxDouble(metrics, GfxMonitor.KEY_AVG_NUM_JANKY, GfxMonitor.KEY_MAX_NUM_JANKY,
+                (List<Double>)mAccumulatedStats.get(JankStat.NUM_JANKY));
 
         // Store average and max percentile frame times
-        putAvgMax(metrics, GfxMonitor.KEY_AVG_FRAME_TIME_90TH_PERCENTILE,
+        putAvgMaxInteger(metrics, GfxMonitor.KEY_AVG_FRAME_TIME_90TH_PERCENTILE,
                 GfxMonitor.KEY_MAX_FRAME_TIME_90TH_PERCENTILE,
-                mAccumulatedStats.get(JankStat.FRAME_TIME_90TH));
-        putAvgMax(metrics, GfxMonitor.KEY_AVG_FRAME_TIME_95TH_PERCENTILE,
+                (List<Integer>)mAccumulatedStats.get(JankStat.FRAME_TIME_90TH));
+        putAvgMaxInteger(metrics, GfxMonitor.KEY_AVG_FRAME_TIME_95TH_PERCENTILE,
                 GfxMonitor.KEY_MAX_FRAME_TIME_95TH_PERCENTILE,
-                mAccumulatedStats.get(JankStat.FRAME_TIME_95TH));
-        putAvgMax(metrics, GfxMonitor.KEY_AVG_FRAME_TIME_99TH_PERCENTILE,
+                (List<Integer>)mAccumulatedStats.get(JankStat.FRAME_TIME_95TH));
+        putAvgMaxInteger(metrics, GfxMonitor.KEY_AVG_FRAME_TIME_99TH_PERCENTILE,
                 GfxMonitor.KEY_MAX_FRAME_TIME_99TH_PERCENTILE,
-                mAccumulatedStats.get(JankStat.FRAME_TIME_99TH));
+                (List<Integer>)mAccumulatedStats.get(JankStat.FRAME_TIME_99TH));
 
         // Store average and max missed vsync
-        putAvgMax(metrics, GfxMonitor.KEY_AVG_MISSED_VSYNC, GfxMonitor.KEY_MAX_MISSED_VSYNC,
-                mAccumulatedStats.get(JankStat.NUM_MISSED_VSYNC));
+        putAvgMaxInteger(metrics, GfxMonitor.KEY_AVG_MISSED_VSYNC, GfxMonitor.KEY_MAX_MISSED_VSYNC,
+                (List<Integer>)mAccumulatedStats.get(JankStat.NUM_MISSED_VSYNC));
 
         // Store average and max high input latency
-        putAvgMax(metrics, GfxMonitor.KEY_AVG_HIGH_INPUT_LATENCY,
+        putAvgMaxInteger(metrics, GfxMonitor.KEY_AVG_HIGH_INPUT_LATENCY,
                 GfxMonitor.KEY_MAX_HIGH_INPUT_LATENCY,
-                mAccumulatedStats.get(JankStat.NUM_HIGH_INPUT_LATENCY));
+                (List<Integer>)mAccumulatedStats.get(JankStat.NUM_HIGH_INPUT_LATENCY));
 
         // Store average and max slow ui thread
-        putAvgMax(metrics, GfxMonitor.KEY_AVG_SLOW_UI_THREAD, GfxMonitor.KEY_MAX_SLOW_UI_THREAD,
-                mAccumulatedStats.get(JankStat.NUM_SLOW_UI_THREAD));
+        putAvgMaxInteger(metrics, GfxMonitor.KEY_AVG_SLOW_UI_THREAD,
+                GfxMonitor.KEY_MAX_SLOW_UI_THREAD,
+                (List<Integer>)mAccumulatedStats.get(JankStat.NUM_SLOW_UI_THREAD));
 
         // Store average and max slow bitmap uploads
-        putAvgMax(metrics, GfxMonitor.KEY_AVG_SLOW_BITMAP_UPLOADS,
+        putAvgMaxInteger(metrics, GfxMonitor.KEY_AVG_SLOW_BITMAP_UPLOADS,
                 GfxMonitor.KEY_MAX_SLOW_BITMAP_UPLOADS,
-                mAccumulatedStats.get(JankStat.NUM_SLOW_BITMAP_UPLOADS));
+                (List<Integer>)mAccumulatedStats.get(JankStat.NUM_SLOW_BITMAP_UPLOADS));
 
         // Store average and max slow draw
-        putAvgMax(metrics, GfxMonitor.KEY_AVG_SLOW_DRAW, GfxMonitor.KEY_MAX_SLOW_DRAW,
-                mAccumulatedStats.get(JankStat.NUM_SLOW_DRAW));
+        putAvgMaxInteger(metrics, GfxMonitor.KEY_AVG_SLOW_DRAW, GfxMonitor.KEY_MAX_SLOW_DRAW,
+                (List<Integer>)mAccumulatedStats.get(JankStat.NUM_SLOW_DRAW));
 
         return metrics;
     }