1 package com.android.helpers;
2 
3 import android.app.Instrumentation;
4 import android.os.ParcelFileDescriptor;
5 import android.util.Log;
6 
7 import java.io.ByteArrayOutputStream;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.util.Map;
11 
12 /**
13  * MetricUtility consist of basic utility methods to construct the metrics
14  * reported at the end of the test.
15  */
16 public class MetricUtility {
17 
18     private static final String TAG = MetricUtility.class.getSimpleName();
19     private static final String KEY_JOIN = "_";
20     private static final String METRIC_SEPARATOR = ",";
21 
22     public static final int BUFFER_SIZE = 1024;
23 
24     /**
25      * Append the given array of string to construct the final key used to track the metrics.
26      *
27      * @param keys to append using KEY_JOIN
28      */
constructKey(String... keys)29     public static String constructKey(String... keys) {
30         return String.join(KEY_JOIN, keys);
31     }
32 
33     /**
34      * Add metric to the result map. If metric key already exist append the new metric.
35      *
36      * @param metricKey Unique key to track the metric.
37      * @param metric metric to track.
38      * @param resultMap map of all the metrics.
39      */
addMetric(String metricKey, long metric, Map<String, StringBuilder> resultMap)40     public static void addMetric(String metricKey, long metric, Map<String,
41             StringBuilder> resultMap) {
42         resultMap.compute(metricKey, (key, value) -> (value == null) ?
43                 new StringBuilder().append(metric) : value.append(METRIC_SEPARATOR).append(metric));
44     }
45 
46     /**
47      * Add metric to the result map. If metric key already exist increment the value by 1.
48      *
49      * @param metricKey Unique key to track the metric.
50      * @param resultMap map of all the metrics.
51      */
addMetric(String metricKey, Map<String, Integer> resultMap)52     public static void addMetric(String metricKey, Map<String,
53             Integer> resultMap) {
54         resultMap.compute(metricKey, (key, value) -> (value == null) ? 1 : value + 1);
55     }
56 
57     /**
58      * Turn executeShellCommand into a blocking operation.
59      *
60      * @param command shell command to be executed.
61      * @param instr used to run the shell command.
62      * @return byte array of execution result
63      */
executeCommandBlocking(String command, Instrumentation instr)64     public static byte[] executeCommandBlocking(String command, Instrumentation instr) {
65         try (InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(instr.getUiAutomation()
66                 .executeShellCommand(command));
67                 ByteArrayOutputStream out = new ByteArrayOutputStream()) {
68             byte[] buf = new byte[BUFFER_SIZE];
69             int length;
70             Log.i(TAG, "Start reading the data");
71             while ((length = is.read(buf)) >= 0) {
72                 out.write(buf, 0, length);
73             }
74             Log.i(TAG, "Stop reading the data");
75             return out.toByteArray();
76         } catch (IOException e) {
77             Log.e(TAG, "Error executing: " + command, e);
78             return null;
79         }
80     }
81 
82 }
83