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 org.junit.Test; 20import org.junit.runner.RunWith; 21 22import android.platform.test.annotations.Presubmit; 23import android.support.test.filters.SmallTest; 24import android.support.test.runner.AndroidJUnit4; 25 26import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 27import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; 28import static android.view.WindowManager.LayoutParams.TYPE_TOAST; 29import static org.junit.Assert.assertEquals; 30import static org.junit.Assert.assertFalse; 31import static org.junit.Assert.assertNotNull; 32import static org.junit.Assert.assertNull; 33import static org.junit.Assert.assertTrue; 34import static org.mockito.Mockito.mock; 35 36/** 37 * Tests for the {@link WindowToken} class. 38 * 39 * Build/Install/Run: 40 * bit FrameworksServicesTests:com.android.server.wm.WindowTokenTests 41 */ 42@SmallTest 43@Presubmit 44@RunWith(AndroidJUnit4.class) 45public class WindowTokenTests extends WindowTestsBase { 46 47 @Test 48 public void testAddWindow() throws Exception { 49 final WindowTestUtils.TestWindowToken token = 50 new WindowTestUtils.TestWindowToken(0, mDisplayContent); 51 52 assertEquals(0, token.getWindowsCount()); 53 54 final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1"); 55 final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11"); 56 final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12"); 57 final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2"); 58 final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3"); 59 60 token.addWindow(window1); 61 // NOTE: Child windows will not be added to the token as window containers can only 62 // contain/reference their direct children. 63 token.addWindow(window11); 64 token.addWindow(window12); 65 token.addWindow(window2); 66 token.addWindow(window3); 67 68 // Should not contain the child windows that were added above. 69 assertEquals(3, token.getWindowsCount()); 70 assertTrue(token.hasWindow(window1)); 71 assertFalse(token.hasWindow(window11)); 72 assertFalse(token.hasWindow(window12)); 73 assertTrue(token.hasWindow(window2)); 74 assertTrue(token.hasWindow(window3)); 75 } 76 77 @Test 78 public void testChildRemoval() throws Exception { 79 final DisplayContent dc = mDisplayContent; 80 final WindowTestUtils.TestWindowToken token = new WindowTestUtils.TestWindowToken(0, dc); 81 82 assertEquals(token, dc.getWindowToken(token.token)); 83 84 final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1"); 85 final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2"); 86 87 window2.removeImmediately(); 88 // The token should still be mapped in the display content since it still has a child. 89 assertEquals(token, dc.getWindowToken(token.token)); 90 91 window1.removeImmediately(); 92 // The token should have been removed from the display content since it no longer has a 93 // child. 94 assertEquals(null, dc.getWindowToken(token.token)); 95 } 96 97 @Test 98 public void testAdjustAnimLayer() throws Exception { 99 final WindowTestUtils.TestWindowToken token = 100 new WindowTestUtils.TestWindowToken(0, mDisplayContent); 101 final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1"); 102 final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11"); 103 final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12"); 104 final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2"); 105 final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3"); 106 107 window2.mLayer = 100; 108 window3.mLayer = 200; 109 110 // We assign layers once, to get the base values computed by 111 // the controller. 112 mLayersController.assignWindowLayers(mDisplayContent); 113 114 final int window1StartLayer = window1.mWinAnimator.mAnimLayer; 115 final int window11StartLayer = window11.mWinAnimator.mAnimLayer; 116 final int window12StartLayer = window12.mWinAnimator.mAnimLayer; 117 final int window2StartLayer = window2.mWinAnimator.mAnimLayer; 118 final int window3StartLayer = window3.mWinAnimator.mAnimLayer; 119 120 // Then we set an adjustment, and assign them again, they should 121 // be offset. 122 int adj = token.adj = 50; 123 mLayersController.assignWindowLayers(mDisplayContent); 124 final int highestLayer = token.getHighestAnimLayer(); 125 126 assertEquals(window1StartLayer + adj, window1.mWinAnimator.mAnimLayer); 127 assertEquals(window11StartLayer + adj, window11.mWinAnimator.mAnimLayer); 128 assertEquals(window12StartLayer + adj, window12.mWinAnimator.mAnimLayer); 129 assertEquals(window2StartLayer + adj, window2.mWinAnimator.mAnimLayer); 130 assertEquals(window3StartLayer + adj, window3.mWinAnimator.mAnimLayer); 131 assertEquals(window3StartLayer + adj, highestLayer); 132 } 133 134 /** 135 * Test that a window token isn't orphaned by the system when it is requested to be removed. 136 * Tokens should only be removed from the system when all their windows are gone. 137 */ 138 @Test 139 public void testTokenRemovalProcess() throws Exception { 140 final WindowTestUtils.TestWindowToken token = 141 new WindowTestUtils.TestWindowToken(TYPE_TOAST, mDisplayContent, 142 true /* persistOnEmpty */); 143 144 // Verify that the token is on the display 145 assertNotNull(mDisplayContent.getWindowToken(token.token)); 146 147 final WindowState window1 = createWindow(null, TYPE_TOAST, token, "window1"); 148 final WindowState window2 = createWindow(null, TYPE_TOAST, token, "window2"); 149 150 mDisplayContent.removeWindowToken(token.token); 151 // Verify that the token is no longer mapped on the display 152 assertNull(mDisplayContent.getWindowToken(token.token)); 153 // Verify that the token is still attached to its parent 154 assertNotNull(token.getParent()); 155 // Verify that the token windows are still around. 156 assertEquals(2, token.getWindowsCount()); 157 158 window1.removeImmediately(); 159 // Verify that the token is still attached to its parent 160 assertNotNull(token.getParent()); 161 // Verify that the other token window is still around. 162 assertEquals(1, token.getWindowsCount()); 163 164 window2.removeImmediately(); 165 // Verify that the token is no-longer attached to its parent 166 assertNull(token.getParent()); 167 // Verify that the token windows are no longer attached to it. 168 assertEquals(0, token.getWindowsCount()); 169 } 170} 171