1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.server.cts; 18 19 import com.android.tradefed.device.DeviceNotAvailableException; 20 import com.android.tradefed.device.ITestDevice; 21 import com.android.tradefed.testtype.DeviceTestCase; 22 23 /** 24 * Ensure that compatibility dialog is shown when launching an application with 25 * an unsupported smallest width. 26 */ 27 public class DisplaySizeTest extends DeviceTestCase { 28 private static final String DENSITY_PROP_DEVICE = "ro.sf.lcd_density"; 29 private static final String DENSITY_PROP_EMULATOR = "qemu.sf.lcd_density"; 30 31 private static final String AM_START_COMMAND = "am start -n %s/%s.%s"; 32 private static final String AM_FORCE_STOP = "am force-stop %s"; 33 34 private static final int ACTIVITY_TIMEOUT_MILLIS = 1000; 35 private static final int WINDOW_TIMEOUT_MILLIS = 1000; 36 37 private ITestDevice mDevice; 38 39 @Override setUp()40 protected void setUp() throws Exception { 41 super.setUp(); 42 43 mDevice = getDevice(); 44 } 45 46 @Override tearDown()47 protected void tearDown() throws Exception { 48 super.tearDown(); 49 50 try { 51 resetDensity(); 52 53 // Ensure app process is stopped. 54 forceStopPackage("android.displaysize.app"); 55 forceStopPackage("android.server.app"); 56 } catch (DeviceNotAvailableException e) { 57 // Do nothing. 58 } 59 } 60 testCompatibilityDialog()61 public void testCompatibilityDialog() throws Exception { 62 // Launch some other app (not to perform density change on launcher). 63 startActivity("android.server.app", "TestActivity"); 64 verifyWindowDisplayed("TestActivity", ACTIVITY_TIMEOUT_MILLIS); 65 66 setUnsupportedDensity(); 67 68 // Launch target app. 69 startActivity("android.displaysize.app", "SmallestWidthActivity"); 70 verifyWindowDisplayed("SmallestWidthActivity", ACTIVITY_TIMEOUT_MILLIS); 71 verifyWindowDisplayed("UnsupportedDisplaySizeDialog", WINDOW_TIMEOUT_MILLIS); 72 } 73 testCompatibilityDialogWhenFocused()74 public void testCompatibilityDialogWhenFocused() throws Exception { 75 startActivity("android.displaysize.app", "SmallestWidthActivity"); 76 verifyWindowDisplayed("SmallestWidthActivity", ACTIVITY_TIMEOUT_MILLIS); 77 78 setUnsupportedDensity(); 79 80 verifyWindowDisplayed("UnsupportedDisplaySizeDialog", WINDOW_TIMEOUT_MILLIS); 81 } 82 testCompatibilityDialogAfterReturn()83 public void testCompatibilityDialogAfterReturn() throws Exception { 84 // Launch target app. 85 startActivity("android.displaysize.app", "SmallestWidthActivity"); 86 verifyWindowDisplayed("SmallestWidthActivity", ACTIVITY_TIMEOUT_MILLIS); 87 // Launch another activity. 88 startOtherActivityOnTop("android.displaysize.app", "SmallestWidthActivity"); 89 verifyWindowDisplayed("TestActivity", ACTIVITY_TIMEOUT_MILLIS); 90 91 setUnsupportedDensity(); 92 93 // Go back. 94 mDevice.executeShellCommand("input keyevent 4"); 95 96 verifyWindowDisplayed("SmallestWidthActivity", ACTIVITY_TIMEOUT_MILLIS); 97 verifyWindowDisplayed("UnsupportedDisplaySizeDialog", WINDOW_TIMEOUT_MILLIS); 98 } 99 setUnsupportedDensity()100 private void setUnsupportedDensity() throws DeviceNotAvailableException { 101 // Set device to 0.85 zoom. It doesn't matter that we're zooming out 102 // since the feature verifies that we're in a non-default density. 103 final int stableDensity = getStableDensity(); 104 final int targetDensity = (int) (stableDensity * 0.85); 105 setDensity(targetDensity); 106 } 107 getStableDensity()108 private int getStableDensity() { 109 try { 110 final String densityProp; 111 if (mDevice.getSerialNumber().startsWith("emulator-")) { 112 densityProp = DENSITY_PROP_EMULATOR; 113 } else { 114 densityProp = DENSITY_PROP_DEVICE; 115 } 116 117 return Integer.parseInt(mDevice.getProperty(densityProp)); 118 } catch (DeviceNotAvailableException e) { 119 return 0; 120 } 121 } 122 setDensity(int targetDensity)123 private void setDensity(int targetDensity) throws DeviceNotAvailableException { 124 mDevice.executeShellCommand("wm density " + targetDensity); 125 126 // Verify that the density is changed. 127 final String output = mDevice.executeShellCommand("wm density"); 128 final boolean success = output.contains("Override density: " + targetDensity); 129 130 assertTrue("Failed to set density to " + targetDensity, success); 131 } 132 resetDensity()133 private void resetDensity() throws DeviceNotAvailableException { 134 mDevice.executeShellCommand("wm density reset"); 135 } 136 forceStopPackage(String packageName)137 private void forceStopPackage(String packageName) throws DeviceNotAvailableException { 138 final String forceStopCmd = String.format(AM_FORCE_STOP, packageName); 139 mDevice.executeShellCommand(forceStopCmd); 140 } 141 startActivity(String packageName, String activityName)142 private void startActivity(String packageName, String activityName) 143 throws DeviceNotAvailableException { 144 mDevice.executeShellCommand(getStartCommand(packageName, activityName)); 145 } 146 startOtherActivityOnTop(String packageName, String activityName)147 private void startOtherActivityOnTop(String packageName, String activityName) 148 throws DeviceNotAvailableException { 149 final String startCmd = getStartCommand(packageName, activityName) 150 + " -f 0x20000000 --ez launch_another_activity true"; 151 mDevice.executeShellCommand(startCmd); 152 } 153 getStartCommand(String packageName, String activityName)154 private String getStartCommand(String packageName, String activityName) { 155 return String.format(AM_START_COMMAND, packageName, packageName, activityName); 156 } 157 verifyWindowDisplayed(String windowName, long timeoutMillis)158 private void verifyWindowDisplayed(String windowName, long timeoutMillis) 159 throws DeviceNotAvailableException { 160 boolean success = false; 161 162 // Verify that compatibility dialog is shown within 1000ms. 163 final long timeoutTimeMillis = System.currentTimeMillis() + timeoutMillis; 164 while (!success && System.currentTimeMillis() < timeoutTimeMillis) { 165 final String output = mDevice.executeShellCommand("dumpsys window"); 166 success = output.contains(windowName); 167 } 168 169 assertTrue(windowName + " was not displayed", success); 170 } 171 } 172