DisplayContentTests.java revision 51c1b670224fa1598644426b472d51346dd22f30
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 17package com.android.server.wm; 18 19import static android.view.Display.DEFAULT_DISPLAY; 20import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; 21import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 22import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 23import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; 24import static com.android.server.wm.WindowContainer.POSITION_TOP; 25import static org.junit.Assert.assertEquals; 26import static org.junit.Assert.assertTrue; 27 28import org.junit.Test; 29import org.junit.runner.RunWith; 30 31import android.content.res.Configuration; 32import android.platform.test.annotations.Presubmit; 33import android.support.test.filters.SmallTest; 34import android.support.test.runner.AndroidJUnit4; 35 36import java.util.Arrays; 37import java.util.LinkedList; 38import java.util.List; 39 40/** 41 * Tests for the {@link DisplayContent} class. 42 * 43 * Build/Install/Run: 44 * bit FrameworksServicesTests:com.android.server.wm.DisplayContentTests 45 */ 46@SmallTest 47@Presubmit 48@RunWith(AndroidJUnit4.class) 49public class DisplayContentTests extends WindowTestsBase { 50 51 @Test 52 public void testForAllWindows() throws Exception { 53 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION, 54 sDisplayContent, "exiting app"); 55 final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken; 56 exitingAppToken.mIsExiting = true; 57 exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken); 58 59 assertForAllWindowsOrder(Arrays.asList( 60 sWallpaperWindow, 61 exitingAppWindow, 62 sChildAppWindowBelow, 63 sAppWindow, 64 sChildAppWindowAbove, 65 sDockedDividerWindow, 66 sStatusBarWindow, 67 sNavBarWindow, 68 sImeWindow, 69 sImeDialogWindow)); 70 } 71 72 @Test 73 public void testForAllWindows_WithAppImeTarget() throws Exception { 74 final WindowState imeAppTarget = 75 createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget"); 76 77 sWm.mInputMethodTarget = imeAppTarget; 78 79 assertForAllWindowsOrder(Arrays.asList( 80 sWallpaperWindow, 81 sChildAppWindowBelow, 82 sAppWindow, 83 sChildAppWindowAbove, 84 imeAppTarget, 85 sImeWindow, 86 sImeDialogWindow, 87 sDockedDividerWindow, 88 sStatusBarWindow, 89 sNavBarWindow)); 90 } 91 92 @Test 93 public void testForAllWindows_WithChildWindowImeTarget() throws Exception { 94 sWm.mInputMethodTarget = sChildAppWindowAbove; 95 96 assertForAllWindowsOrder(Arrays.asList( 97 sWallpaperWindow, 98 sChildAppWindowBelow, 99 sAppWindow, 100 sChildAppWindowAbove, 101 sImeWindow, 102 sImeDialogWindow, 103 sDockedDividerWindow, 104 sStatusBarWindow, 105 sNavBarWindow)); 106 } 107 108 @Test 109 public void testForAllWindows_WithStatusBarImeTarget() throws Exception { 110 sWm.mInputMethodTarget = sStatusBarWindow; 111 112 assertForAllWindowsOrder(Arrays.asList( 113 sWallpaperWindow, 114 sChildAppWindowBelow, 115 sAppWindow, 116 sChildAppWindowAbove, 117 sDockedDividerWindow, 118 sStatusBarWindow, 119 sImeWindow, 120 sImeDialogWindow, 121 sNavBarWindow)); 122 } 123 124 @Test 125 public void testForAllWindows_WithInBetweenWindowToken() throws Exception { 126 // This window is set-up to be z-ordered between some windows that go in the same token like 127 // the nav bar and status bar. 128 final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION, 129 sDisplayContent, "voiceInteractionWindow"); 130 131 assertForAllWindowsOrder(Arrays.asList( 132 sWallpaperWindow, 133 sChildAppWindowBelow, 134 sAppWindow, 135 sChildAppWindowAbove, 136 sDockedDividerWindow, 137 voiceInteractionWindow, 138 sStatusBarWindow, 139 sNavBarWindow, 140 sImeWindow, 141 sImeDialogWindow)); 142 } 143 144 @Test 145 public void testComputeImeTarget() throws Exception { 146 // Verify that an app window can be an ime target. 147 final WindowState appWin = createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin"); 148 appWin.setHasSurface(true); 149 assertTrue(appWin.canBeImeTarget()); 150 WindowState imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */); 151 assertEquals(appWin, imeTarget); 152 153 // Verify that an child window can be an ime target. 154 final WindowState childWin = createWindow(appWin, 155 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin"); 156 childWin.setHasSurface(true); 157 assertTrue(childWin.canBeImeTarget()); 158 imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */); 159 assertEquals(childWin, imeTarget); 160 } 161 162 /** 163 * This tests stack movement between displays and proper stack's, task's and app token's display 164 * container references updates. 165 */ 166 @Test 167 public void testMoveStackBetweenDisplays() throws Exception { 168 // Create a second display. 169 final DisplayContent dc = createNewDisplay(); 170 171 // Add stack with activity. 172 final TaskStack stack = createTaskStackOnDisplay(dc); 173 assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId()); 174 assertEquals(dc, stack.getParent().getParent()); 175 assertEquals(dc, stack.getDisplayContent()); 176 177 final Task task = createTaskInStack(stack, 0 /* userId */); 178 final WindowTestUtils.TestAppWindowToken token = new WindowTestUtils.TestAppWindowToken(dc); 179 task.addChild(token, 0); 180 assertEquals(dc, task.getDisplayContent()); 181 assertEquals(dc, token.getDisplayContent()); 182 183 // Move stack to first display. 184 sDisplayContent.moveStackToDisplay(stack, true /* onTop */); 185 assertEquals(sDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId()); 186 assertEquals(sDisplayContent, stack.getParent().getParent()); 187 assertEquals(sDisplayContent, stack.getDisplayContent()); 188 assertEquals(sDisplayContent, task.getDisplayContent()); 189 assertEquals(sDisplayContent, token.getDisplayContent()); 190 } 191 192 /** 193 * This tests override configuration updates for display content. 194 */ 195 @Test 196 public void testDisplayOverrideConfigUpdate() throws Exception { 197 final int displayId = sDisplayContent.getDisplayId(); 198 final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration(); 199 200 // Create new, slightly changed override configuration and apply it to the display. 201 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig); 202 newOverrideConfig.densityDpi += 120; 203 newOverrideConfig.fontScale += 0.3; 204 205 sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId); 206 207 // Check that override config is applied. 208 assertEquals(newOverrideConfig, sDisplayContent.getOverrideConfiguration()); 209 } 210 211 /** 212 * This tests global configuration updates when default display config is updated. 213 */ 214 @Test 215 public void testDefaultDisplayOverrideConfigUpdate() throws Exception { 216 final Configuration currentConfig = sDisplayContent.getConfiguration(); 217 218 // Create new, slightly changed override configuration and apply it to the display. 219 final Configuration newOverrideConfig = new Configuration(currentConfig); 220 newOverrideConfig.densityDpi += 120; 221 newOverrideConfig.fontScale += 0.3; 222 223 sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY); 224 225 // Check that global configuration is updated, as we've updated default display's config. 226 Configuration globalConfig = sWm.mRoot.getConfiguration(); 227 assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi); 228 assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */); 229 230 // Return back to original values. 231 sWm.setNewDisplayOverrideConfiguration(currentConfig, DEFAULT_DISPLAY); 232 globalConfig = sWm.mRoot.getConfiguration(); 233 assertEquals(currentConfig.densityDpi, globalConfig.densityDpi); 234 assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */); 235 } 236 237 @Test 238 public void testFocusedWindowMultipleDisplays() throws Exception { 239 // Create a focusable window and check that focus is calcualted correctly 240 final WindowState window1 = 241 createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "window1"); 242 assertEquals(window1, sWm.mRoot.computeFocusedWindow()); 243 244 // Check that a new display doesn't affect focus 245 final DisplayContent dc = createNewDisplay(); 246 assertEquals(window1, sWm.mRoot.computeFocusedWindow()); 247 248 // Add a window to the second display, and it should be focused 249 final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2"); 250 assertEquals(window2, sWm.mRoot.computeFocusedWindow()); 251 252 // Move the first window to the to including parents, and make sure focus is updated 253 window1.getParent().positionChildAt(POSITION_TOP, window1, true); 254 assertEquals(window1, sWm.mRoot.computeFocusedWindow()); 255 } 256 257 /** 258 * This tests setting the maximum ui width on a display. 259 */ 260 @Test 261 public void testMaxUiWidth() throws Exception { 262 final int baseWidth = 1440; 263 final int baseHeight = 2560; 264 final int baseDensity = 300; 265 266 sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity); 267 268 final int maxWidth = 300; 269 final int resultingHeight = (maxWidth * baseHeight) / baseWidth; 270 final int resultingDensity = (maxWidth * baseDensity) / baseWidth; 271 272 sDisplayContent.setMaxUiWidth(maxWidth); 273 verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity); 274 275 // Assert setting values again does not change; 276 sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity); 277 verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity); 278 279 final int smallerWidth = 200; 280 final int smallerHeight = 400; 281 final int smallerDensity = 100; 282 283 // Specify smaller dimension, verify that it is honored 284 sDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity); 285 verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity); 286 287 // Verify that setting the max width to a greater value than the base width has no effect 288 sDisplayContent.setMaxUiWidth(maxWidth); 289 verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity); 290 } 291 292 private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth, 293 int expectedBaseHeight, int expectedBaseDensity) { 294 assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth); 295 assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight); 296 assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity); 297 } 298 299 private void assertForAllWindowsOrder(List<WindowState> expectedWindows) { 300 final LinkedList<WindowState> actualWindows = new LinkedList(); 301 302 // Test forward traversal. 303 sDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */); 304 assertEquals(expectedWindows.size(), actualWindows.size()); 305 for (WindowState w : expectedWindows) { 306 assertEquals(w, actualWindows.pollFirst()); 307 } 308 assertTrue(actualWindows.isEmpty()); 309 310 // Test backward traversal. 311 sDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */); 312 assertEquals(expectedWindows.size(), actualWindows.size()); 313 for (WindowState w : expectedWindows) { 314 assertEquals(w, actualWindows.pollLast()); 315 } 316 assertTrue(actualWindows.isEmpty()); 317 } 318} 319