1 /* 2 * Copyright (C) 2017 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 17 package com.android.server.wm; 18 19 import static android.app.AppOpsManager.OP_NONE; 20 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; 21 22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; 23 import static com.android.server.wm.WindowContainer.POSITION_TOP; 24 25 import android.app.ActivityManager; 26 import android.content.ComponentName; 27 import android.os.Build; 28 import android.os.IBinder; 29 import android.view.IApplicationToken; 30 import android.view.IWindow; 31 import android.view.WindowManager; 32 33 /** 34 * A collection of static functions that provide access to WindowManager related test functionality. 35 */ 36 class WindowTestUtils { 37 private static int sNextTaskId = 0; 38 39 /** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */ createTaskInStack(WindowManagerService service, TaskStack stack, int userId)40 static Task createTaskInStack(WindowManagerService service, TaskStack stack, 41 int userId) { 42 synchronized (service.mGlobalLock) { 43 final Task newTask = new Task(sNextTaskId++, stack, userId, service, 0, false, 44 new ActivityManager.TaskDescription(), null); 45 stack.addTask(newTask, POSITION_TOP); 46 return newTask; 47 } 48 } 49 50 /** Creates an {@link AppWindowToken} and adds it to the specified {@link Task}. */ createAppWindowTokenInTask(DisplayContent dc, Task task)51 static TestAppWindowToken createAppWindowTokenInTask(DisplayContent dc, Task task) { 52 final TestAppWindowToken newToken = createTestAppWindowToken(dc); 53 task.addChild(newToken, POSITION_TOP); 54 return newToken; 55 } 56 createTestAppWindowToken(DisplayContent dc)57 static TestAppWindowToken createTestAppWindowToken(DisplayContent dc) { 58 synchronized (dc.mWmService.mGlobalLock) { 59 return new TestAppWindowToken(dc); 60 } 61 } 62 63 /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */ 64 static class TestAppWindowToken extends AppWindowToken { 65 boolean mOnTop = false; 66 TestAppWindowToken(DisplayContent dc)67 private TestAppWindowToken(DisplayContent dc) { 68 super(dc.mWmService, new IApplicationToken.Stub() { 69 @Override 70 public String getName() { 71 return null; 72 } 73 }, new ComponentName("", ""), false, dc, true /* fillsParent */); 74 mTargetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT; 75 mActivityRecord = mock(ActivityRecord.class); 76 mActivityRecord.app = mock(WindowProcessController.class); 77 } 78 getWindowsCount()79 int getWindowsCount() { 80 return mChildren.size(); 81 } 82 hasWindow(WindowState w)83 boolean hasWindow(WindowState w) { 84 return mChildren.contains(w); 85 } 86 getFirstChild()87 WindowState getFirstChild() { 88 return mChildren.peekFirst(); 89 } 90 getLastChild()91 WindowState getLastChild() { 92 return mChildren.peekLast(); 93 } 94 95 @Override isOnTop()96 boolean isOnTop() { 97 return mOnTop; 98 } 99 100 } 101 createTestWindowToken(int type, DisplayContent dc)102 static TestWindowToken createTestWindowToken(int type, DisplayContent dc) { 103 return createTestWindowToken(type, dc, false /* persistOnEmpty */); 104 } 105 createTestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty)106 static TestWindowToken createTestWindowToken(int type, DisplayContent dc, 107 boolean persistOnEmpty) { 108 synchronized (dc.mWmService.mGlobalLock) { 109 return new TestWindowToken(type, dc, persistOnEmpty); 110 } 111 } 112 113 /* Used so we can gain access to some protected members of the {@link WindowToken} class */ 114 static class TestWindowToken extends WindowToken { 115 TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty)116 private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) { 117 super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc, 118 false /* ownerCanManageAppTokens */); 119 } 120 getWindowsCount()121 int getWindowsCount() { 122 return mChildren.size(); 123 } 124 hasWindow(WindowState w)125 boolean hasWindow(WindowState w) { 126 return mChildren.contains(w); 127 } 128 } 129 130 /* Used so we can gain access to some protected members of the {@link Task} class */ 131 static class TestTask extends Task { 132 boolean mShouldDeferRemoval = false; 133 boolean mOnDisplayChangedCalled = false; 134 private boolean mIsAnimating = false; 135 TestTask(int taskId, TaskStack stack, int userId, WindowManagerService service, int resizeMode, boolean supportsPictureInPicture, TaskRecord taskRecord)136 TestTask(int taskId, TaskStack stack, int userId, WindowManagerService service, 137 int resizeMode, boolean supportsPictureInPicture, 138 TaskRecord taskRecord) { 139 super(taskId, stack, userId, service, resizeMode, supportsPictureInPicture, 140 new ActivityManager.TaskDescription(), taskRecord); 141 stack.addTask(this, POSITION_TOP); 142 } 143 shouldDeferRemoval()144 boolean shouldDeferRemoval() { 145 return mShouldDeferRemoval; 146 } 147 positionInParent()148 int positionInParent() { 149 return getParent().mChildren.indexOf(this); 150 } 151 152 @Override onDisplayChanged(DisplayContent dc)153 void onDisplayChanged(DisplayContent dc) { 154 super.onDisplayChanged(dc); 155 mOnDisplayChangedCalled = true; 156 } 157 158 @Override isSelfAnimating()159 boolean isSelfAnimating() { 160 return mIsAnimating; 161 } 162 setLocalIsAnimating(boolean isAnimating)163 void setLocalIsAnimating(boolean isAnimating) { 164 mIsAnimating = isAnimating; 165 } 166 } 167 createTestTask(TaskStack stack)168 static TestTask createTestTask(TaskStack stack) { 169 return new TestTask(sNextTaskId++, stack, 0, stack.mWmService, RESIZE_MODE_UNRESIZEABLE, 170 false, mock(TaskRecord.class)); 171 } 172 173 /** Used to track resize reports. */ 174 static class TestWindowState extends WindowState { 175 boolean mResizeReported; 176 TestWindowState(WindowManagerService service, Session session, IWindow window, WindowManager.LayoutParams attrs, WindowToken token)177 TestWindowState(WindowManagerService service, Session session, IWindow window, 178 WindowManager.LayoutParams attrs, WindowToken token) { 179 super(service, session, window, token, null, OP_NONE, 0, attrs, 0, 0, 180 false /* ownerCanAddInternalSystemWindow */); 181 } 182 183 @Override reportResized()184 void reportResized() { 185 super.reportResized(); 186 mResizeReported = true; 187 } 188 189 @Override isGoneForLayoutLw()190 public boolean isGoneForLayoutLw() { 191 return false; 192 } 193 194 @Override updateResizingWindowIfNeeded()195 void updateResizingWindowIfNeeded() { 196 // Used in AppWindowTokenTests#testLandscapeSeascapeRotationRelayout to deceive 197 // the system that it can actually update the window. 198 boolean hadSurface = mHasSurface; 199 mHasSurface = true; 200 201 super.updateResizingWindowIfNeeded(); 202 203 mHasSurface = hadSurface; 204 } 205 } 206 } 207