WindowTokenTests.java revision dee1b3f80c363fa6d3c9e87acd729161bce56c23
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 TestWindowToken token = new TestWindowToken(0, sDisplayContent);
50
51        assertEquals(0, token.getWindowsCount());
52
53        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
54        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
55        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
56        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
57        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
58
59        token.addWindow(window1);
60        // NOTE: Child windows will not be added to the token as window containers can only
61        // contain/reference their direct children.
62        token.addWindow(window11);
63        token.addWindow(window12);
64        token.addWindow(window2);
65        token.addWindow(window3);
66
67        // Should not contain the child windows that were added above.
68        assertEquals(3, token.getWindowsCount());
69        assertTrue(token.hasWindow(window1));
70        assertFalse(token.hasWindow(window11));
71        assertFalse(token.hasWindow(window12));
72        assertTrue(token.hasWindow(window2));
73        assertTrue(token.hasWindow(window3));
74    }
75
76    @Test
77    public void testChildRemoval() throws Exception {
78        final DisplayContent dc = sDisplayContent;
79        final TestWindowToken token = new TestWindowToken(0, dc);
80
81        assertEquals(token, dc.getWindowToken(token.token));
82
83        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
84        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
85
86        window2.removeImmediately();
87        // The token should still be mapped in the display content since it still has a child.
88        assertEquals(token, dc.getWindowToken(token.token));
89
90        window1.removeImmediately();
91        // The token should have been removed from the display content since it no longer has a
92        // child.
93        assertEquals(null, dc.getWindowToken(token.token));
94    }
95
96    @Test
97    public void testAdjustAnimLayer() throws Exception {
98        final TestWindowToken token = new TestWindowToken(0, sDisplayContent);
99        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
100        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
101        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
102        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
103        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
104
105        window2.mLayer = 100;
106        window3.mLayer = 200;
107
108        // We assign layers once, to get the base values computed by
109        // the controller.
110        sLayersController.assignWindowLayers(sDisplayContent);
111
112        final int window1StartLayer = window1.mWinAnimator.mAnimLayer;
113        final int window11StartLayer = window11.mWinAnimator.mAnimLayer;
114        final int window12StartLayer = window12.mWinAnimator.mAnimLayer;
115        final int window2StartLayer = window2.mWinAnimator.mAnimLayer;
116        final int window3StartLayer = window3.mWinAnimator.mAnimLayer;
117
118        // Then we set an adjustment, and assign them again, they should
119        // be offset.
120        int adj = token.adj = 50;
121        sLayersController.assignWindowLayers(sDisplayContent);
122        final int highestLayer = token.getHighestAnimLayer();
123
124        assertEquals(window1StartLayer + adj, window1.mWinAnimator.mAnimLayer);
125        assertEquals(window11StartLayer + adj, window11.mWinAnimator.mAnimLayer);
126        assertEquals(window12StartLayer + adj, window12.mWinAnimator.mAnimLayer);
127        assertEquals(window2StartLayer + adj, window2.mWinAnimator.mAnimLayer);
128        assertEquals(window3StartLayer + adj, window3.mWinAnimator.mAnimLayer);
129        assertEquals(window3StartLayer + adj, highestLayer);
130    }
131
132    /**
133     * Test that a window token isn't orphaned by the system when it is requested to be removed.
134     * Tokens should only be removed from the system when all their windows are gone.
135     */
136    @Test
137    public void testTokenRemovalProcess() throws Exception {
138        final TestWindowToken token =
139                new TestWindowToken(TYPE_TOAST, sDisplayContent, true /* persistOnEmpty */);
140
141        // Verify that the token is on the display
142        assertNotNull(sDisplayContent.getWindowToken(token.token));
143
144        final WindowState window1 = createWindow(null, TYPE_TOAST, token, "window1");
145        final WindowState window2 = createWindow(null, TYPE_TOAST, token, "window2");
146
147        sDisplayContent.removeWindowToken(token.token);
148        // Verify that the token is no longer mapped on the display
149        assertNull(sDisplayContent.getWindowToken(token.token));
150        // Verify that the token is still attached to its parent
151        assertNotNull(token.getParent());
152        // Verify that the token windows are still around.
153        assertEquals(2, token.getWindowsCount());
154
155        window1.removeImmediately();
156        // Verify that the token is still attached to its parent
157        assertNotNull(token.getParent());
158        // Verify that the other token window is still around.
159        assertEquals(1, token.getWindowsCount());
160
161        window2.removeImmediately();
162        // Verify that the token is no-longer attached to its parent
163        assertNull(token.getParent());
164        // Verify that the token windows are no longer attached to it.
165        assertEquals(0, token.getWindowsCount());
166    }
167}
168