DisplayContentTests.java revision 8e44f6c46822028a853c41610d2289e299987af0
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 static android.view.Display.DEFAULT_DISPLAY;
20import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
21import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
22import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
23import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
24import static org.junit.Assert.assertEquals;
25import static org.junit.Assert.assertTrue;
26
27import org.junit.Test;
28import org.junit.runner.RunWith;
29
30import android.content.res.Configuration;
31import android.platform.test.annotations.Presubmit;
32import android.support.test.filters.SmallTest;
33import android.support.test.runner.AndroidJUnit4;
34
35import java.util.Arrays;
36import java.util.LinkedList;
37import java.util.List;
38
39/**
40 * Tests for the {@link DisplayContent} class.
41 *
42 * Build/Install/Run:
43 *  bit FrameworksServicesTests:com.android.server.wm.DisplayContentTests
44 */
45@SmallTest
46@Presubmit
47@RunWith(AndroidJUnit4.class)
48public class DisplayContentTests extends WindowTestsBase {
49
50    @Test
51    public void testForAllWindows() throws Exception {
52        final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
53                sDisplayContent, "exiting app");
54        final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
55        exitingAppToken.mIsExiting = true;
56        exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken);
57
58        assertForAllWindowsOrder(Arrays.asList(
59                sWallpaperWindow,
60                exitingAppWindow,
61                sChildAppWindowBelow,
62                sAppWindow,
63                sChildAppWindowAbove,
64                sDockedDividerWindow,
65                sStatusBarWindow,
66                sNavBarWindow,
67                sImeWindow,
68                sImeDialogWindow));
69    }
70
71    @Test
72    public void testForAllWindows_WithAppImeTarget() throws Exception {
73        final WindowState imeAppTarget =
74                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
75
76        sWm.mInputMethodTarget = imeAppTarget;
77
78        assertForAllWindowsOrder(Arrays.asList(
79                sWallpaperWindow,
80                sChildAppWindowBelow,
81                sAppWindow,
82                sChildAppWindowAbove,
83                imeAppTarget,
84                sImeWindow,
85                sImeDialogWindow,
86                sDockedDividerWindow,
87                sStatusBarWindow,
88                sNavBarWindow));
89    }
90
91    @Test
92    public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
93        sWm.mInputMethodTarget = sChildAppWindowAbove;
94
95        assertForAllWindowsOrder(Arrays.asList(
96                sWallpaperWindow,
97                sChildAppWindowBelow,
98                sAppWindow,
99                sChildAppWindowAbove,
100                sImeWindow,
101                sImeDialogWindow,
102                sDockedDividerWindow,
103                sStatusBarWindow,
104                sNavBarWindow));
105    }
106
107    @Test
108    public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
109        sWm.mInputMethodTarget = sStatusBarWindow;
110
111        assertForAllWindowsOrder(Arrays.asList(
112                sWallpaperWindow,
113                sChildAppWindowBelow,
114                sAppWindow,
115                sChildAppWindowAbove,
116                sDockedDividerWindow,
117                sStatusBarWindow,
118                sImeWindow,
119                sImeDialogWindow,
120                sNavBarWindow));
121    }
122
123    @Test
124    public void testForAllWindows_WithInBetweenWindowToken() throws Exception {
125        // This window is set-up to be z-ordered between some windows that go in the same token like
126        // the nav bar and status bar.
127        final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
128                sDisplayContent, "voiceInteractionWindow");
129
130        assertForAllWindowsOrder(Arrays.asList(
131                sWallpaperWindow,
132                sChildAppWindowBelow,
133                sAppWindow,
134                sChildAppWindowAbove,
135                sDockedDividerWindow,
136                voiceInteractionWindow,
137                sStatusBarWindow,
138                sNavBarWindow,
139                sImeWindow,
140                sImeDialogWindow));
141    }
142
143    @Test
144    public void testComputeImeTarget() throws Exception {
145        // Verify that an app window can be an ime target.
146        final WindowState appWin = createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin");
147        appWin.setHasSurface(true);
148        assertTrue(appWin.canBeImeTarget());
149        WindowState imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
150        assertEquals(appWin, imeTarget);
151
152        // Verify that an child window can be an ime target.
153        final WindowState childWin = createWindow(appWin,
154                TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
155        childWin.setHasSurface(true);
156        assertTrue(childWin.canBeImeTarget());
157        imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
158        assertEquals(childWin, imeTarget);
159    }
160
161    /**
162     * This tests stack movement between displays and proper stack's, task's and app token's display
163     * container references updates.
164     */
165    @Test
166    public void testMoveStackBetweenDisplays() throws Exception {
167        // Create a second display.
168        final DisplayContent dc = createNewDisplay();
169
170        // Add stack with activity.
171        final TaskStack stack = createTaskStackOnDisplay(dc);
172        assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
173        assertEquals(dc, stack.getParent().getParent());
174        assertEquals(dc, stack.getDisplayContent());
175
176        final Task task = createTaskInStack(stack, 0 /* userId */);
177        final TestAppWindowToken token = new TestAppWindowToken(dc);
178        task.addChild(token, 0);
179        assertEquals(dc, task.getDisplayContent());
180        assertEquals(dc, token.getDisplayContent());
181
182        // Move stack to first display.
183        sDisplayContent.moveStackToDisplay(stack);
184        assertEquals(sDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
185        assertEquals(sDisplayContent, stack.getParent().getParent());
186        assertEquals(sDisplayContent, stack.getDisplayContent());
187        assertEquals(sDisplayContent, task.getDisplayContent());
188        assertEquals(sDisplayContent, token.getDisplayContent());
189    }
190
191    /**
192     * This tests override configuration updates for display content.
193     */
194    @Test
195    public void testDisplayOverrideConfigUpdate() throws Exception {
196        final int displayId = sDisplayContent.getDisplayId();
197        final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration();
198
199        // Create new, slightly changed override configuration and apply it to the display.
200        final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
201        newOverrideConfig.densityDpi += 120;
202        newOverrideConfig.fontScale += 0.3;
203
204        sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId);
205
206        // Check that override config is applied.
207        assertEquals(newOverrideConfig, sDisplayContent.getOverrideConfiguration());
208    }
209
210    /**
211     * This tests global configuration updates when default display config is updated.
212     */
213    @Test
214    public void testDefaultDisplayOverrideConfigUpdate() throws Exception {
215        final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration();
216
217        // Create new, slightly changed override configuration and apply it to the display.
218        final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
219        newOverrideConfig.densityDpi += 120;
220        newOverrideConfig.fontScale += 0.3;
221
222        sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY);
223
224        // Check that global configuration is updated, as we've updated default display's config.
225        Configuration globalConfig = sWm.mRoot.getConfiguration();
226        assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
227        assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
228
229        // Return back to original values.
230        sWm.setNewDisplayOverrideConfiguration(currentOverrideConfig, DEFAULT_DISPLAY);
231        globalConfig = sWm.mRoot.getConfiguration();
232        assertEquals(currentOverrideConfig.densityDpi, globalConfig.densityDpi);
233        assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
234    }
235
236    private void assertForAllWindowsOrder(List<WindowState> expectedWindows) {
237        final LinkedList<WindowState> actualWindows = new LinkedList();
238
239        // Test forward traversal.
240        sDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
241        assertEquals(expectedWindows.size(), actualWindows.size());
242        for (WindowState w : expectedWindows) {
243            assertEquals(w, actualWindows.pollFirst());
244        }
245        assertTrue(actualWindows.isEmpty());
246
247        // Test backward traversal.
248        sDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
249        assertEquals(expectedWindows.size(), actualWindows.size());
250        for (WindowState w : expectedWindows) {
251            assertEquals(w, actualWindows.pollLast());
252        }
253        assertTrue(actualWindows.isEmpty());
254    }
255}
256