Snap for 9470583 from 54d3cd2cc5349ef02eaa59a161421b12f141409d to tm-qpr3-release

Change-Id: Iac51cc13104a9960ee101850ffedaa9fa5f3995d
diff --git a/javatests/com/android/loganalysis/parser/DmesgParserTest.java b/javatests/com/android/loganalysis/parser/DmesgParserTest.java
index e4ea7af..cc79db7 100644
--- a/javatests/com/android/loganalysis/parser/DmesgParserTest.java
+++ b/javatests/com/android/loganalysis/parser/DmesgParserTest.java
@@ -50,6 +50,8 @@
                 "[    1.115467] init: Loaded 198 kernel modules took 748 ms",
                 "[    2.471163] init: Wait for property 'apexd.status=ready' took 403ms",
                 "[    3.786943] ueventd: Coldboot took 0.701291 seconds",
+                "[    4.295667] init: Command 'mount_all --late' action=late-fs "
+                        + "/vendor/etc/init/hw/init.rc:347) took 250ms and succeeded",
                 "[   22.962730] init: starting service 'bootanim'...",
                 "[   23.252321] init: starting service 'netd'...",
                 "[   29.331069] ipa-wan ipa_wwan_ioctl:1428 dev(rmnet_data0) register to IPA",
@@ -113,7 +115,9 @@
 
         assertEquals("Service info items list size should be 2", 2,
                 dmesgParser.getServiceInfoItems().size());
-        assertEquals("Stage info items list size should be 3",3,
+        assertEquals(
+                "Stage info items list size should be 4",
+                4,
                 dmesgParser.getStageInfoItems().size());
         assertEquals("Action info items list size should be 9",9,
                 dmesgParser.getActionInfoItems().size());
@@ -138,7 +142,9 @@
             dmesgParser.parseInfo(bufferedReader);
             assertEquals("Service info items list size should be 2", 2,
                     dmesgParser.getServiceInfoItems().size());
-            assertEquals("Stage info items list size should be 3", 3,
+            assertEquals(
+                    "Stage info items list size should be 4",
+                    4,
                     dmesgParser.getStageInfoItems().size());
             assertEquals("Action info items list size should be 9",9,
                     dmesgParser.getActionInfoItems().size());
@@ -223,7 +229,7 @@
             dmesgParser.parseStageInfo(line);
         }
         List<DmesgStageInfoItem> stageInfoItems = dmesgParser.getStageInfoItems();
-        assertEquals(3, stageInfoItems.size());
+        assertEquals(4, stageInfoItems.size());
         assertEquals(EXPECTED_STAGE_INFO_ITEMS, stageInfoItems);
     }
 
@@ -272,6 +278,7 @@
         return Arrays.asList(
                 new DmesgStageInfoItem("init_Wait for property 'apexd.status=ready'", null, 403L),
                 new DmesgStageInfoItem("ueventd_Coldboot", null, 701L),
+                new DmesgStageInfoItem("init_mount_all_late", null, 250L),
                 new DmesgStageInfoItem("first", 41665L, null));
     }
 
diff --git a/src/com/android/loganalysis/parser/DmesgParser.java b/src/com/android/loganalysis/parser/DmesgParser.java
index 53514d2..f7aac4d 100644
--- a/src/com/android/loganalysis/parser/DmesgParser.java
+++ b/src/com/android/loganalysis/parser/DmesgParser.java
@@ -47,6 +47,7 @@
     private static final String INIT = "init";
     private static final String WAIT_PROPERTY = "Wait for property ";
     private static final String TOTAL_MODULE = "TOTAL_MODULE";
+    private static final String MOUNT_ALL = "mount_all";
 
     // Matches: [ 14.822691] init:
     private static final String SERVICE_PREFIX = String.format("^\\[\\s+(?<%s>.*)\\] init:\\s+",
@@ -106,8 +107,8 @@
                             "%sLoaded kernel module \\S+\\/(?<koname>\\S+)\\.ko", SERVICE_PREFIX));
 
     // Matches: [    3.791635] ueventd: Coldboot took 0.695055 seconds
-    private static final String STAGE_SUFFIX= String.format(
-            "(?<%s>.*)\\s+took\\s+(?<%s>.*)\\s+seconds$", STAGE, DURATION);
+    private static final String STAGE_SUFFIX =
+            String.format("(?<%s>.*)\\s+took\\s+(?<%s>.*)\\s+seconds$", STAGE, DURATION);
     private static final Pattern UEVENTD_STAGE_INFO = Pattern.compile(
             String.format("%s%s", UEVENTD_PREFIX, STAGE_SUFFIX));
 
@@ -117,6 +118,15 @@
     private static final Pattern WAIT_FOR_PROPERTY_INFO = Pattern.compile(
             String.format("%s%s", SERVICE_PREFIX, PROPERTY_SUFFIX));
 
+    // Matches: [    2.295667] init: Command 'mount_all --late' action=late-fs
+    // (/vendor/etc/init/init.rc:347) took 250ms and succeeded
+    private static final String MOUNT_SUFFIX =
+            String.format(
+                    "Command 'mount_all (?<%s>/\\S+|.*)?--(?<%s>.+)'.* took (?<%s>\\d+)ms.*",
+                    SOURCE, STAGE, DURATION);
+    private static final Pattern MOUNT_STAGE_INFO =
+            Pattern.compile(String.format("%s%s", SERVICE_PREFIX, MOUNT_SUFFIX));
+
     private DmesgItem mDmesgItem = new DmesgItem();
 
     /**
@@ -134,10 +144,10 @@
     /**
      * Parse the kernel log till EOF to retrieve the duration of the service calls, start times of
      * different boot stages and actions taken. Besides, while parsing these informations are stored
-     * in the intermediate {@link DmesgServiceInfoItem}, {@link DmesgStageInfoItem} and
-     * {@link DmesgActionInfoItem} objects
+     * in the intermediate {@link DmesgServiceInfoItem}, {@link DmesgStageInfoItem} and {@link
+     * DmesgActionInfoItem} objects
      *
-     * @param input dmesg log
+     * @param bufferedLog dmesg log
      * @throws IOException
      */
     public DmesgItem parseInfo(BufferedReader bufferedLog) throws IOException {
@@ -184,9 +194,9 @@
      * log and store the {@code duration} it took to complete the service if the end time stamp is
      * available in {@link DmesgServiceInfoItem}.
      *
-     * @param individual line of the dmesg log
-     * @return {@code true}, if the {@code line} indicates start or end of a service,
-     *         {@code false}, otherwise
+     * @param line individual line of the dmesg log
+     * @return {@code true}, if the {@code line} indicates start or end of a service, {@code false},
+     *     otherwise
      */
     @VisibleForTesting
     boolean parseServiceInfo(String line) {
@@ -211,13 +221,12 @@
     }
 
     /**
-     * Parse init stages log from each {@code line} of dmesg log and
-     * store the stage name, start time and duration if available in a
-     * {@link DmesgStageInfoItem} object
+     * Parse init stages log from each {@code line} of dmesg log and store the stage name, start
+     * time and duration if available in a {@link DmesgStageInfoItem} object
      *
-     * @param individual line of the dmesg log
-     * @return {@code true}, if the {@code line} indicates start of a boot stage,
-     *         {@code false}, otherwise
+     * @param line individual line of the dmesg log
+     * @return {@code true}, if the {@code line} indicates start of a boot stage, {@code false},
+     *     otherwise
      */
     @VisibleForTesting
     boolean parseStageInfo(String line) {
@@ -246,17 +255,31 @@
             mDmesgItem.addStageInfoItem(stageInfoItem);
             return true;
         }
-
+        if ((match = matches(MOUNT_STAGE_INFO, line)) != null) {
+            DmesgStageInfoItem stageInfoItem = new DmesgStageInfoItem();
+            if (match.group(SOURCE).isEmpty()) {
+                stageInfoItem.setStageName(
+                        String.format("%s_%s_%s", INIT, MOUNT_ALL, match.group(STAGE)));
+            } else {
+                stageInfoItem.setStageName(
+                        String.format(
+                                "%s_%s_%s_%s",
+                                INIT, MOUNT_ALL, match.group(STAGE), match.group(SOURCE).trim()));
+            }
+            stageInfoItem.setDuration((long) Double.parseDouble(match.group(DURATION)));
+            mDmesgItem.addStageInfoItem(stageInfoItem);
+            return true;
+        }
         return false;
     }
 
     /**
-     * Parse action from each {@code line} of dmesg log and store the action name and start time
-     * in {@link DmesgActionInfoItem} object
+     * Parse action from each {@code line} of dmesg log and store the action name and start time in
+     * {@link DmesgActionInfoItem} object
      *
-     * @param individual {@code line} of the dmesg log
-     * @return {@code true}, if {@code line} indicates starting of processing of action
-     *         {@code false}, otherwise
+     * @param line individual {@code line} of the dmesg log
+     * @return {@code true}, if {@code line} indicates starting of processing of action {@code
+     *     false}, otherwise
      */
     @VisibleForTesting
     boolean parseActionInfo(String line) {
@@ -279,7 +302,7 @@
      * Parse modules from each {@code line} of dmesg log and store the module name and loading time
      * in {@link DmesgModuleInfoItem} object
      *
-     * @param individual {@code line} of the dmesg log
+     * @param line individual {@code line} of the dmesg log
      * @return {@code true}, if {@code line} indicates start, end of a module loading or the summary
      *     {@code false}, otherwise
      */