Merge "Explicitly invoke keyguard for visibility test" into oc-dev
am: c1f7fd18f9

Change-Id: Ib0eae3c29ab1cbc912f93044b5bc4c072a17f054
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayLockedKeyguardTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayLockedKeyguardTests.java
new file mode 100644
index 0000000..d520f2c
--- /dev/null
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayLockedKeyguardTests.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.server.cts;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+import static android.server.cts.ActivityManagerState.STATE_RESUMED;
+import static android.server.cts.ActivityManagerState.STATE_STOPPED;
+import static android.server.cts.StateLogger.logE;
+
+/**
+ * Display tests that require a locked keyguard.
+ *
+ * Build: mmma -j32 cts/hostsidetests/services
+ * Run: cts/hostsidetests/services/activityandwindowmanager/util/run-test CtsServicesHostTestCases android.server.cts.ActivityManagerDisplayLockedKeyguardTests
+ */
+public class ActivityManagerDisplayLockedKeyguardTests extends ActivityManagerDisplayTestBase {
+
+    private static final String TEST_ACTIVITY_NAME = "TestActivity";
+    private static final String VIRTUAL_DISPLAY_ACTIVITY = "VirtualDisplayActivity";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        setLockCredential();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            removeLockCredential();
+            gotoKeyguard();
+        } catch (DeviceNotAvailableException e) {
+            logE(e.getMessage());
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Test that virtual display content is hidden when device is locked.
+     */
+    public void testVirtualDisplayHidesContentWhenLocked() throws Exception {
+        if (!supportsMultiDisplay() || !isHandheld()) { return; }
+
+        // Create new usual virtual display.
+        final DisplayState newDisplay = new VirtualDisplayBuilder(this).build();
+        mAmWmState.assertVisibility(VIRTUAL_DISPLAY_ACTIVITY, true /* visible */);
+
+        // Launch activity on new secondary display.
+        launchActivityOnDisplay(TEST_ACTIVITY_NAME, newDisplay.mDisplayId);
+        mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, true /* visible */);
+
+        // Lock the device.
+        gotoKeyguard();
+        mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
+        mAmWmState.waitForActivityState(mDevice, TEST_ACTIVITY_NAME, STATE_STOPPED);
+        mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, false /* visible */);
+
+        // Unlock and check if visibility is back.
+        unlockDeviceWithCredential();
+        mAmWmState.waitForKeyguardGone(mDevice);
+        mAmWmState.waitForActivityState(mDevice, TEST_ACTIVITY_NAME, STATE_RESUMED);
+        mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, true /* visible */);
+    }
+}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTestBase.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTestBase.java
new file mode 100644
index 0000000..cf44ad7
--- /dev/null
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTestBase.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.server.cts;
+
+import com.android.tradefed.device.CollectingOutputReceiver;
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+import static android.server.cts.ActivityAndWindowManagersState.DEFAULT_DISPLAY_ID;
+import static android.server.cts.StateLogger.log;
+import static android.server.cts.StateLogger.logE;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Base class for ActivityManager display tests.
+ *
+ * @see ActivityManagerDisplayTests
+ * @see ActivityManagerDisplayLockedKeyguardTests
+ */
+public class ActivityManagerDisplayTestBase extends ActivityManagerTestBase {
+
+    static final int CUSTOM_DENSITY_DPI = 222;
+
+    private static final String DUMPSYS_ACTIVITY_PROCESSES = "dumpsys activity processes";
+    private static final String VIRTUAL_DISPLAY_ACTIVITY = "VirtualDisplayActivity";
+    private static final int INVALID_DENSITY_DPI = -1;
+
+    private boolean mVirtualDisplayCreated;
+
+    /** Temp storage used for parsing. */
+    final LinkedList<String> mDumpLines = new LinkedList<>();
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            destroyVirtualDisplays();
+        } catch (DeviceNotAvailableException e) {
+            logE(e.getMessage());
+        }
+        super.tearDown();
+    }
+
+    /** Contains the configurations applied to attached displays. */
+    static final class DisplayState {
+        int mDisplayId;
+        String mOverrideConfig;
+
+        private DisplayState(int displayId, String overrideConfig) {
+            mDisplayId = displayId;
+            mOverrideConfig = overrideConfig;
+        }
+
+        private int getWidth() {
+            final String[] configParts = mOverrideConfig.split(" ");
+            for (String part : configParts) {
+                if (part.endsWith("dp") && part.startsWith("w")) {
+                    final String widthString = part.substring(1, part.length() - 3);
+                    return Integer.parseInt(widthString);
+                }
+            }
+
+            return -1;
+        }
+
+        private int getHeight() {
+            final String[] configParts = mOverrideConfig.split(" ");
+            for (String part : configParts) {
+                if (part.endsWith("dp") && part.startsWith("h")) {
+                    final String heightString = part.substring(1, part.length() - 3);
+                    return Integer.parseInt(heightString);
+                }
+            }
+
+            return -1;
+        }
+
+        int getDpi() {
+            final String[] configParts = mOverrideConfig.split(" ");
+            for (String part : configParts) {
+                if (part.endsWith("dpi")) {
+                    final String densityDpiString = part.substring(0, part.length() - 3);
+                    return Integer.parseInt(densityDpiString);
+                }
+            }
+
+            return -1;
+        }
+    }
+
+    /** Contains the configurations applied to attached displays. */
+    static final class ReportedDisplays {
+        private static final Pattern sGlobalConfigurationPattern =
+                Pattern.compile("mGlobalConfiguration: (\\{.*\\})");
+        private static final Pattern sDisplayOverrideConfigurationsPattern =
+                Pattern.compile("Display override configurations:");
+        private static final Pattern sDisplayConfigPattern =
+                Pattern.compile("(\\d+): (\\{.*\\})");
+
+        String mGlobalConfig;
+        private Map<Integer, DisplayState> mDisplayStates = new HashMap<>();
+
+        static ReportedDisplays create(LinkedList<String> dump) {
+            final ReportedDisplays result = new ReportedDisplays();
+
+            while (!dump.isEmpty()) {
+                final String line = dump.pop().trim();
+
+                Matcher matcher = sDisplayOverrideConfigurationsPattern.matcher(line);
+                if (matcher.matches()) {
+                    log(line);
+                    while (ReportedDisplays.shouldContinueExtracting(dump, sDisplayConfigPattern)) {
+                        final String displayOverrideConfigLine = dump.pop().trim();
+                        log(displayOverrideConfigLine);
+                        matcher = sDisplayConfigPattern.matcher(displayOverrideConfigLine);
+                        matcher.matches();
+                        final Integer displayId = Integer.valueOf(matcher.group(1));
+                        result.mDisplayStates.put(displayId,
+                                new DisplayState(displayId, matcher.group(2)));
+                    }
+                    continue;
+                }
+
+                matcher = sGlobalConfigurationPattern.matcher(line);
+                if (matcher.matches()) {
+                    log(line);
+                    result.mGlobalConfig = matcher.group(1);
+                }
+            }
+
+            return result;
+        }
+
+        /** Check if next line in dump matches the pattern and we should continue extracting. */
+        static boolean shouldContinueExtracting(LinkedList<String> dump, Pattern matchingPattern) {
+            if (dump.isEmpty()) {
+                return false;
+            }
+
+            final String line = dump.peek().trim();
+            return matchingPattern.matcher(line).matches();
+        }
+
+        DisplayState getDisplayState(int displayId) {
+            return mDisplayStates.get(displayId);
+        }
+
+        /** Return the display state with width, height, dpi */
+        DisplayState getDisplayState(int width, int height, int dpi) {
+            for (Map.Entry<Integer, DisplayState> entry : mDisplayStates.entrySet()) {
+                final DisplayState ds = entry.getValue();
+                if (ds.mDisplayId != DEFAULT_DISPLAY_ID && ds.getDpi() == dpi
+                        && ds.getWidth() == width && ds.getHeight() == height) {
+                    return ds;
+                }
+            }
+            return null;
+        }
+
+        /** Check if reported state is valid. */
+        boolean isValidState(int expectedDisplayCount) {
+            if (mDisplayStates.size() != expectedDisplayCount) {
+                return false;
+            }
+
+            for (Map.Entry<Integer, DisplayState> entry : mDisplayStates.entrySet()) {
+                final DisplayState ds = entry.getValue();
+                if (ds.mDisplayId != DEFAULT_DISPLAY_ID && ds.getDpi() == -1) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    ReportedDisplays getDisplaysStates() throws DeviceNotAvailableException {
+        final CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
+        mDevice.executeShellCommand(DUMPSYS_ACTIVITY_PROCESSES, outputReceiver);
+        String dump = outputReceiver.getOutput();
+        mDumpLines.clear();
+
+        Collections.addAll(mDumpLines, dump.split("\\n"));
+
+        return ReportedDisplays.create(mDumpLines);
+    }
+
+    /** Find the display that was not originally reported in oldDisplays and added in newDisplays */
+    private List<ActivityManagerDisplayTests.DisplayState> findNewDisplayStates(
+            ReportedDisplays oldDisplays, ReportedDisplays newDisplays) {
+        final ArrayList<DisplayState> displays = new ArrayList();
+
+        for (Integer displayId : newDisplays.mDisplayStates.keySet()) {
+            if (!oldDisplays.mDisplayStates.containsKey(displayId)) {
+                displays.add(newDisplays.getDisplayState(displayId));
+            }
+        }
+
+        return displays;
+    }
+
+    /**
+     * Create new virtual display.
+     * @param densityDpi provide custom density for the display.
+     * @param launchInSplitScreen start {@link VirtualDisplayActivity} to side from
+     *                            {@link LaunchingActivity} on primary display.
+     * @param publicDisplay make display public.
+     * @param resizeDisplay should resize display when surface size changes.
+     * @param launchActivity should launch test activity immediately after display creation.
+     * @return {@link ActivityManagerDisplayTests.DisplayState} of newly created display.
+     * @throws Exception
+     */
+    private List<ActivityManagerDisplayTests.DisplayState> createVirtualDisplays(int densityDpi,
+            boolean launchInSplitScreen, boolean publicDisplay, boolean resizeDisplay,
+            String launchActivity, int displayCount) throws Exception {
+        // Start an activity that is able to create virtual displays.
+        if (launchInSplitScreen) {
+            getLaunchActivityBuilder().setToSide(true)
+                    .setTargetActivityName(VIRTUAL_DISPLAY_ACTIVITY).execute();
+        } else {
+            launchActivity(VIRTUAL_DISPLAY_ACTIVITY);
+        }
+        mAmWmState.computeState(mDevice, new String[] {VIRTUAL_DISPLAY_ACTIVITY},
+                false /* compareTaskAndStackBounds */);
+        final ActivityManagerDisplayTests.ReportedDisplays originalDS = getDisplaysStates();
+        final int originalDisplayCount = originalDS.mDisplayStates.size();
+
+        // Create virtual display with custom density dpi.
+        executeShellCommand(getCreateVirtualDisplayCommand(densityDpi, publicDisplay, resizeDisplay,
+                launchActivity, displayCount));
+        mVirtualDisplayCreated = true;
+
+        // Wait for the virtual display to be created and get configurations.
+        final ActivityManagerDisplayTests.ReportedDisplays ds =
+                getDisplayStateAfterChange(originalDisplayCount + displayCount);
+        assertEquals("New virtual display must be created",
+                originalDisplayCount + displayCount, ds.mDisplayStates.size());
+
+        // Find the newly added display.
+        final List<ActivityManagerDisplayTests.DisplayState> newDisplays
+                = findNewDisplayStates(originalDS, ds);
+        assertTrue("New virtual display must be created", displayCount == newDisplays.size());
+
+        return newDisplays;
+    }
+
+    /**
+     * Destroy existing virtual display.
+     */
+    void destroyVirtualDisplays() throws Exception {
+        if (mVirtualDisplayCreated) {
+            executeShellCommand(getDestroyVirtualDisplayCommand());
+            mVirtualDisplayCreated = false;
+        }
+    }
+
+    static class VirtualDisplayBuilder {
+        private final ActivityManagerDisplayTestBase mTests;
+
+        private int mDensityDpi = CUSTOM_DENSITY_DPI;
+        private boolean mLaunchInSplitScreen = false;
+        private boolean mPublicDisplay = false;
+        private boolean mResizeDisplay = true;
+        private String mLaunchActivity = null;
+
+        public VirtualDisplayBuilder(ActivityManagerDisplayTestBase tests) {
+            mTests = tests;
+        }
+
+        public VirtualDisplayBuilder setDensityDpi(int densityDpi) {
+            mDensityDpi = densityDpi;
+            return this;
+        }
+
+        public VirtualDisplayBuilder setLaunchInSplitScreen(boolean launchInSplitScreen) {
+            mLaunchInSplitScreen = launchInSplitScreen;
+            return this;
+        }
+
+        public VirtualDisplayBuilder setPublicDisplay(boolean publicDisplay) {
+            mPublicDisplay = publicDisplay;
+            return this;
+        }
+
+        public VirtualDisplayBuilder setResizeDisplay(boolean resizeDisplay) {
+            mResizeDisplay = resizeDisplay;
+            return this;
+        }
+
+        public VirtualDisplayBuilder setLaunchActivity(String launchActivity) {
+            mLaunchActivity = launchActivity;
+            return this;
+        }
+
+        public DisplayState build() throws Exception {
+            final List<DisplayState> displays = build(1);
+            return displays != null && !displays.isEmpty() ? displays.get(0) : null;
+        }
+
+        public List<DisplayState> build(int count) throws Exception {
+            return mTests.createVirtualDisplays(mDensityDpi, mLaunchInSplitScreen, mPublicDisplay,
+                    mResizeDisplay, mLaunchActivity, count);
+        }
+    }
+
+    private static String getCreateVirtualDisplayCommand(int densityDpi, boolean publicDisplay,
+            boolean resizeDisplay, String launchActivity, int displayCount) {
+        final StringBuilder commandBuilder
+                = new StringBuilder(getAmStartCmd(VIRTUAL_DISPLAY_ACTIVITY));
+        commandBuilder.append(" -f 0x20000000");
+        commandBuilder.append(" --es command create_display");
+        if (densityDpi != INVALID_DENSITY_DPI) {
+            commandBuilder.append(" --ei density_dpi ").append(densityDpi);
+        }
+        commandBuilder.append(" --ei count ").append(displayCount);
+        commandBuilder.append(" --ez public_display ").append(publicDisplay);
+        commandBuilder.append(" --ez resize_display ").append(resizeDisplay);
+        if (launchActivity != null) {
+            commandBuilder.append(" --es launch_target_activity ").append(launchActivity);
+        }
+        return commandBuilder.toString();
+    }
+
+    private static String getDestroyVirtualDisplayCommand() {
+        return getAmStartCmd(VIRTUAL_DISPLAY_ACTIVITY) + " -f 0x20000000" +
+                " --es command destroy_display";
+    }
+
+    /** Wait for provided number of displays and report their configurations. */
+    ReportedDisplays getDisplayStateAfterChange(int expectedDisplayCount)
+            throws DeviceNotAvailableException {
+        ReportedDisplays ds = getDisplaysStates();
+
+        int retriesLeft = 5;
+        while (!ds.isValidState(expectedDisplayCount) && retriesLeft-- > 0) {
+            log("***Waiting for the correct number of displays...");
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                log(e.toString());
+            }
+            ds = getDisplaysStates();
+        }
+
+        return ds;
+    }
+
+    /** Checks if the device supports multi-display. */
+    boolean supportsMultiDisplay() throws Exception {
+        return hasDeviceFeature("android.software.activities_on_secondary_displays");
+    }
+}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java
index 9ea71d8..4e07eb4 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java
@@ -20,19 +20,14 @@
 import com.android.tradefed.device.CollectingOutputReceiver;
 import com.android.tradefed.device.DeviceNotAvailableException;
 
-import java.awt.Rectangle;
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import static android.server.cts.ActivityAndWindowManagersState.DEFAULT_DISPLAY_ID;
 import static android.server.cts.ActivityManagerState.STATE_RESUMED;
-import static android.server.cts.ActivityManagerState.STATE_STOPPED;
 import static android.server.cts.StateLogger.log;
 import static android.server.cts.StateLogger.logE;
 
@@ -40,8 +35,7 @@
  * Build: mmma -j32 cts/hostsidetests/services
  * Run: cts/hostsidetests/services/activityandwindowmanager/util/run-test CtsServicesHostTestCases android.server.cts.ActivityManagerDisplayTests
  */
-public class ActivityManagerDisplayTests extends ActivityManagerTestBase {
-    private static final String DUMPSYS_ACTIVITY_PROCESSES = "dumpsys activity processes";
+public class ActivityManagerDisplayTests extends ActivityManagerDisplayTestBase {
     private static final String WM_SIZE = "wm size";
     private static final String WM_DENSITY = "wm density";
 
@@ -54,17 +48,10 @@
     private static final String VR_TEST_ACTIVITY_NAME = "VrTestActivity";
     private static final String SECOND_PACKAGE_NAME = "android.server.cts.second";
     private static final String THIRD_PACKAGE_NAME = "android.server.cts.third";
-    private static final int INVALID_DENSITY_DPI = -1;
-    private static final int CUSTOM_DENSITY_DPI = 222;
     private static final int VR_VIRTUAL_DISPLAY_WIDTH = 70;
     private static final int VR_VIRTUAL_DISPLAY_HEIGHT = 90;
     private static final int VR_VIRTUAL_DISPLAY_DPI = 320;
 
-    /** Temp storage used for parsing. */
-    private final LinkedList<String> mDumpLines = new LinkedList<>();
-
-    private boolean mVirtualDisplayCreated;
-
     /** Physical display metrics and overrides in the beginning of the test. */
     private ReportedDisplayMetrics mInitialDisplayMetrics;
 
@@ -77,7 +64,6 @@
     @Override
     protected void tearDown() throws Exception {
         try {
-            destroyVirtualDisplays();
             enablePersistentVrMode(false);
             restoreDisplayMetricsOverrides();
         } catch (DeviceNotAvailableException e) {
@@ -131,9 +117,6 @@
         // Find the density of created display.
         final int newDensityDpi = newDisplay.getDpi();
         assertEquals(CUSTOM_DENSITY_DPI, newDensityDpi);
-
-        // Destroy the created display.
-        executeShellCommand(getDestroyVirtualDisplayCommand());
     }
 
     /**
@@ -1001,31 +984,6 @@
     }
 
     /**
-     * Test that virtual display content is hidden when device is locked.
-     */
-    public void testVirtualDisplayHidesContentWhenLocked() throws Exception {
-        if (!supportsMultiDisplay() || !isHandheld()) { return; }
-
-        // Create new usual virtual display.
-        final DisplayState newDisplay = new VirtualDisplayBuilder(this).build();
-        mAmWmState.assertVisibility(VIRTUAL_DISPLAY_ACTIVITY, true /* visible */);
-
-        // Launch activity on new secondary display.
-        launchActivityOnDisplay(TEST_ACTIVITY_NAME, newDisplay.mDisplayId);
-        mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, true /* visible */);
-
-        // Lock the device.
-        sleepDevice();
-        mAmWmState.waitForActivityState(mDevice, TEST_ACTIVITY_NAME, STATE_STOPPED);
-        mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, false /* visible */);
-
-        // Unlock and check if visibility is back.
-        wakeUpAndUnlockDevice();
-        mAmWmState.waitForActivityState(mDevice, TEST_ACTIVITY_NAME, STATE_RESUMED);
-        mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, true /* visible */);
-    }
-
-    /**
      * Test that all activities that were on the private display are destroyed on display removal.
      */
     @Presubmit
@@ -1526,317 +1484,8 @@
         }
     }
 
-    /** Find the display that was not originally reported in oldDisplays and added in newDisplays */
-    private List<DisplayState> findNewDisplayStates(ReportedDisplays oldDisplays,
-            ReportedDisplays newDisplays) {
-        final ArrayList<DisplayState> displays = new ArrayList();
-
-        for (Integer displayId : newDisplays.mDisplayStates.keySet()) {
-            if (!oldDisplays.mDisplayStates.containsKey(displayId)) {
-                displays.add(newDisplays.getDisplayState(displayId));
-            }
-        }
-
-        return displays;
-    }
-
-    /**
-     * Create new virtual display.
-     * @param densityDpi provide custom density for the display.
-     * @param launchInSplitScreen start {@link VirtualDisplayActivity} to side from
-     *                            {@link LaunchingActivity} on primary display.
-     * @param publicDisplay make display public.
-     * @param resizeDisplay should resize display when surface size changes.
-     * @param launchActivity should launch test activity immediately after display creation.
-     * @return {@link DisplayState} of newly created display.
-     * @throws Exception
-     */
-    private List<DisplayState> createVirtualDisplays(int densityDpi, boolean launchInSplitScreen,
-            boolean publicDisplay, boolean resizeDisplay, String launchActivity, int displayCount)
-            throws Exception {
-        // Start an activity that is able to create virtual displays.
-        if (launchInSplitScreen) {
-            getLaunchActivityBuilder().setToSide(true)
-                    .setTargetActivityName(VIRTUAL_DISPLAY_ACTIVITY).execute();
-        } else {
-            launchActivity(VIRTUAL_DISPLAY_ACTIVITY);
-        }
-        mAmWmState.computeState(mDevice, new String[] {VIRTUAL_DISPLAY_ACTIVITY},
-                false /* compareTaskAndStackBounds */);
-        final ReportedDisplays originalDS = getDisplaysStates();
-        final int originalDisplayCount = originalDS.mDisplayStates.size();
-
-        // Create virtual display with custom density dpi.
-        executeShellCommand(getCreateVirtualDisplayCommand(densityDpi, publicDisplay, resizeDisplay,
-                launchActivity, displayCount));
-        mVirtualDisplayCreated = true;
-
-        // Wait for the virtual display to be created and get configurations.
-        final ReportedDisplays ds =
-                getDisplayStateAfterChange(originalDisplayCount + displayCount);
-        assertEquals("New virtual display must be created",
-                originalDisplayCount + displayCount, ds.mDisplayStates.size());
-
-        // Find the newly added display.
-        final List<DisplayState> newDisplays = findNewDisplayStates(originalDS, ds);
-        assertTrue("New virtual display must be created", displayCount == newDisplays.size());
-
-        return newDisplays;
-    }
-
-    /**
-     * Destroy existing virtual display.
-     */
-    private void destroyVirtualDisplays() throws Exception {
-        if (mVirtualDisplayCreated) {
-            executeShellCommand(getDestroyVirtualDisplayCommand());
-            mVirtualDisplayCreated = false;
-        }
-    }
-
-    /** Wait for provided number of displays and report their configurations. */
-    private ReportedDisplays getDisplayStateAfterChange(int expectedDisplayCount)
-            throws DeviceNotAvailableException {
-        ReportedDisplays ds = getDisplaysStates();
-
-        int retriesLeft = 5;
-        while (!ds.isValidState(expectedDisplayCount) && retriesLeft-- > 0) {
-            log("***Waiting for the correct number of displays...");
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-                log(e.toString());
-            }
-            ds = getDisplaysStates();
-        }
-
-        return ds;
-    }
-
-    private ReportedDisplays getDisplaysStates() throws DeviceNotAvailableException {
-        final CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
-        mDevice.executeShellCommand(DUMPSYS_ACTIVITY_PROCESSES, outputReceiver);
-        String dump = outputReceiver.getOutput();
-        mDumpLines.clear();
-
-        Collections.addAll(mDumpLines, dump.split("\\n"));
-
-        return ReportedDisplays.create(mDumpLines);
-    }
-
-    /** Contains the configurations applied to attached displays. */
-    private static final class DisplayState {
-        private int mDisplayId;
-        private String mOverrideConfig;
-
-        private DisplayState(int displayId, String overrideConfig) {
-            mDisplayId = displayId;
-            mOverrideConfig = overrideConfig;
-        }
-
-        private int getWidth() {
-            final String[] configParts = mOverrideConfig.split(" ");
-            for (String part : configParts) {
-                if (part.endsWith("dp") && part.startsWith("w")) {
-                    final String widthString = part.substring(1, part.length() - 3);
-                    return Integer.parseInt(widthString);
-                }
-            }
-
-            return -1;
-        }
-
-        private int getHeight() {
-            final String[] configParts = mOverrideConfig.split(" ");
-            for (String part : configParts) {
-                if (part.endsWith("dp") && part.startsWith("h")) {
-                    final String heightString = part.substring(1, part.length() - 3);
-                    return Integer.parseInt(heightString);
-                }
-            }
-
-            return -1;
-        }
-
-        private int getDpi() {
-            final String[] configParts = mOverrideConfig.split(" ");
-            for (String part : configParts) {
-                if (part.endsWith("dpi")) {
-                    final String densityDpiString = part.substring(0, part.length() - 3);
-                    return Integer.parseInt(densityDpiString);
-                }
-            }
-
-            return -1;
-        }
-    }
-
-
-
-    /** Contains the configurations applied to attached displays. */
-    private static final class ReportedDisplays {
-        private static final Pattern sGlobalConfigurationPattern =
-                Pattern.compile("mGlobalConfiguration: (\\{.*\\})");
-        private static final Pattern sDisplayOverrideConfigurationsPattern =
-                Pattern.compile("Display override configurations:");
-        private static final Pattern sDisplayConfigPattern =
-                Pattern.compile("(\\d+): (\\{.*\\})");
-
-        private String mGlobalConfig;
-        private Map<Integer, DisplayState> mDisplayStates = new HashMap<>();
-
-        static ReportedDisplays create(LinkedList<String> dump) {
-            final ReportedDisplays result = new ReportedDisplays();
-
-            while (!dump.isEmpty()) {
-                final String line = dump.pop().trim();
-
-                Matcher matcher = sDisplayOverrideConfigurationsPattern.matcher(line);
-                if (matcher.matches()) {
-                    log(line);
-                    while (ReportedDisplays.shouldContinueExtracting(dump, sDisplayConfigPattern)) {
-                        final String displayOverrideConfigLine = dump.pop().trim();
-                        log(displayOverrideConfigLine);
-                        matcher = sDisplayConfigPattern.matcher(displayOverrideConfigLine);
-                        matcher.matches();
-                        final Integer displayId = Integer.valueOf(matcher.group(1));
-                        result.mDisplayStates.put(displayId,
-                                new DisplayState(displayId, matcher.group(2)));
-                    }
-                    continue;
-                }
-
-                matcher = sGlobalConfigurationPattern.matcher(line);
-                if (matcher.matches()) {
-                    log(line);
-                    result.mGlobalConfig = matcher.group(1);
-                }
-            }
-
-            return result;
-        }
-
-        /** Check if next line in dump matches the pattern and we should continue extracting. */
-        static boolean shouldContinueExtracting(LinkedList<String> dump, Pattern matchingPattern) {
-            if (dump.isEmpty()) {
-                return false;
-            }
-
-            final String line = dump.peek().trim();
-            return matchingPattern.matcher(line).matches();
-        }
-
-        DisplayState getDisplayState(int displayId) {
-            return mDisplayStates.get(displayId);
-        }
-
-        /** Return the display state with width, height, dpi */
-        DisplayState getDisplayState(int width, int height, int dpi) {
-            for (Map.Entry<Integer, DisplayState> entry : mDisplayStates.entrySet()) {
-                final DisplayState ds = entry.getValue();
-                if (ds.mDisplayId != DEFAULT_DISPLAY_ID && ds.getDpi() == dpi
-                    && ds.getWidth() == width && ds.getHeight() == height) {
-                    return ds;
-                }
-            }
-            return null;
-        }
-
-        /** Check if reported state is valid. */
-        boolean isValidState(int expectedDisplayCount) {
-            if (mDisplayStates.size() != expectedDisplayCount) {
-                return false;
-            }
-
-            for (Map.Entry<Integer, DisplayState> entry : mDisplayStates.entrySet()) {
-                final DisplayState ds = entry.getValue();
-                if (ds.mDisplayId != DEFAULT_DISPLAY_ID && ds.getDpi() == -1) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    private static class VirtualDisplayBuilder {
-        private final ActivityManagerDisplayTests mTests;
-
-        private int mDensityDpi = CUSTOM_DENSITY_DPI;
-        private boolean mLaunchInSplitScreen = false;
-        private boolean mPublicDisplay = false;
-        private boolean mResizeDisplay = true;
-        private String mLaunchActivity = null;
-
-        public VirtualDisplayBuilder(ActivityManagerDisplayTests tests) {
-            mTests = tests;
-        }
-
-        public VirtualDisplayBuilder setDensityDpi(int densityDpi) {
-            mDensityDpi = densityDpi;
-            return this;
-        }
-
-        public VirtualDisplayBuilder setLaunchInSplitScreen(boolean launchInSplitScreen) {
-            mLaunchInSplitScreen = launchInSplitScreen;
-            return this;
-        }
-
-        public VirtualDisplayBuilder setPublicDisplay(boolean publicDisplay) {
-            mPublicDisplay = publicDisplay;
-            return this;
-        }
-
-        public VirtualDisplayBuilder setResizeDisplay(boolean resizeDisplay) {
-            mResizeDisplay = resizeDisplay;
-            return this;
-        }
-
-        public VirtualDisplayBuilder setLaunchActivity(String launchActivity) {
-            mLaunchActivity = launchActivity;
-            return this;
-        }
-
-        public DisplayState build() throws Exception {
-            final List<DisplayState> displays = build(1);
-            return displays != null && !displays.isEmpty() ? displays.get(0) : null;
-        }
-
-        public List<DisplayState> build(int count) throws Exception {
-            return mTests.createVirtualDisplays(mDensityDpi, mLaunchInSplitScreen, mPublicDisplay,
-                    mResizeDisplay, mLaunchActivity, count);
-        }
-    }
-
-    private static String getCreateVirtualDisplayCommand(int densityDpi, boolean publicDisplay,
-            boolean resizeDisplay, String launchActivity, int displayCount) {
-        final StringBuilder commandBuilder
-                = new StringBuilder(getAmStartCmd(VIRTUAL_DISPLAY_ACTIVITY));
-        commandBuilder.append(" -f 0x20000000");
-        commandBuilder.append(" --es command create_display");
-        if (densityDpi != INVALID_DENSITY_DPI) {
-            commandBuilder.append(" --ei density_dpi ").append(densityDpi);
-        }
-        commandBuilder.append(" --ei count ").append(displayCount);
-        commandBuilder.append(" --ez public_display ").append(publicDisplay);
-        commandBuilder.append(" --ez resize_display ").append(resizeDisplay);
-        if (launchActivity != null) {
-            commandBuilder.append(" --es launch_target_activity ").append(launchActivity);
-        }
-        return commandBuilder.toString();
-    }
-
-    private static String getDestroyVirtualDisplayCommand() {
-        return getAmStartCmd(VIRTUAL_DISPLAY_ACTIVITY) + " -f 0x20000000" +
-                " --es command destroy_display";
-    }
-
     private static String getResizeVirtualDisplayCommand() {
         return getAmStartCmd(VIRTUAL_DISPLAY_ACTIVITY) + " -f 0x20000000" +
                 " --es command resize_display";
     }
-
-    /** Checks if the device supports multi-display. */
-    private boolean supportsMultiDisplay() throws Exception {
-        return hasDeviceFeature("android.software.activities_on_secondary_displays");
-    }
 }