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.wm; 18 19 import static android.server.wm.app.Components.TEST_ACTIVITY; 20 import static android.server.wm.displaysize.Components.SMALLEST_WIDTH_ACTIVITY; 21 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertTrue; 24 25 import android.graphics.Point; 26 import android.hardware.display.DisplayManager; 27 import android.hardware.display.VirtualDisplay; 28 import android.os.Build; 29 import android.os.Handler; 30 import android.os.Looper; 31 import android.platform.test.annotations.Presubmit; 32 import android.view.Display; 33 34 import org.junit.After; 35 import org.junit.Test; 36 37 /** 38 * Ensure that compatibility dialog is shown when launching an application with 39 * an unsupported smallest width. 40 * 41 * <p>Build/Install/Run: 42 * atest CtsWindowManagerDeviceTestCases:DisplaySizeTest 43 */ 44 @Presubmit 45 @android.server.wm.annotation.Group3 46 public class DisplaySizeTest extends ActivityManagerTestBase { 47 48 /** @see com.android.server.wm.UnsupportedDisplaySizeDialog */ 49 private static final String UNSUPPORTED_DISPLAY_SIZE_DIALOG_NAME = 50 "UnsupportedDisplaySizeDialog"; 51 52 @After tearDown()53 public void tearDown() { 54 // Ensure app process is stopped. 55 stopTestPackage(SMALLEST_WIDTH_ACTIVITY.getPackageName()); 56 stopTestPackage(TEST_ACTIVITY.getPackageName()); 57 } 58 59 @Test testCompatibilityDialog()60 public void testCompatibilityDialog() { 61 // Launch some other app (not to perform density change on launcher). 62 launchActivity(TEST_ACTIVITY); 63 mWmState.assertActivityDisplayed(TEST_ACTIVITY); 64 65 createManagedScreenDensitySession().setUnsupportedDensity(); 66 67 // Launch target app. 68 launchActivity(SMALLEST_WIDTH_ACTIVITY); 69 mWmState.assertActivityDisplayed(SMALLEST_WIDTH_ACTIVITY); 70 mWmState.assertWindowDisplayed(UNSUPPORTED_DISPLAY_SIZE_DIALOG_NAME); 71 } 72 73 @Test testCompatibilityDialogWhenFocused()74 public void testCompatibilityDialogWhenFocused() { 75 launchActivity(SMALLEST_WIDTH_ACTIVITY); 76 mWmState.assertActivityDisplayed(SMALLEST_WIDTH_ACTIVITY); 77 78 createManagedScreenDensitySession().setUnsupportedDensity(); 79 80 mWmState.assertWindowDisplayed(UNSUPPORTED_DISPLAY_SIZE_DIALOG_NAME); 81 } 82 83 @Test testCompatibilityDialogAfterReturn()84 public void testCompatibilityDialogAfterReturn() { 85 // Launch target app. 86 launchActivity(SMALLEST_WIDTH_ACTIVITY); 87 mWmState.assertActivityDisplayed(SMALLEST_WIDTH_ACTIVITY); 88 // Launch another activity. 89 final CommandSession.ActivitySession activity = createManagedActivityClientSession() 90 .startActivity(getLaunchActivityBuilder().setUseInstrumentation() 91 .setTargetActivity(TEST_ACTIVITY)); 92 mWmState.assertActivityDisplayed(TEST_ACTIVITY); 93 separateTestJournal(); 94 95 createManagedScreenDensitySession().setUnsupportedDensity(); 96 97 assertActivityLifecycle(TEST_ACTIVITY, true /* relaunched */); 98 activity.finish(); 99 100 mWmState.assertActivityDisplayed(SMALLEST_WIDTH_ACTIVITY); 101 mWmState.assertWindowDisplayed(UNSUPPORTED_DISPLAY_SIZE_DIALOG_NAME); 102 } 103 104 @Test testSizeRangesAfterSettingDisplaySize()105 public void testSizeRangesAfterSettingDisplaySize() throws InterruptedException { 106 VirtualDisplay virtualDisplay = null; 107 try { 108 final int initialLength = 500; 109 final int newLength = 1000; 110 final DisplayManager displayManager = mDm; 111 virtualDisplay = displayManager.createVirtualDisplay("CtsDisplay", initialLength, 112 initialLength, 160 /* densityDpi */, null /* surface */, 0 /* flags */); 113 final Display targetDisplay = virtualDisplay.getDisplay(); 114 final int targetDisplayId = targetDisplay.getDisplayId(); 115 final boolean[] displayChanged = { false }; 116 displayManager.registerDisplayListener(new DisplayManager.DisplayListener() { 117 @Override 118 public void onDisplayAdded(int displayId) {} 119 120 @Override 121 public void onDisplayRemoved(int displayId) {} 122 123 @Override 124 public void onDisplayChanged(int displayId) { 125 if (displayId == targetDisplayId) { 126 synchronized (displayManager) { 127 displayChanged[0] = true; 128 displayManager.notify(); 129 } 130 displayManager.unregisterDisplayListener(this); 131 } 132 } 133 }, new Handler(Looper.getMainLooper())); 134 135 executeShellCommand(String.format("wm size %sx%s -d %s", 136 newLength, newLength, targetDisplayId)); 137 138 synchronized (displayManager) { 139 if (!displayChanged[0]) { 140 displayManager.wait(3000 /* milliseconds */); 141 } 142 assertTrue("DisplayManager must receive onDisplayChanged event", displayChanged[0]); 143 } 144 145 final Point expectedSize = new Point(newLength, newLength); 146 final Point smallestSize = new Point(); 147 final Point largestSize = new Point(); 148 targetDisplay.getCurrentSizeRange(smallestSize, largestSize); 149 assertEquals("Smallest size must be changed.", expectedSize, smallestSize); 150 assertEquals("Largest size must be changed.", expectedSize, largestSize); 151 } finally { 152 if (virtualDisplay != null) { 153 virtualDisplay.release(); 154 } 155 } 156 } 157 createManagedScreenDensitySession()158 protected ScreenDensitySession createManagedScreenDensitySession() { 159 return mObjectTracker.manage(new ScreenDensitySession()); 160 } 161 162 private static class ScreenDensitySession implements AutoCloseable { 163 private static final String DENSITY_PROP_DEVICE = "ro.sf.lcd_density"; 164 private static final String DENSITY_PROP_EMULATOR = "qemu.sf.lcd_density"; 165 setUnsupportedDensity()166 void setUnsupportedDensity() { 167 // Set device to 0.85 zoom. It doesn't matter that we're zooming out 168 // since the feature verifies that we're in a non-default density. 169 final int stableDensity = getStableDensity(); 170 final int targetDensity = (int) (stableDensity * 0.85); 171 setDensity(targetDensity); 172 } 173 174 @Override close()175 public void close() throws Exception { 176 resetDensity(); 177 } 178 getStableDensity()179 private int getStableDensity() { 180 final String densityProp; 181 if (Build.IS_EMULATOR) { 182 densityProp = DENSITY_PROP_EMULATOR; 183 } else { 184 densityProp = DENSITY_PROP_DEVICE; 185 } 186 187 return Integer.parseInt(executeShellCommand("getprop " + densityProp).trim()); 188 } 189 setDensity(int targetDensity)190 private void setDensity(int targetDensity) { 191 executeShellCommand("wm density " + targetDensity); 192 193 // Verify that the density is changed. 194 final String output = executeShellCommand("wm density"); 195 final boolean success = output.contains("Override density: " + targetDensity); 196 197 assertTrue("Failed to set density to " + targetDensity, success); 198 } 199 resetDensity()200 private void resetDensity() { 201 executeShellCommand("wm density reset"); 202 } 203 } 204 } 205