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