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.FlakyTest; 24 import android.support.test.filters.SmallTest; 25 import android.support.test.runner.AndroidJUnit4; 26 27 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 28 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; 29 import static android.view.WindowManager.LayoutParams.TYPE_TOAST; 30 import static org.junit.Assert.assertEquals; 31 import static org.junit.Assert.assertFalse; 32 import static org.junit.Assert.assertNotNull; 33 import static org.junit.Assert.assertNull; 34 import static org.junit.Assert.assertTrue; 35 import static org.mockito.Mockito.mock; 36 37 /** 38 * Tests for the {@link WindowToken} class. 39 * 40 * Build/Install/Run: 41 * bit FrameworksServicesTests:com.android.server.wm.WindowTokenTests 42 */ 43 @SmallTest 44 @FlakyTest(bugId = 74078662) 45 @Presubmit 46 @RunWith(AndroidJUnit4.class) 47 public class WindowTokenTests extends WindowTestsBase { 48 49 @Test 50 public void testAddWindow() throws Exception { 51 final WindowTestUtils.TestWindowToken token = 52 WindowTestUtils.createTestWindowToken(0, mDisplayContent); 53 54 assertEquals(0, token.getWindowsCount()); 55 56 final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1"); 57 final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11"); 58 final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12"); 59 final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2"); 60 final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3"); 61 62 token.addWindow(window1); 63 // NOTE: Child windows will not be added to the token as window containers can only 64 // contain/reference their direct children. 65 token.addWindow(window11); 66 token.addWindow(window12); 67 token.addWindow(window2); 68 token.addWindow(window3); 69 70 // Should not contain the child windows that were added above. 71 assertEquals(3, token.getWindowsCount()); 72 assertTrue(token.hasWindow(window1)); 73 assertFalse(token.hasWindow(window11)); 74 assertFalse(token.hasWindow(window12)); 75 assertTrue(token.hasWindow(window2)); 76 assertTrue(token.hasWindow(window3)); 77 } 78 79 @Test 80 public void testChildRemoval() throws Exception { 81 final DisplayContent dc = mDisplayContent; 82 final WindowTestUtils.TestWindowToken token = WindowTestUtils.createTestWindowToken(0, dc); 83 84 assertEquals(token, dc.getWindowToken(token.token)); 85 86 final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1"); 87 final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2"); 88 89 window2.removeImmediately(); 90 // The token should still be mapped in the display content since it still has a child. 91 assertEquals(token, dc.getWindowToken(token.token)); 92 93 window1.removeImmediately(); 94 // The token should have been removed from the display content since it no longer has a 95 // child. 96 assertEquals(null, dc.getWindowToken(token.token)); 97 } 98 99 /** 100 * Test that a window token isn't orphaned by the system when it is requested to be removed. 101 * Tokens should only be removed from the system when all their windows are gone. 102 */ 103 @Test 104 public void testTokenRemovalProcess() throws Exception { 105 final WindowTestUtils.TestWindowToken token = WindowTestUtils.createTestWindowToken( 106 TYPE_TOAST, mDisplayContent, true /* persistOnEmpty */); 107 108 // Verify that the token is on the display 109 assertNotNull(mDisplayContent.getWindowToken(token.token)); 110 111 final WindowState window1 = createWindow(null, TYPE_TOAST, token, "window1"); 112 final WindowState window2 = createWindow(null, TYPE_TOAST, token, "window2"); 113 114 mDisplayContent.removeWindowToken(token.token); 115 // Verify that the token is no longer mapped on the display 116 assertNull(mDisplayContent.getWindowToken(token.token)); 117 // Verify that the token is still attached to its parent 118 assertNotNull(token.getParent()); 119 // Verify that the token windows are still around. 120 assertEquals(2, token.getWindowsCount()); 121 122 window1.removeImmediately(); 123 // Verify that the token is still attached to its parent 124 assertNotNull(token.getParent()); 125 // Verify that the other token window is still around. 126 assertEquals(1, token.getWindowsCount()); 127 128 window2.removeImmediately(); 129 // Verify that the token is no-longer attached to its parent 130 assertNull(token.getParent()); 131 // Verify that the token windows are no longer attached to it. 132 assertEquals(0, token.getWindowsCount()); 133 } 134 } 135