WindowTestsBase.java revision 4ede3e0d0a9e76c701db19e073d2d1ff487d2a64
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.Assert; 20import org.junit.Before; 21 22import android.content.Context; 23import android.os.IBinder; 24import android.support.test.InstrumentationRegistry; 25import android.view.IWindow; 26import android.view.WindowManager; 27 28import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID; 29import static android.app.AppOpsManager.OP_NONE; 30import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; 31import static android.content.res.Configuration.EMPTY; 32import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; 33import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; 34import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 35import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY; 36import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 37import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; 38import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 39import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 40import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; 41import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; 42import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 43import static com.android.server.wm.WindowContainer.POSITION_TOP; 44import static org.mockito.Mockito.mock; 45 46/** 47 * Common base class for window manager unit test classes. 48 */ 49class WindowTestsBase { 50 static WindowManagerService sWm = null; 51 private final IWindow mIWindow = new TestIWindow(); 52 private final Session mMockSession = mock(Session.class); 53 private static int sNextStackId = FIRST_DYNAMIC_STACK_ID; 54 private static int sNextTaskId = 0; 55 56 private static boolean sOneTimeSetupDone = false; 57 static DisplayContent sDisplayContent; 58 static WindowLayersController sLayersController; 59 static WindowState sWallpaperWindow; 60 static WindowState sImeWindow; 61 static WindowState sImeDialogWindow; 62 static WindowState sStatusBarWindow; 63 static WindowState sDockedDividerWindow; 64 static WindowState sNavBarWindow; 65 static WindowState sAppWindow; 66 static WindowState sChildAppWindowAbove; 67 static WindowState sChildAppWindowBelow; 68 69 @Before 70 public void setUp() throws Exception { 71 if (sOneTimeSetupDone) { 72 return; 73 } 74 sOneTimeSetupDone = true; 75 final Context context = InstrumentationRegistry.getTargetContext(); 76 sWm = TestWindowManagerPolicy.getWindowManagerService(context); 77 sLayersController = new WindowLayersController(sWm); 78 sDisplayContent = new DisplayContent(context.getDisplay(), sWm, sLayersController, 79 new WallpaperController(sWm)); 80 sWm.mRoot.addChild(sDisplayContent, 0); 81 82 // Set-up some common windows. 83 sWallpaperWindow = createWindow(null, TYPE_WALLPAPER, sDisplayContent, "wallpaperWindow"); 84 sImeWindow = createWindow(null, TYPE_INPUT_METHOD, sDisplayContent, "sImeWindow"); 85 sImeDialogWindow = 86 createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow"); 87 sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow"); 88 sNavBarWindow = 89 createWindow(null, TYPE_NAVIGATION_BAR, sDisplayContent, "sNavBarWindow"); 90 sDockedDividerWindow = 91 createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow"); 92 sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow"); 93 sChildAppWindowAbove = createWindow(sAppWindow, 94 TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindowAbove"); 95 sChildAppWindowBelow = createWindow(sAppWindow, 96 TYPE_APPLICATION_MEDIA_OVERLAY, sAppWindow.mToken, "sChildAppWindowBelow"); 97 } 98 99 /** Asserts that the first entry is greater than the second entry. */ 100 void assertGreaterThan(int first, int second) throws Exception { 101 Assert.assertTrue("Excepted " + first + " to be greater than " + second, first > second); 102 } 103 104 private WindowToken createWindowToken(DisplayContent dc, int type) { 105 if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) { 106 return new TestWindowToken(type, dc); 107 } 108 109 final TaskStack stack = createTaskStackOnDisplay(dc); 110 final Task task = createTaskInStack(stack, 0 /* userId */); 111 final TestAppWindowToken token = new TestAppWindowToken(dc); 112 task.addChild(token, 0); 113 return token; 114 } 115 116 WindowState createWindow(WindowState parent, int type, String name) { 117 return (parent == null) 118 ? createWindow(parent, type, sDisplayContent, name) 119 : createWindow(parent, type, parent.mToken, name); 120 } 121 122 WindowState createAppWindow(Task task, int type, String name) { 123 final AppWindowToken token = new TestAppWindowToken(sDisplayContent); 124 task.addChild(token, 0); 125 return createWindow(null, type, token, name); 126 } 127 128 WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) { 129 final WindowToken token = createWindowToken(dc, type); 130 return createWindow(parent, type, token, name); 131 } 132 133 WindowState createWindow(WindowState parent, int type, WindowToken token, String name) { 134 final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type); 135 attrs.setTitle(name); 136 137 final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE, 138 0, attrs, 0, 0); 139 // TODO: Probably better to make this call in the WindowState ctor to avoid errors with 140 // adding it to the token... 141 token.addWindow(w); 142 return w; 143 } 144 145 /** Creates a {@link TaskStack} and adds it to the specified {@link DisplayContent}. */ 146 TaskStack createTaskStackOnDisplay(DisplayContent dc) { 147 final int stackId = sNextStackId++; 148 dc.addStackToDisplay(stackId, true); 149 return sWm.mStackIdToStack.get(stackId); 150 } 151 152 /**Creates a {@link Task} and adds it to the specified {@link TaskStack}. */ 153 Task createTaskInStack(TaskStack stack, int userId) { 154 final Task newTask = new Task(sNextTaskId++, stack, userId, sWm, null, EMPTY, false, 0, 155 false, null); 156 stack.addTask(newTask, POSITION_TOP); 157 return newTask; 158 } 159 160 /* Used so we can gain access to some protected members of the {@link WindowToken} class */ 161 class TestWindowToken extends WindowToken { 162 163 TestWindowToken(int type, DisplayContent dc) { 164 this(type, dc, false /* persistOnEmpty */); 165 } 166 167 TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) { 168 super(sWm, mock(IBinder.class), type, persistOnEmpty, dc); 169 } 170 171 int getWindowsCount() { 172 return mChildren.size(); 173 } 174 175 boolean hasWindow(WindowState w) { 176 return mChildren.contains(w); 177 } 178 } 179 180 /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */ 181 class TestAppWindowToken extends AppWindowToken { 182 183 TestAppWindowToken(DisplayContent dc) { 184 super(sWm, null, false, dc); 185 } 186 187 int getWindowsCount() { 188 return mChildren.size(); 189 } 190 191 boolean hasWindow(WindowState w) { 192 return mChildren.contains(w); 193 } 194 195 WindowState getFirstChild() { 196 return mChildren.getFirst(); 197 } 198 199 WindowState getLastChild() { 200 return mChildren.getLast(); 201 } 202 } 203 204 /** 205 * Used so we can gain access to some protected members of {@link TaskWindowContainerController} 206 * class. 207 */ 208 class TestTaskWindowContainerController extends TaskWindowContainerController { 209 210 TestTaskWindowContainerController(int stackId) { 211 super(sNextTaskId++, stackId, 0 /* userId */, null /* bounds */, 212 EMPTY /* overrideConfig*/, RESIZE_MODE_UNRESIZEABLE, false /* homeTask*/, 213 false /* isOnTopLauncher */, true /* toTop*/, true /* showForAllUsers */); 214 } 215 } 216 217 /** Used to track resize reports. */ 218 class TestWindowState extends WindowState { 219 boolean resizeReported; 220 221 TestWindowState(WindowManager.LayoutParams attrs, WindowToken token) { 222 super(sWm, mMockSession, mIWindow, token, null, OP_NONE, 0, attrs, 0, 0); 223 } 224 225 @Override 226 void reportResized() { 227 super.reportResized(); 228 resizeReported = true; 229 } 230 231 @Override 232 public boolean isGoneForLayoutLw() { 233 return false; 234 } 235 236 @Override 237 void updateResizingWindowIfNeeded() { 238 // Used in AppWindowTokenTests#testLandscapeSeascapeRotationRelayout to deceive 239 // the system that it can actually update the window. 240 boolean hadSurface = mHasSurface; 241 mHasSurface = true; 242 243 super.updateResizingWindowIfNeeded(); 244 245 mHasSurface = hadSurface; 246 } 247 } 248} 249