blob: da1defabeaafd44159cd2749a6c26bd683084b28 [file] [log] [blame]
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +09001/*
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
17package com.android.server.wm;
18
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090019import static android.app.AppOpsManager.OP_NONE;
20import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
21
Tadashi G. Takaokaa7a66952018-11-16 15:04:21 +090022import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090023import static com.android.server.wm.WindowContainer.POSITION_TOP;
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090024
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090025import android.app.ActivityManager;
26import android.content.ComponentName;
Tiger Huang51c5a1d2018-12-11 20:24:51 +080027import android.os.Build;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090028import android.os.IBinder;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090029import android.view.IApplicationToken;
30import android.view.IWindow;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090031import android.view.WindowManager;
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090032
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090033/**
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +090034 * A collection of static functions that provide access to WindowManager related test functionality.
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090035 */
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +090036class WindowTestUtils {
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090037 private static int sNextTaskId = 0;
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +090038
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090039 /** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +090040 static Task createTaskInStack(WindowManagerService service, TaskStack stack,
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090041 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
Yunfan Chen0e7aff92018-12-05 16:35:32 -080050 /** Creates an {@link AppWindowToken} and adds it to the specified {@link Task}. */
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +090051 static TestAppWindowToken createAppWindowTokenInTask(DisplayContent dc, Task task) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -080052 final TestAppWindowToken newToken = createTestAppWindowToken(dc);
53 task.addChild(newToken, POSITION_TOP);
54 return newToken;
55 }
56
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090057 static TestAppWindowToken createTestAppWindowToken(DisplayContent dc) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -080058 synchronized (dc.mWmService.mGlobalLock) {
Vishnu Nairf77d53d2019-02-20 14:38:50 -080059 return new TestAppWindowToken(dc, true /* skipOnParentChanged */);
60 }
61 }
62
63 static TestAppWindowToken createTestAppWindowToken(DisplayContent dc,
64 boolean skipOnParentChanged) {
65 synchronized (dc.mWmService.mGlobalLock) {
66 return new TestAppWindowToken(dc, skipOnParentChanged);
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090067 }
68 }
69
70 /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +090071 static class TestAppWindowToken extends AppWindowToken {
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090072 boolean mOnTop = false;
Riddle Hsub398da32019-01-21 21:48:16 +080073 private boolean mSkipPrepareSurfaces;
Riddle Hsu3a4bb612019-01-31 00:02:22 +080074 boolean mSkipOnParentChanged = true;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090075
Vishnu Nairf77d53d2019-02-20 14:38:50 -080076 private TestAppWindowToken(DisplayContent dc, boolean skipOnParentChanged) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -080077 super(dc.mWmService, new IApplicationToken.Stub() {
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090078 @Override
79 public String getName() {
80 return null;
81 }
82 }, new ComponentName("", ""), false, dc, true /* fillsParent */);
Tiger Huang51c5a1d2018-12-11 20:24:51 +080083 mTargetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT;
Vishnu Nairf77d53d2019-02-20 14:38:50 -080084 mSkipOnParentChanged = skipOnParentChanged;
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090085 }
86
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +090087 int getWindowsCount() {
88 return mChildren.size();
89 }
90
91 boolean hasWindow(WindowState w) {
92 return mChildren.contains(w);
93 }
94
95 WindowState getFirstChild() {
96 return mChildren.peekFirst();
97 }
98
99 WindowState getLastChild() {
100 return mChildren.peekLast();
101 }
102
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900103 @Override
Riddle Hsu3a4bb612019-01-31 00:02:22 +0800104 void onParentChanged() {
105 if (!mSkipOnParentChanged) {
106 super.onParentChanged();
107 } else {
108 updateConfigurationFromParent(this);
Evan Rosky966759f2019-01-15 10:33:58 -0800109 }
Yunfan Chen279f5582018-12-12 15:24:50 -0800110 }
111
112 @Override
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900113 boolean isOnTop() {
114 return mOnTop;
115 }
116
Riddle Hsub398da32019-01-21 21:48:16 +0800117 @Override
118 void prepareSurfaces() {
119 if (!mSkipPrepareSurfaces) {
120 super.prepareSurfaces();
121 }
122 }
123
124 void setSkipPrepareSurfaces(boolean ignore) {
125 mSkipPrepareSurfaces = ignore;
126 }
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900127 }
128
Riddle Hsu3a4bb612019-01-31 00:02:22 +0800129 /**
130 * Used when we don't want to perform surface related operation in
131 * {@link WindowContainer#onParentChanged} or the overridden method, but the configuration
132 * still needs to propagate from parent.
133 *
134 * @see ConfigurationContainer#onParentChanged
135 */
136 static void updateConfigurationFromParent(WindowContainer container) {
137 final WindowContainer parent = container.getParent();
138 if (parent != null) {
139 container.onConfigurationChanged(parent.getConfiguration());
140 container.onMergedOverrideConfigurationChanged();
141 }
142 }
143
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900144 static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {
145 return createTestWindowToken(type, dc, false /* persistOnEmpty */);
146 }
147
148 static TestWindowToken createTestWindowToken(int type, DisplayContent dc,
149 boolean persistOnEmpty) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800150 synchronized (dc.mWmService.mGlobalLock) {
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900151 return new TestWindowToken(type, dc, persistOnEmpty);
152 }
153 }
154
155 /* Used so we can gain access to some protected members of the {@link WindowToken} class */
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900156 static class TestWindowToken extends WindowToken {
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900157
158 private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800159 super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc,
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900160 false /* ownerCanManageAppTokens */);
161 }
162
163 int getWindowsCount() {
164 return mChildren.size();
165 }
166
167 boolean hasWindow(WindowState w) {
168 return mChildren.contains(w);
169 }
170 }
171
172 /* Used so we can gain access to some protected members of the {@link Task} class */
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900173 static class TestTask extends Task {
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900174 boolean mShouldDeferRemoval = false;
175 boolean mOnDisplayChangedCalled = false;
176 private boolean mIsAnimating = false;
177
178 TestTask(int taskId, TaskStack stack, int userId, WindowManagerService service,
179 int resizeMode, boolean supportsPictureInPicture,
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800180 TaskRecord taskRecord) {
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900181 super(taskId, stack, userId, service, resizeMode, supportsPictureInPicture,
Yunfan Chen0e7aff92018-12-05 16:35:32 -0800182 new ActivityManager.TaskDescription(), taskRecord);
183 stack.addTask(this, POSITION_TOP);
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900184 }
185
186 boolean shouldDeferRemoval() {
187 return mShouldDeferRemoval;
188 }
189
190 int positionInParent() {
191 return getParent().mChildren.indexOf(this);
192 }
193
194 @Override
195 void onDisplayChanged(DisplayContent dc) {
196 super.onDisplayChanged(dc);
197 mOnDisplayChangedCalled = true;
198 }
199
200 @Override
201 boolean isSelfAnimating() {
202 return mIsAnimating;
203 }
204
205 void setLocalIsAnimating(boolean isAnimating) {
206 mIsAnimating = isAnimating;
207 }
208 }
209
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900210 static TestTask createTestTask(TaskStack stack) {
Yunfan Chen279f5582018-12-12 15:24:50 -0800211 return new TestTask(sNextTaskId++, stack, 0, stack.mWmService, RESIZE_MODE_UNRESIZEABLE,
212 false, mock(TaskRecord.class));
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900213 }
214
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900215 /** Used to track resize reports. */
Tadashi G. Takaokad7aa79a2019-02-08 17:42:37 +0900216 static class TestWindowState extends WindowState {
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900217 boolean mResizeReported;
218
219 TestWindowState(WindowManagerService service, Session session, IWindow window,
220 WindowManager.LayoutParams attrs, WindowToken token) {
221 super(service, session, window, token, null, OP_NONE, 0, attrs, 0, 0,
222 false /* ownerCanAddInternalSystemWindow */);
223 }
224
225 @Override
226 void reportResized() {
227 super.reportResized();
228 mResizeReported = 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 }
Yunfan Chen279f5582018-12-12 15:24:50 -0800247
248 @Override
Riddle Hsu3a4bb612019-01-31 00:02:22 +0800249 void onParentChanged() {
250 updateConfigurationFromParent(this);
Yunfan Chen279f5582018-12-12 15:24:50 -0800251 }
Tadashi G. Takaokabf0d57b2018-11-19 16:09:58 +0900252 }
Tadashi G. Takaoka74ccec22018-10-23 11:07:13 +0900253}