WindowLayersControllerTests.java revision 11cc516a925ac7fc814dbb0a79a7f0abfbfe1ce1
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.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
27import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
28import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
29import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
30import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
31import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
32import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
33
34/**
35 * Tests for the {@link WindowLayersController} class.
36 *
37 * Build/Install/Run:
38 *  bit FrameworksServicesTests:com.android.server.wm.WindowLayersControllerTests
39 */
40@SmallTest
41@Presubmit
42@RunWith(AndroidJUnit4.class)
43public class WindowLayersControllerTests extends WindowTestsBase {
44
45    @Test
46    public void testAssignWindowLayers_ForImeWithNoTarget() throws Exception {
47        sWm.mInputMethodTarget = null;
48        mLayersController.assignWindowLayers(mDisplayContent);
49
50        // The Ime has an higher base layer than app windows and lower base layer than system
51        // windows, so it should be above app windows and below system windows if there isn't an IME
52        // target.
53        assertWindowLayerGreaterThan(mImeWindow, mChildAppWindowAbove);
54        assertWindowLayerGreaterThan(mImeWindow, mAppWindow);
55        assertWindowLayerGreaterThan(mImeWindow, mDockedDividerWindow);
56        assertWindowLayerGreaterThan(mNavBarWindow, mImeWindow);
57        assertWindowLayerGreaterThan(mStatusBarWindow, mImeWindow);
58
59        // And, IME dialogs should always have an higher layer than the IME.
60        assertWindowLayerGreaterThan(mImeDialogWindow, mImeWindow);
61    }
62
63    @Test
64    public void testAssignWindowLayers_ForImeWithAppTarget() throws Exception {
65        final WindowState imeAppTarget =
66                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
67        sWm.mInputMethodTarget = imeAppTarget;
68        mLayersController.assignWindowLayers(mDisplayContent);
69
70        // Ime should be above all app windows and below system windows if it is targeting an app
71        // window.
72        assertWindowLayerGreaterThan(mImeWindow, imeAppTarget);
73        assertWindowLayerGreaterThan(mImeWindow, mChildAppWindowAbove);
74        assertWindowLayerGreaterThan(mImeWindow, mAppWindow);
75        assertWindowLayerGreaterThan(mImeWindow, mDockedDividerWindow);
76        assertWindowLayerGreaterThan(mNavBarWindow, mImeWindow);
77        assertWindowLayerGreaterThan(mStatusBarWindow, mImeWindow);
78
79        // And, IME dialogs should always have an higher layer than the IME.
80        assertWindowLayerGreaterThan(mImeDialogWindow, mImeWindow);
81    }
82
83    @Test
84    public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() throws Exception {
85        final WindowState imeAppTarget =
86                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
87        final WindowState imeAppTargetChildAboveWindow = createWindow(imeAppTarget,
88                TYPE_APPLICATION_ATTACHED_DIALOG, imeAppTarget.mToken,
89                "imeAppTargetChildAboveWindow");
90        final WindowState imeAppTargetChildBelowWindow = createWindow(imeAppTarget,
91                TYPE_APPLICATION_MEDIA_OVERLAY, imeAppTarget.mToken,
92                "imeAppTargetChildBelowWindow");
93
94        sWm.mInputMethodTarget = imeAppTarget;
95        mLayersController.assignWindowLayers(mDisplayContent);
96
97        // Ime should be above all app windows except for child windows that are z-ordered above it
98        // and below system windows if it is targeting an app window.
99        assertWindowLayerGreaterThan(mImeWindow, imeAppTarget);
100        assertWindowLayerGreaterThan(imeAppTargetChildAboveWindow, mImeWindow);
101        assertWindowLayerGreaterThan(mImeWindow, imeAppTargetChildBelowWindow);
102        assertWindowLayerGreaterThan(mImeWindow, mChildAppWindowAbove);
103        assertWindowLayerGreaterThan(mImeWindow, mAppWindow);
104        assertWindowLayerGreaterThan(mImeWindow, mDockedDividerWindow);
105        assertWindowLayerGreaterThan(mNavBarWindow, mImeWindow);
106        assertWindowLayerGreaterThan(mStatusBarWindow, mImeWindow);
107
108        // And, IME dialogs should always have an higher layer than the IME.
109        assertWindowLayerGreaterThan(mImeDialogWindow, mImeWindow);
110    }
111
112    @Test
113    public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() throws Exception {
114        final WindowState appBelowImeTarget =
115                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "appBelowImeTarget");
116        final WindowState imeAppTarget =
117                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
118        final WindowState appAboveImeTarget =
119                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "appAboveImeTarget");
120
121        sWm.mInputMethodTarget = imeAppTarget;
122        mLayersController.assignWindowLayers(mDisplayContent);
123
124        // Ime should be above all app windows except for non-fullscreen app window above it and
125        // below system windows if it is targeting an app window.
126        assertWindowLayerGreaterThan(mImeWindow, imeAppTarget);
127        assertWindowLayerGreaterThan(mImeWindow, appBelowImeTarget);
128        assertWindowLayerGreaterThan(appAboveImeTarget, mImeWindow);
129        assertWindowLayerGreaterThan(mImeWindow, mChildAppWindowAbove);
130        assertWindowLayerGreaterThan(mImeWindow, mAppWindow);
131        assertWindowLayerGreaterThan(mImeWindow, mDockedDividerWindow);
132        assertWindowLayerGreaterThan(mNavBarWindow, mImeWindow);
133        assertWindowLayerGreaterThan(mStatusBarWindow, mImeWindow);
134
135        // And, IME dialogs should always have an higher layer than the IME.
136        assertWindowLayerGreaterThan(mImeDialogWindow, mImeWindow);
137    }
138
139    @Test
140    public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception {
141        final WindowState imeSystemOverlayTarget = createWindow(null, TYPE_SYSTEM_OVERLAY,
142                mDisplayContent, "imeSystemOverlayTarget",
143                true /* ownerCanAddInternalSystemWindow */);
144
145        sWm.mInputMethodTarget = imeSystemOverlayTarget;
146        mLayersController.assignWindowLayers(mDisplayContent);
147
148        // The IME target base layer is higher than all window except for the nav bar window, so the
149        // IME should be above all windows except for the nav bar.
150        assertWindowLayerGreaterThan(mImeWindow, imeSystemOverlayTarget);
151        assertWindowLayerGreaterThan(mImeWindow, mChildAppWindowAbove);
152        assertWindowLayerGreaterThan(mImeWindow, mAppWindow);
153        assertWindowLayerGreaterThan(mImeWindow, mDockedDividerWindow);
154        assertWindowLayerGreaterThan(mImeWindow, mStatusBarWindow);
155        assertWindowLayerGreaterThan(mNavBarWindow, mImeWindow);
156
157        // And, IME dialogs should always have an higher layer than the IME.
158        assertWindowLayerGreaterThan(mImeDialogWindow, mImeWindow);
159    }
160
161    @Test
162    public void testStackLayers() throws Exception {
163        WindowState pinnedStackWindow = createWindowOnStack(null, PINNED_STACK_ID,
164                TYPE_BASE_APPLICATION, mDisplayContent, "pinnedStackWindow");
165        WindowState dockedStackWindow = createWindowOnStack(null, DOCKED_STACK_ID,
166                TYPE_BASE_APPLICATION, mDisplayContent, "dockedStackWindow");
167        WindowState assistantStackWindow = createWindowOnStack(null, ASSISTANT_STACK_ID,
168                TYPE_BASE_APPLICATION, mDisplayContent, "assistantStackWindow");
169
170        mLayersController.assignWindowLayers(mDisplayContent);
171
172        assertWindowLayerGreaterThan(dockedStackWindow, mAppWindow);
173        assertWindowLayerGreaterThan(assistantStackWindow, dockedStackWindow);
174        assertWindowLayerGreaterThan(pinnedStackWindow, assistantStackWindow);
175    }
176
177    private void assertWindowLayerGreaterThan(WindowState first, WindowState second)
178            throws Exception {
179        assertGreaterThan(first.mWinAnimator.mAnimLayer, second.mWinAnimator.mAnimLayer);
180    }
181
182}
183