Add Event class for KvmHypTracer

In preparation to re-use this class for other tests make it more generic
with a common place to parse events: KvmHypEvent()

Bug: 340244758
Test: atest AVFHostTestCase#testNoLongHypSections
Change-Id: I66267892348577b9ccc44282c25ceaa4b80a4817
diff --git a/tests/hostside/helper/java/com/android/microdroid/test/host/KvmHypTracer.java b/tests/hostside/helper/java/com/android/microdroid/test/host/KvmHypTracer.java
index a91049d..06b3624 100644
--- a/tests/hostside/helper/java/com/android/microdroid/test/host/KvmHypTracer.java
+++ b/tests/hostside/helper/java/com/android/microdroid/test/host/KvmHypTracer.java
@@ -34,19 +34,58 @@
 import java.util.regex.Pattern;
 import javax.annotation.Nonnull;
 
+class KvmHypEvent {
+    public final int cpu;
+    public final double timestamp;
+    public final String name;
+    public final String args;
+    public final boolean valid;
+
+    private static final Pattern LOST_EVENT_PATTERN = Pattern.compile(
+            "^CPU:[0-9]* \\[LOST ([0-9]*) EVENTS\\]");
+
+    public KvmHypEvent(String str) {
+        Matcher matcher = LOST_EVENT_PATTERN.matcher(str);
+        if (matcher.find())
+            throw new OutOfMemoryError("Lost " + matcher.group(1) + " events");
+
+        Pattern pattern = Pattern.compile(
+                "^\\[([0-9]*)\\][ \t]*([0-9]*\\.[0-9]*): (\\S+) (.*)");
+
+        matcher = pattern.matcher(str);
+        if (!matcher.find()) {
+            valid = false;
+            cpu = 0;
+            timestamp = 0;
+            name = "";
+            args = "";
+            CLog.w("Failed to parse hyp event: " + str);
+            return;
+        }
+
+        cpu = Integer.parseInt(matcher.group(1));
+        timestamp = Double.parseDouble(matcher.group(2));
+        name = matcher.group(3);
+        args = matcher.group(4);
+        valid = true;
+    }
+
+    public String toString() {
+        return String.format(
+                "[%03d]\t%f: %s %s", cpu, timestamp, name, args);
+    }
+}
+
 /** This class provides utilities to interact with the hyp tracing subsystem */
 public final class KvmHypTracer {
 
     private static final String HYP_TRACING_ROOT = "/sys/kernel/tracing/hyp/";
     private static final int DEFAULT_BUF_SIZE_KB = 4 * 1024;
-    private static final Pattern LOST_EVENT_PATTERN = Pattern.compile(
-            "^CPU:[0-9]* \\[LOST ([0-9]*) EVENTS\\]");
 
     private final CommandRunner mRunner;
     private final ITestDevice mDevice;
     private final int mNrCpus;
     private final String mHypEvents[];
-    private final Pattern mHypEventPattern;
 
     private final ArrayList<File> mTraces;
 
@@ -75,8 +114,6 @@
         mTraces = new ArrayList<File>();
         mNrCpus = Integer.parseInt(mRunner.run("nproc"));
         mHypEvents = events;
-        mHypEventPattern = Pattern.compile(
-            "^\\[([0-9]*)\\][ \t]*([0-9]*\\.[0-9]*): (" + String.join("|", mHypEvents) + ") (.*)");
     }
 
     public String run(String payload_cmd) throws Exception {
@@ -140,6 +177,20 @@
         return true;
     }
 
+    private KvmHypEvent getNextEvent(BufferedReader br) throws Exception {
+        KvmHypEvent event;
+        String l;
+
+        if ((l = br.readLine()) == null)
+            return null;
+
+        event = new KvmHypEvent(l);
+        if (!event.valid)
+            return null;
+
+        return event;
+    }
+
     public SimpleStats getDurationStats() throws Exception {
         String[] reqEvents = {"hyp_enter", "hyp_exit"};
         SimpleStats stats = new SimpleStats();
@@ -152,26 +203,21 @@
             double last = 0.0, hyp_enter = 0.0;
             String l, prev_event = "";
             while ((l = br.readLine()) != null) {
-                Matcher matcher = LOST_EVENT_PATTERN.matcher(l);
-                if (matcher.find())
-                    throw new OutOfMemoryError("Lost " + matcher.group(1) + " events");
+                KvmHypEvent hypEvent = new KvmHypEvent(l);
 
-                matcher = mHypEventPattern.matcher(l);
-                if (!matcher.find()) {
-                    CLog.w("Failed to parse hyp event: " + l);
+                if (!hypEvent.valid)
                     continue;
-                }
 
-                int cpu = Integer.parseInt(matcher.group(1));
+                int cpu = hypEvent.cpu;
                 if (cpu < 0 || cpu >= mNrCpus)
                     throw new ParseException("Incorrect CPU number: " + cpu, 0);
 
-                double cur = Double.parseDouble(matcher.group(2));
+                double cur = hypEvent.timestamp;
                 if (cur < last)
                     throw new ParseException("Time must not go backward: " + cur, 0);
                 last = cur;
 
-                String event = matcher.group(3);
+                String event = hypEvent.name;
                 if (event.equals(prev_event)) {
                     throw new ParseException("Hyp event found twice in a row: " + trace + " - " + l,
                                              0);
@@ -186,7 +232,7 @@
                         hyp_enter = cur;
                         break;
                     default:
-                        throw new ParseException("Unexpected line in trace" + l, 0);
+                        throw new ParseException("Unexpected line in trace " + l, 0);
                 }
                 prev_event = event;
             }