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