WindowLayersControllerTests.java revision ca9e061256861a86d7d1c2770c666451d3fb53de
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.Before;
20import org.junit.Test;
21import org.junit.runner.RunWith;
22
23import android.platform.test.annotations.Presubmit;
24import android.support.test.filters.SmallTest;
25import android.support.test.runner.AndroidJUnit4;
26
27import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
28import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
29import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
30import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
31import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
32import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
33import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
34import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
35import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
36import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
37
38/**
39 * Tests for the {@link WindowLayersController} class.
40 *
41 * Build/Install/Run:
42 *  bit FrameworksServicesTests:com.android.server.wm.WindowLayersControllerTests
43 */
44@SmallTest
45@Presubmit
46@RunWith(AndroidJUnit4.class)
47public class WindowLayersControllerTests extends WindowTestsBase {
48
49    private static boolean sOneTimeSetupDone = false;
50    private static WindowLayersController sLayersController;
51    private static DisplayContent sDisplayContent;
52    private static WindowState sImeWindow;
53    private static WindowState sImeDialogWindow;
54    private static WindowState sStatusBarWindow;
55    private static WindowState sDockedDividerWindow;
56    private static WindowState sNavBarWindow;
57    private static WindowState sAppWindow;
58    private static WindowState sChildAppWindow;
59
60    @Before
61    public void setUp() throws Exception {
62        super.setUp();
63
64        if (sOneTimeSetupDone) {
65            return;
66        }
67        sOneTimeSetupDone = true;
68        sLayersController = new WindowLayersController(sWm);
69        sDisplayContent =
70                new DisplayContent(mDisplay, sWm, sLayersController, new WallpaperController(sWm));
71        final WindowState wallpaperWindow =
72                createWindow(null, TYPE_WALLPAPER, sDisplayContent, "wallpaperWindow");
73        sImeWindow = createWindow(null, TYPE_INPUT_METHOD, sDisplayContent, "sImeWindow");
74        sImeDialogWindow =
75                createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow");
76        sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow");
77        sNavBarWindow =
78                createWindow(null, TYPE_NAVIGATION_BAR, sStatusBarWindow.mToken, "sNavBarWindow");
79        sDockedDividerWindow =
80                createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow");
81        sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow");
82        sChildAppWindow = createWindow(sAppWindow,
83                TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindow");
84    }
85
86    @Test
87    public void testAssignWindowLayers_ForImeWithNoTarget() throws Exception {
88        sWm.mInputMethodTarget = null;
89        sLayersController.assignWindowLayers(sDisplayContent);
90
91        // The Ime has an higher base layer than app windows and lower base layer than system
92        // windows, so it should be above app windows and below system windows if there isn't an IME
93        // target.
94        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
95        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
96        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
97        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
98        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
99
100        // And, IME dialogs should always have an higher layer than the IME.
101        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
102    }
103
104    @Test
105    public void testAssignWindowLayers_ForImeWithAppTarget() throws Exception {
106        final WindowState imeAppTarget =
107                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
108        sWm.mInputMethodTarget = imeAppTarget;
109        sLayersController.assignWindowLayers(sDisplayContent);
110
111        // Ime should be above all app windows and below system windows if it is targeting an app
112        // window.
113        assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
114        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
115        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
116        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
117        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
118        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
119
120        // And, IME dialogs should always have an higher layer than the IME.
121        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
122    }
123
124    @Test
125    public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() throws Exception {
126        final WindowState imeAppTarget =
127                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
128        final WindowState imeAppTargetChildAboveWindow = createWindow(imeAppTarget,
129                TYPE_APPLICATION_ATTACHED_DIALOG, imeAppTarget.mToken,
130                "imeAppTargetChildAboveWindow");
131        final WindowState imeAppTargetChildBelowWindow = createWindow(imeAppTarget,
132                TYPE_APPLICATION_MEDIA_OVERLAY, imeAppTarget.mToken,
133                "imeAppTargetChildBelowWindow");
134
135        sWm.mInputMethodTarget = imeAppTarget;
136        sLayersController.assignWindowLayers(sDisplayContent);
137
138        // Ime should be above all app windows except for child windows that are z-ordered above it
139        // and below system windows if it is targeting an app window.
140        assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
141        assertWindowLayerGreaterThan(imeAppTargetChildAboveWindow, sImeWindow);
142        assertWindowLayerGreaterThan(sImeWindow, imeAppTargetChildBelowWindow);
143        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
144        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
145        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
146        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
147        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
148
149        // And, IME dialogs should always have an higher layer than the IME.
150        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
151    }
152
153    @Test
154    public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() throws Exception {
155        final WindowState appBelowImeTarget =
156                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "appBelowImeTarget");
157        final WindowState imeAppTarget =
158                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
159        final WindowState appAboveImeTarget =
160                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "appAboveImeTarget");
161
162        sWm.mInputMethodTarget = imeAppTarget;
163        sLayersController.assignWindowLayers(sDisplayContent);
164
165        // Ime should be above all app windows except for non-fullscreen app window above it and
166        // below system windows if it is targeting an app window.
167        assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
168        assertWindowLayerGreaterThan(sImeWindow, appBelowImeTarget);
169        assertWindowLayerGreaterThan(appAboveImeTarget, sImeWindow);
170        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
171        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
172        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
173        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
174        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
175
176        // And, IME dialogs should always have an higher layer than the IME.
177        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
178    }
179
180    @Test
181    public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception {
182        final WindowState imeSystemOverlayTarget =
183                createWindow(null, TYPE_SYSTEM_OVERLAY, sDisplayContent, "imeSystemOverlayTarget");
184
185        sWm.mInputMethodTarget = imeSystemOverlayTarget;
186        sLayersController.assignWindowLayers(sDisplayContent);
187
188        // The IME target base layer is higher than all window except for the nav bar window, so the
189        // IME should be above all windows except for the nav bar.
190        assertWindowLayerGreaterThan(sImeWindow, imeSystemOverlayTarget);
191        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
192        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
193        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
194        assertWindowLayerGreaterThan(sImeWindow, sStatusBarWindow);
195        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
196
197        // And, IME dialogs should always have an higher layer than the IME.
198        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
199    }
200
201    private void assertWindowLayerGreaterThan(WindowState first, WindowState second)
202            throws Exception {
203        assertGreaterThan(first.mWinAnimator.mAnimLayer, second.mWinAnimator.mAnimLayer);
204    }
205
206}
207