Merge "Update removeOwners() for variable dumpsys output."
diff --git a/src/com/android/tradefed/device/TestDevice.java b/src/com/android/tradefed/device/TestDevice.java
index f78d42a..243425c 100644
--- a/src/com/android/tradefed/device/TestDevice.java
+++ b/src/com/android/tradefed/device/TestDevice.java
@@ -1331,7 +1331,8 @@
                 // Line is "Profile owner (User <id>):
                 String[] tokens = line.split("\\(|\\)| ");
                 int userId = Integer.parseInt(tokens[4]);
-                i++;
+
+                i = moveToNextIndexMatchingRegex(".*admin=.*", lines, i);
                 line = lines[i].trim();
                 // Line is admin=ComponentInfo{<component>}
                 tokens = line.split("\\{|\\}");
@@ -1339,13 +1340,14 @@
                 CLog.d("Cleaning up profile owner " + userId + " " + componentName);
                 removeAdmin(componentName, userId);
             } else if (line.contains("Device Owner:")) {
-                i++;
+                i = moveToNextIndexMatchingRegex(".*admin=.*", lines, i);
                 line = lines[i].trim();
                 // Line is admin=ComponentInfo{<component>}
                 String[] tokens = line.split("\\{|\\}");
                 String componentName = tokens[1];
+
                 // Skip to user id line.
-                i += 3;
+                i = moveToNextIndexMatchingRegex(".*User ID:.*", lines, i);
                 line = lines[i].trim();
                 // Line is User ID: <N>
                 tokens = line.split(":");
@@ -1357,6 +1359,30 @@
     }
 
     /**
+     * Search forward from the current index to find a string matching the given regex.
+     *
+     * @param regex The regex to match each line against.
+     * @param lines An array of strings to be searched.
+     * @param currentIndex the index to start searching from.
+     * @return The index of a string beginning with the regex.
+     * @throws IllegalStateException if the line cannot be found.
+     */
+    private int moveToNextIndexMatchingRegex(String regex, String[] lines, int currentIndex) {
+        while (currentIndex < lines.length && !lines[currentIndex].matches(regex)) {
+            currentIndex++;
+        }
+
+        if (currentIndex >= lines.length) {
+            throw new IllegalStateException(
+                    "The output of 'dumpsys device_policy' was not as expected. Owners have not "
+                            + "been removed. This will leave the device in an unstable state and "
+                            + "will lead to further test failures.");
+        }
+
+        return currentIndex;
+    }
+
+    /**
      * Helper for Api level checking of features in the new release before we incremented the api
      * number.
      */
diff --git a/tests/src/com/android/tradefed/device/TestDeviceTest.java b/tests/src/com/android/tradefed/device/TestDeviceTest.java
index 91d3ef5..198ce23 100644
--- a/tests/src/com/android/tradefed/device/TestDeviceTest.java
+++ b/tests/src/com/android/tradefed/device/TestDeviceTest.java
@@ -3639,6 +3639,44 @@
         assertEquals(Integer.valueOf(10), intArgs.get(1));
     }
 
+    public void testRemoveOwnersWithAdditionalLines() throws Exception {
+        mTestDevice =
+                Mockito.spy(
+                        new TestableTestDevice() {
+                            @Override
+                            public String executeShellCommand(String command)
+                                    throws DeviceNotAvailableException {
+                                return "Current Device Policy Manager state:\n"
+                                        + "  Device Owner: \n"
+                                        + "    admin=ComponentInfo{aaa/aaa}\n"
+                                        + "    name=\n"
+                                        + "    package=aaa\n"
+                                        + "    moreLines=true\n"
+                                        + "    User ID: 0\n"
+                                        + "\n"
+                                        + "  Profile Owner (User 10): \n"
+                                        + "    admin=ComponentInfo{bbb/bbb}\n"
+                                        + "    name=bbb\n"
+                                        + "    package=bbb\n";
+                            }
+                        });
+        mTestDevice.removeOwners();
+
+        // Verified removeAdmin is called to remove owners.
+        ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class);
+        Mockito.verify(mTestDevice, Mockito.times(2))
+                .removeAdmin(stringCaptor.capture(), intCaptor.capture());
+        List<String> stringArgs = stringCaptor.getAllValues();
+        List<Integer> intArgs = intCaptor.getAllValues();
+
+        assertEquals("aaa/aaa", stringArgs.get(0));
+        assertEquals(Integer.valueOf(0), intArgs.get(0));
+
+        assertEquals("bbb/bbb", stringArgs.get(1));
+        assertEquals(Integer.valueOf(10), intArgs.get(1));
+    }
+
     /** Test that the output of cryptfs allows for encryption for newest format. */
     public void testIsEncryptionSupported_newformat() throws Exception {
         mTestDevice =