WindowStateTests.java revision 342479581e113a6cf05f6e1d6470a86ad6032bcb
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 java.util.LinkedList;
27
28import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
29import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
30import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
31import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
32import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
33import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
34import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
35import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
36import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
37import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
38import static org.junit.Assert.assertEquals;
39import static org.junit.Assert.assertFalse;
40import static org.junit.Assert.assertNull;
41import static org.junit.Assert.assertTrue;
42
43/**
44 * Tests for the {@link WindowState} class.
45 *
46 * Build/Install/Run:
47 *  bit FrameworksServicesTests:com.android.server.wm.WindowStateTests
48 */
49@SmallTest
50@Presubmit
51@RunWith(AndroidJUnit4.class)
52public class WindowStateTests extends WindowTestsBase {
53
54    @Test
55    public void testIsParentWindowHidden() throws Exception {
56        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
57        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
58        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
59
60        assertFalse(parentWindow.mHidden);
61        assertFalse(parentWindow.isParentWindowHidden());
62        assertFalse(child1.isParentWindowHidden());
63        assertFalse(child2.isParentWindowHidden());
64
65        parentWindow.mHidden = true;
66        assertFalse(parentWindow.isParentWindowHidden());
67        assertTrue(child1.isParentWindowHidden());
68        assertTrue(child2.isParentWindowHidden());
69    }
70
71    @Test
72    public void testIsChildWindow() throws Exception {
73        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
74        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
75        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
76        final WindowState randomWindow = createWindow(null, TYPE_APPLICATION, "randomWindow");
77
78        assertFalse(parentWindow.isChildWindow());
79        assertTrue(child1.isChildWindow());
80        assertTrue(child2.isChildWindow());
81        assertFalse(randomWindow.isChildWindow());
82    }
83
84    @Test
85    public void testHasChild() throws Exception {
86        final WindowState win1 = createWindow(null, TYPE_APPLICATION, "win1");
87        final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW, "win11");
88        final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW, "win12");
89        final WindowState win2 = createWindow(null, TYPE_APPLICATION, "win2");
90        final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW, "win21");
91        final WindowState randomWindow = createWindow(null, TYPE_APPLICATION, "randomWindow");
92
93        assertTrue(win1.hasChild(win11));
94        assertTrue(win1.hasChild(win12));
95        assertTrue(win2.hasChild(win21));
96
97        assertFalse(win1.hasChild(win21));
98        assertFalse(win1.hasChild(randomWindow));
99
100        assertFalse(win2.hasChild(win11));
101        assertFalse(win2.hasChild(win12));
102        assertFalse(win2.hasChild(randomWindow));
103    }
104
105    @Test
106    public void testGetParentWindow() throws Exception {
107        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
108        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
109        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
110
111        assertNull(parentWindow.getParentWindow());
112        assertEquals(parentWindow, child1.getParentWindow());
113        assertEquals(parentWindow, child2.getParentWindow());
114    }
115
116    @Test
117    public void testGetTopParentWindow() throws Exception {
118        final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
119        final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, "child1");
120        final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, "child2");
121
122        assertEquals(root, root.getTopParentWindow());
123        assertEquals(root, child1.getTopParentWindow());
124        assertEquals(child1, child2.getParentWindow());
125        assertEquals(root, child2.getTopParentWindow());
126
127        // Test case were child is detached from parent.
128        root.removeChild(child1);
129        assertEquals(child1, child1.getTopParentWindow());
130        assertEquals(child1, child2.getParentWindow());
131    }
132
133    @Test
134    public void testIsOnScreen_hiddenByPolicy() {
135        final WindowState window = createWindow(null, TYPE_APPLICATION, "window");
136        window.setHasSurface(true);
137        assertTrue(window.isOnScreen());
138        window.hideLw(false /* doAnimation */);
139        assertFalse(window.isOnScreen());
140    }
141
142    @Test
143    public void testCanBeImeTarget() throws Exception {
144        final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow");
145        final WindowState imeWindow = createWindow(null, TYPE_INPUT_METHOD, "imeWindow");
146
147        // Setting FLAG_NOT_FOCUSABLE without FLAG_ALT_FOCUSABLE_IM prevents the window from being
148        // an IME target.
149        appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
150        imeWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
151
152        // Make windows visible
153        appWindow.setHasSurface(true);
154        imeWindow.setHasSurface(true);
155
156        // Windows without flags (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM) can't be IME targets
157        assertFalse(appWindow.canBeImeTarget());
158        assertFalse(imeWindow.canBeImeTarget());
159
160        // Add IME target flags
161        appWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
162        imeWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
163
164        // Visible app window with flags can be IME target while an IME window can never be an IME
165        // target regardless of its visibility or flags.
166        assertTrue(appWindow.canBeImeTarget());
167        assertFalse(imeWindow.canBeImeTarget());
168
169        // Make windows invisible
170        appWindow.hideLw(false /* doAnimation */);
171        imeWindow.hideLw(false /* doAnimation */);
172
173        // Invisible window can't be IME targets even if they have the right flags.
174        assertFalse(appWindow.canBeImeTarget());
175        assertFalse(imeWindow.canBeImeTarget());
176    }
177
178    @Test
179    public void testGetWindow() throws Exception {
180        final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
181        final WindowState mediaChild = createWindow(root, TYPE_APPLICATION_MEDIA, "mediaChild");
182        final WindowState mediaOverlayChild = createWindow(root,
183                TYPE_APPLICATION_MEDIA_OVERLAY, "mediaOverlayChild");
184        final WindowState attachedDialogChild = createWindow(root,
185                TYPE_APPLICATION_ATTACHED_DIALOG, "attachedDialogChild");
186        final WindowState subPanelChild = createWindow(root,
187                TYPE_APPLICATION_SUB_PANEL, "subPanelChild");
188        final WindowState aboveSubPanelChild = createWindow(root,
189                TYPE_APPLICATION_ABOVE_SUB_PANEL, "aboveSubPanelChild");
190
191        final LinkedList<WindowState> windows = new LinkedList();
192
193        root.getWindow(w -> {
194            windows.addLast(w);
195            return false;
196        });
197
198        // getWindow should have returned candidate windows in z-order.
199        assertEquals(aboveSubPanelChild, windows.pollFirst());
200        assertEquals(subPanelChild, windows.pollFirst());
201        assertEquals(attachedDialogChild, windows.pollFirst());
202        assertEquals(root, windows.pollFirst());
203        assertEquals(mediaOverlayChild, windows.pollFirst());
204        assertEquals(mediaChild, windows.pollFirst());
205        assertTrue(windows.isEmpty());
206    }
207}
208