DisplayContentTests.java revision 8e44f6c46822028a853c41610d2289e299987af0
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 org.junit.Assert.assertEquals; 25import static org.junit.Assert.assertTrue; 26 27import org.junit.Test; 28import org.junit.runner.RunWith; 29 30import android.content.res.Configuration; 31import android.platform.test.annotations.Presubmit; 32import android.support.test.filters.SmallTest; 33import android.support.test.runner.AndroidJUnit4; 34 35import java.util.Arrays; 36import java.util.LinkedList; 37import java.util.List; 38 39/** 40 * Tests for the {@link DisplayContent} class. 41 * 42 * Build/Install/Run: 43 * bit FrameworksServicesTests:com.android.server.wm.DisplayContentTests 44 */ 45@SmallTest 46@Presubmit 47@RunWith(AndroidJUnit4.class) 48public class DisplayContentTests extends WindowTestsBase { 49 50 @Test 51 public void testForAllWindows() throws Exception { 52 final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION, 53 sDisplayContent, "exiting app"); 54 final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken; 55 exitingAppToken.mIsExiting = true; 56 exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken); 57 58 assertForAllWindowsOrder(Arrays.asList( 59 sWallpaperWindow, 60 exitingAppWindow, 61 sChildAppWindowBelow, 62 sAppWindow, 63 sChildAppWindowAbove, 64 sDockedDividerWindow, 65 sStatusBarWindow, 66 sNavBarWindow, 67 sImeWindow, 68 sImeDialogWindow)); 69 } 70 71 @Test 72 public void testForAllWindows_WithAppImeTarget() throws Exception { 73 final WindowState imeAppTarget = 74 createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget"); 75 76 sWm.mInputMethodTarget = imeAppTarget; 77 78 assertForAllWindowsOrder(Arrays.asList( 79 sWallpaperWindow, 80 sChildAppWindowBelow, 81 sAppWindow, 82 sChildAppWindowAbove, 83 imeAppTarget, 84 sImeWindow, 85 sImeDialogWindow, 86 sDockedDividerWindow, 87 sStatusBarWindow, 88 sNavBarWindow)); 89 } 90 91 @Test 92 public void testForAllWindows_WithChildWindowImeTarget() throws Exception { 93 sWm.mInputMethodTarget = sChildAppWindowAbove; 94 95 assertForAllWindowsOrder(Arrays.asList( 96 sWallpaperWindow, 97 sChildAppWindowBelow, 98 sAppWindow, 99 sChildAppWindowAbove, 100 sImeWindow, 101 sImeDialogWindow, 102 sDockedDividerWindow, 103 sStatusBarWindow, 104 sNavBarWindow)); 105 } 106 107 @Test 108 public void testForAllWindows_WithStatusBarImeTarget() throws Exception { 109 sWm.mInputMethodTarget = sStatusBarWindow; 110 111 assertForAllWindowsOrder(Arrays.asList( 112 sWallpaperWindow, 113 sChildAppWindowBelow, 114 sAppWindow, 115 sChildAppWindowAbove, 116 sDockedDividerWindow, 117 sStatusBarWindow, 118 sImeWindow, 119 sImeDialogWindow, 120 sNavBarWindow)); 121 } 122 123 @Test 124 public void testForAllWindows_WithInBetweenWindowToken() throws Exception { 125 // This window is set-up to be z-ordered between some windows that go in the same token like 126 // the nav bar and status bar. 127 final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION, 128 sDisplayContent, "voiceInteractionWindow"); 129 130 assertForAllWindowsOrder(Arrays.asList( 131 sWallpaperWindow, 132 sChildAppWindowBelow, 133 sAppWindow, 134 sChildAppWindowAbove, 135 sDockedDividerWindow, 136 voiceInteractionWindow, 137 sStatusBarWindow, 138 sNavBarWindow, 139 sImeWindow, 140 sImeDialogWindow)); 141 } 142 143 @Test 144 public void testComputeImeTarget() throws Exception { 145 // Verify that an app window can be an ime target. 146 final WindowState appWin = createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin"); 147 appWin.setHasSurface(true); 148 assertTrue(appWin.canBeImeTarget()); 149 WindowState imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */); 150 assertEquals(appWin, imeTarget); 151 152 // Verify that an child window can be an ime target. 153 final WindowState childWin = createWindow(appWin, 154 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin"); 155 childWin.setHasSurface(true); 156 assertTrue(childWin.canBeImeTarget()); 157 imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */); 158 assertEquals(childWin, imeTarget); 159 } 160 161 /** 162 * This tests stack movement between displays and proper stack's, task's and app token's display 163 * container references updates. 164 */ 165 @Test 166 public void testMoveStackBetweenDisplays() throws Exception { 167 // Create a second display. 168 final DisplayContent dc = createNewDisplay(); 169 170 // Add stack with activity. 171 final TaskStack stack = createTaskStackOnDisplay(dc); 172 assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId()); 173 assertEquals(dc, stack.getParent().getParent()); 174 assertEquals(dc, stack.getDisplayContent()); 175 176 final Task task = createTaskInStack(stack, 0 /* userId */); 177 final TestAppWindowToken token = new TestAppWindowToken(dc); 178 task.addChild(token, 0); 179 assertEquals(dc, task.getDisplayContent()); 180 assertEquals(dc, token.getDisplayContent()); 181 182 // Move stack to first display. 183 sDisplayContent.moveStackToDisplay(stack); 184 assertEquals(sDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId()); 185 assertEquals(sDisplayContent, stack.getParent().getParent()); 186 assertEquals(sDisplayContent, stack.getDisplayContent()); 187 assertEquals(sDisplayContent, task.getDisplayContent()); 188 assertEquals(sDisplayContent, token.getDisplayContent()); 189 } 190 191 /** 192 * This tests override configuration updates for display content. 193 */ 194 @Test 195 public void testDisplayOverrideConfigUpdate() throws Exception { 196 final int displayId = sDisplayContent.getDisplayId(); 197 final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration(); 198 199 // Create new, slightly changed override configuration and apply it to the display. 200 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig); 201 newOverrideConfig.densityDpi += 120; 202 newOverrideConfig.fontScale += 0.3; 203 204 sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId); 205 206 // Check that override config is applied. 207 assertEquals(newOverrideConfig, sDisplayContent.getOverrideConfiguration()); 208 } 209 210 /** 211 * This tests global configuration updates when default display config is updated. 212 */ 213 @Test 214 public void testDefaultDisplayOverrideConfigUpdate() throws Exception { 215 final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration(); 216 217 // Create new, slightly changed override configuration and apply it to the display. 218 final Configuration newOverrideConfig = new Configuration(currentOverrideConfig); 219 newOverrideConfig.densityDpi += 120; 220 newOverrideConfig.fontScale += 0.3; 221 222 sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY); 223 224 // Check that global configuration is updated, as we've updated default display's config. 225 Configuration globalConfig = sWm.mRoot.getConfiguration(); 226 assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi); 227 assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */); 228 229 // Return back to original values. 230 sWm.setNewDisplayOverrideConfiguration(currentOverrideConfig, DEFAULT_DISPLAY); 231 globalConfig = sWm.mRoot.getConfiguration(); 232 assertEquals(currentOverrideConfig.densityDpi, globalConfig.densityDpi); 233 assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */); 234 } 235 236 private void assertForAllWindowsOrder(List<WindowState> expectedWindows) { 237 final LinkedList<WindowState> actualWindows = new LinkedList(); 238 239 // Test forward traversal. 240 sDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */); 241 assertEquals(expectedWindows.size(), actualWindows.size()); 242 for (WindowState w : expectedWindows) { 243 assertEquals(w, actualWindows.pollFirst()); 244 } 245 assertTrue(actualWindows.isEmpty()); 246 247 // Test backward traversal. 248 sDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */); 249 assertEquals(expectedWindows.size(), actualWindows.size()); 250 for (WindowState w : expectedWindows) { 251 assertEquals(w, actualWindows.pollLast()); 252 } 253 assertTrue(actualWindows.isEmpty()); 254 } 255} 256