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 com.android.server.wm; 18 19 import org.junit.Test; 20 import org.junit.runner.RunWith; 21 22 import android.platform.test.annotations.Presubmit; 23 import android.support.test.filters.SmallTest; 24 import android.support.test.runner.AndroidJUnit4; 25 import android.view.Surface; 26 import android.view.WindowManager; 27 28 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; 29 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; 30 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; 31 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; 32 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 33 import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; 34 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; 35 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; 36 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 37 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 38 import static org.junit.Assert.assertEquals; 39 import static org.junit.Assert.assertFalse; 40 import static org.junit.Assert.assertNull; 41 import static org.junit.Assert.assertTrue; 42 /** 43 * Tests for the {@link AppWindowToken} class. 44 * 45 * Build/Install/Run: 46 * bit FrameworksServicesTests:com.android.server.wm.AppWindowTokenTests 47 */ 48 @SmallTest 49 @Presubmit 50 @RunWith(AndroidJUnit4.class) 51 public class AppWindowTokenTests extends WindowTestsBase { 52 53 @Test 54 public void testAddWindow_Order() throws Exception { 55 final WindowTestUtils.TestAppWindowToken token = 56 new WindowTestUtils.TestAppWindowToken(mDisplayContent); 57 58 assertEquals(0, token.getWindowsCount()); 59 60 final WindowState win1 = createWindow(null, TYPE_APPLICATION, token, "win1"); 61 final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, token, 62 "startingWin"); 63 final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, token, "baseWin"); 64 final WindowState win4 = createWindow(null, TYPE_APPLICATION, token, "win4"); 65 66 // Should not contain the windows that were added above. 67 assertEquals(4, token.getWindowsCount()); 68 assertTrue(token.hasWindow(win1)); 69 assertTrue(token.hasWindow(startingWin)); 70 assertTrue(token.hasWindow(baseWin)); 71 assertTrue(token.hasWindow(win4)); 72 73 // The starting window should be on-top of all other windows. 74 assertEquals(startingWin, token.getLastChild()); 75 76 // The base application window should be below all other windows. 77 assertEquals(baseWin, token.getFirstChild()); 78 token.removeImmediately(); 79 } 80 81 @Test 82 public void testFindMainWindow() throws Exception { 83 final WindowTestUtils.TestAppWindowToken token = 84 new WindowTestUtils.TestAppWindowToken(mDisplayContent); 85 86 assertNull(token.findMainWindow()); 87 88 final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, token, "window1"); 89 final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11"); 90 final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12"); 91 assertEquals(window1, token.findMainWindow()); 92 window1.mAnimatingExit = true; 93 assertEquals(window1, token.findMainWindow()); 94 final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, token, "window2"); 95 assertEquals(window2, token.findMainWindow()); 96 token.removeImmediately(); 97 } 98 99 @Test 100 public void testGetTopFullscreenWindow() throws Exception { 101 final WindowTestUtils.TestAppWindowToken token = 102 new WindowTestUtils.TestAppWindowToken(mDisplayContent); 103 104 assertNull(token.getTopFullscreenWindow()); 105 106 final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, token, "window1"); 107 final WindowState window11 = createWindow(null, TYPE_APPLICATION, token, "window11"); 108 final WindowState window12 = createWindow(null, TYPE_APPLICATION, token, "window12"); 109 assertEquals(window12, token.getTopFullscreenWindow()); 110 window12.mAttrs.width = 500; 111 assertEquals(window11, token.getTopFullscreenWindow()); 112 window11.mAttrs.width = 500; 113 assertEquals(window1, token.getTopFullscreenWindow()); 114 token.removeImmediately(); 115 } 116 117 @Test 118 public void testLandscapeSeascapeRotationByApp() throws Exception { 119 // Some plumbing to get the service ready for rotation updates. 120 sWm.mDisplayReady = true; 121 sWm.mDisplayEnabled = true; 122 123 // Create an app window with token on a display. 124 final TaskStack stack = createTaskStackOnDisplay(mDisplayContent); 125 final Task task = createTaskInStack(stack, 0 /* userId */); 126 final WindowTestUtils.TestAppWindowToken appWindowToken = 127 new WindowTestUtils.TestAppWindowToken(mDisplayContent); 128 task.addChild(appWindowToken, 0); 129 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams( 130 TYPE_BASE_APPLICATION); 131 attrs.setTitle("AppWindow"); 132 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, appWindowToken); 133 appWindowToken.addWindow(appWindow); 134 135 // Set initial orientation and update. 136 appWindowToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); 137 sWm.updateOrientationFromAppTokens(mDisplayContent.getOverrideConfiguration(), null, 138 mDisplayContent.getDisplayId()); 139 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getLastOrientation()); 140 appWindow.resizeReported = false; 141 142 // Update the orientation to perform 180 degree rotation and check that resize was reported. 143 appWindowToken.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 144 sWm.updateOrientationFromAppTokens(mDisplayContent.getOverrideConfiguration(), null, 145 mDisplayContent.getDisplayId()); 146 sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */); 147 assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mDisplayContent.getLastOrientation()); 148 assertTrue(appWindow.resizeReported); 149 appWindow.removeImmediately(); 150 } 151 152 @Test 153 public void testLandscapeSeascapeRotationByPolicy() throws Exception { 154 // Some plumbing to get the service ready for rotation updates. 155 sWm.mDisplayReady = true; 156 sWm.mDisplayEnabled = true; 157 158 // Create an app window with token on a display. 159 final DisplayContent defaultDisplayContent = sWm.getDefaultDisplayContentLocked(); 160 final TaskStack stack = createTaskStackOnDisplay(defaultDisplayContent); 161 final Task task = createTaskInStack(stack, 0 /* userId */); 162 final WindowTestUtils.TestAppWindowToken appWindowToken = 163 new WindowTestUtils.TestAppWindowToken(defaultDisplayContent); 164 task.addChild(appWindowToken, 0); 165 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams( 166 TYPE_BASE_APPLICATION); 167 attrs.setTitle("AppWindow"); 168 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, appWindowToken); 169 appWindowToken.addWindow(appWindow); 170 171 // Set initial orientation and update. 172 performRotation(Surface.ROTATION_90); 173 appWindow.resizeReported = false; 174 175 // Update the rotation to perform 180 degree rotation and check that resize was reported. 176 performRotation(Surface.ROTATION_270); 177 assertTrue(appWindow.resizeReported); 178 appWindow.removeImmediately(); 179 } 180 181 private void performRotation(int rotationToReport) { 182 ((TestWindowManagerPolicy) sWm.mPolicy).rotationToReport = rotationToReport; 183 sWm.updateRotation(false, false); 184 // Simulate animator finishing orientation change 185 sWm.mRoot.mOrientationChangeComplete = true; 186 sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */); 187 } 188 189 @Test 190 public void testGetOrientation() throws Exception { 191 final WindowTestUtils.TestAppWindowToken token = 192 new WindowTestUtils.TestAppWindowToken(mDisplayContent); 193 token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); 194 195 token.setFillsParent(false); 196 // Can specify orientation if doesn't fill parent. 197 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation()); 198 199 token.setFillsParent(true); 200 token.hidden = true; 201 token.sendingToBottom = true; 202 // Can not specify orientation if app isn't visible even though it fills parent. 203 assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation()); 204 // Can specify orientation if the current orientation candidate is orientation behind. 205 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation(SCREEN_ORIENTATION_BEHIND)); 206 207 token.sendingToBottom = false; 208 token.setIsOnTop(true); 209 // Allow for token to provide orientation hidden if on top and not being sent to bottom. 210 assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation()); 211 } 212 213 @Test 214 public void testKeyguardFlagsDuringRelaunch() throws Exception { 215 final WindowTestUtils.TestAppWindowToken token = 216 new WindowTestUtils.TestAppWindowToken(mDisplayContent); 217 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams( 218 TYPE_BASE_APPLICATION); 219 attrs.flags |= FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD; 220 attrs.setTitle("AppWindow"); 221 final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, token); 222 223 // Add window with show when locked flag 224 token.addWindow(appWindow); 225 assertTrue(token.containsShowWhenLockedWindow() && token.containsDismissKeyguardWindow()); 226 227 // Start relaunching 228 token.startRelaunching(); 229 assertTrue(token.containsShowWhenLockedWindow() && token.containsDismissKeyguardWindow()); 230 231 // Remove window and make sure that we still report back flag 232 token.removeChild(appWindow); 233 assertTrue(token.containsShowWhenLockedWindow() && token.containsDismissKeyguardWindow()); 234 235 // Finish relaunching and ensure flag is now not reported 236 token.finishRelaunching(); 237 assertFalse(token.containsShowWhenLockedWindow() || token.containsDismissKeyguardWindow()); 238 } 239 } 240