blob: ed635ce3f69ee14448402b42a094b908d9a3f7be [file] [log] [blame]
Robert Carr8a2f9132019-11-11 15:03:15 -08001/*
Evan Rosky0037e5f2019-11-05 10:26:24 -08002 * Copyright (C) 2020 The Android Open Source Project
Robert Carr8a2f9132019-11-11 15:03:15 -08003 *
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
Evan Rosky0037e5f2019-11-05 10:26:24 -080019import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
20import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
21import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
22import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Robert Carr8a2f9132019-11-11 15:03:15 -080023import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Robert Carr00c0dbe2020-01-24 15:30:24 -080024import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
Evan Rosky0037e5f2019-11-05 10:26:24 -080025import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
26import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
27import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
28import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Robert Carre10ee3d2019-11-11 15:03:15 -080029import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Robert Carr8a2f9132019-11-11 15:03:15 -080030
Wale Ogunwale0d465192020-01-23 19:14:44 -080031import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
Evan Roskyaf9f27c2020-02-18 18:58:35 +000032import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
Robert Carr8a2f9132019-11-11 15:03:15 -080033import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
Evan Roskya8fde152020-01-07 19:09:13 -080034import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
Rob Carr25376512020-03-09 15:23:19 -070035import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
Evan Roskyaf9f27c2020-02-18 18:58:35 +000036import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
Robert Carr8a2f9132019-11-11 15:03:15 -080037import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
38import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
Robert Carr8a2f9132019-11-11 15:03:15 -080039import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
Louis Changa009c762020-02-26 11:21:31 +080040import static com.android.server.wm.WindowContainer.POSITION_TOP;
Robert Carr8a2f9132019-11-11 15:03:15 -080041
Evan Rosky0037e5f2019-11-05 10:26:24 -080042import static org.junit.Assert.assertEquals;
Jorim Jaggi2a3002a2020-02-17 15:57:34 +000043import static org.junit.Assert.assertFalse;
Evan Rosky05ec8862020-02-28 19:37:04 -080044import static org.junit.Assert.assertNotEquals;
Evan Roskyaf9f27c2020-02-18 18:58:35 +000045import static org.junit.Assert.assertNotNull;
Evan Rosky0037e5f2019-11-05 10:26:24 -080046import static org.junit.Assert.assertTrue;
47import static org.mockito.ArgumentMatchers.any;
Robert Carrf6690d12020-02-04 14:16:21 -080048import static org.mockito.ArgumentMatchers.anyBoolean;
Robert Carre10ee3d2019-11-11 15:03:15 -080049import static org.mockito.ArgumentMatchers.anyInt;
Evan Rosky0037e5f2019-11-05 10:26:24 -080050
51import android.app.ActivityManager.RunningTaskInfo;
52import android.app.ActivityManager.StackInfo;
Robert Carrf6690d12020-02-04 14:16:21 -080053import android.app.PictureInPictureParams;
Evan Roskyaf9f27c2020-02-18 18:58:35 +000054import android.content.pm.ActivityInfo;
Evan Rosky0037e5f2019-11-05 10:26:24 -080055import android.content.res.Configuration;
Robert Carr8a2f9132019-11-11 15:03:15 -080056import android.graphics.Rect;
Robert Carr8a2f9132019-11-11 15:03:15 -080057import android.os.Binder;
Evan Roskya8fde152020-01-07 19:09:13 -080058import android.os.IBinder;
Robert Carr8a2f9132019-11-11 15:03:15 -080059import android.os.RemoteException;
Evan Rosky0037e5f2019-11-05 10:26:24 -080060import android.platform.test.annotations.Presubmit;
Evan Roskya8fde152020-01-07 19:09:13 -080061import android.util.ArrayMap;
Robert Carrf6690d12020-02-04 14:16:21 -080062import android.util.Rational;
Evan Rosky0037e5f2019-11-05 10:26:24 -080063import android.view.Display;
Wale Ogunwale57946582020-03-21 14:29:07 -070064import android.window.ITaskOrganizer;
65import android.window.WindowContainerTransaction;
Robert Carr8a2f9132019-11-11 15:03:15 -080066
67import androidx.test.filters.SmallTest;
68
69import org.junit.Test;
70import org.junit.runner.RunWith;
71
Evan Rosky0037e5f2019-11-05 10:26:24 -080072import java.util.ArrayList;
73import java.util.List;
74
Robert Carr8a2f9132019-11-11 15:03:15 -080075/**
Wale Ogunwale57946582020-03-21 14:29:07 -070076 * Test class for {@link ITaskOrganizer} and {@link android.window.ITaskOrganizerController}.
Robert Carr8a2f9132019-11-11 15:03:15 -080077 *
78 * Build/Install/Run:
79 * atest WmTests:TaskOrganizerTests
80 */
81@SmallTest
82@Presubmit
83@RunWith(WindowTestRunner.class)
84public class TaskOrganizerTests extends WindowTestsBase {
Robert Carr00c0dbe2020-01-24 15:30:24 -080085 private ITaskOrganizer registerMockOrganizer(int windowingMode) {
Robert Carr8a2f9132019-11-11 15:03:15 -080086 final ITaskOrganizer organizer = mock(ITaskOrganizer.class);
87 when(organizer.asBinder()).thenReturn(new Binder());
88
Evan Rosky0037e5f2019-11-05 10:26:24 -080089 mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(
90 organizer, windowingMode);
Robert Carr8a2f9132019-11-11 15:03:15 -080091
92 return organizer;
93 }
94
Robert Carr00c0dbe2020-01-24 15:30:24 -080095 private ITaskOrganizer registerMockOrganizer() {
96 return registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);
97 }
98
Robert Carr8a2f9132019-11-11 15:03:15 -080099 @Test
100 public void testAppearVanish() throws RemoteException {
101 final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
102 final Task task = createTaskInStack(stack, 0 /* userId */);
Robert Carr00c0dbe2020-01-24 15:30:24 -0800103 final ITaskOrganizer organizer = registerMockOrganizer();
Robert Carr8a2f9132019-11-11 15:03:15 -0800104
105 task.setTaskOrganizer(organizer);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700106 verify(organizer).onTaskAppeared(any());
Robert Carr8a2f9132019-11-11 15:03:15 -0800107
108 task.removeImmediately();
Wale Ogunwaledec34082020-03-22 09:45:00 -0700109 verify(organizer).onTaskVanished(any());
Robert Carr8a2f9132019-11-11 15:03:15 -0800110 }
111
112 @Test
113 public void testSwapOrganizer() throws RemoteException {
114 final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
115 final Task task = createTaskInStack(stack, 0 /* userId */);
Robert Carr00c0dbe2020-01-24 15:30:24 -0800116 final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);
117 final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED);
Robert Carr8a2f9132019-11-11 15:03:15 -0800118
119 task.setTaskOrganizer(organizer);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700120 verify(organizer).onTaskAppeared(any());
Robert Carr8a2f9132019-11-11 15:03:15 -0800121 task.setTaskOrganizer(organizer2);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700122 verify(organizer).onTaskVanished(any());
123 verify(organizer2).onTaskAppeared(any());
Robert Carr8a2f9132019-11-11 15:03:15 -0800124 }
125
126 @Test
Robert Carr00c0dbe2020-01-24 15:30:24 -0800127 public void testSwapWindowingModes() throws RemoteException {
128 final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
129 final Task task = createTaskInStack(stack, 0 /* userId */);
130 final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);
131 final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED);
Rob Carrab179782020-03-10 12:50:30 -0700132
Robert Carr00c0dbe2020-01-24 15:30:24 -0800133 stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700134 verify(organizer).onTaskAppeared(any());
Robert Carr00c0dbe2020-01-24 15:30:24 -0800135 stack.setWindowingMode(WINDOWING_MODE_PINNED);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700136 verify(organizer).onTaskVanished(any());
137 verify(organizer2).onTaskAppeared(any());
Robert Carr00c0dbe2020-01-24 15:30:24 -0800138 }
139
140 @Test
Robert Carr8a2f9132019-11-11 15:03:15 -0800141 public void testClearOrganizer() throws RemoteException {
142 final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
143 final Task task = createTaskInStack(stack, 0 /* userId */);
Robert Carr00c0dbe2020-01-24 15:30:24 -0800144 final ITaskOrganizer organizer = registerMockOrganizer();
Robert Carr8a2f9132019-11-11 15:03:15 -0800145
Robert Carr9fd095b2020-01-24 14:40:06 -0800146 stack.setTaskOrganizer(organizer);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700147 verify(organizer).onTaskAppeared(any());
148 assertTrue(stack.isOrganized());
Robert Carr8a2f9132019-11-11 15:03:15 -0800149
Robert Carr9fd095b2020-01-24 14:40:06 -0800150 stack.setTaskOrganizer(null);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700151 verify(organizer).onTaskVanished(any());
152 assertFalse(stack.isOrganized());
Robert Carr8a2f9132019-11-11 15:03:15 -0800153 }
154
155 @Test
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800156 public void testUnregisterOrganizer() throws RemoteException {
157 final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
158 final Task task = createTaskInStack(stack, 0 /* userId */);
159 final ITaskOrganizer organizer = registerMockOrganizer();
160
161 stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700162 verify(organizer).onTaskAppeared(any());
163 assertTrue(stack.isOrganized());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800164
165 mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700166 verify(organizer).onTaskVanished(any());
167 assertFalse(stack.isOrganized());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800168 }
169
170 @Test
171 public void testUnregisterOrganizerReturnsRegistrationToPrevious() throws RemoteException {
172 final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
173 final Task task = createTaskInStack(stack, 0 /* userId */);
174 final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent);
175 final Task task2 = createTaskInStack(stack2, 0 /* userId */);
176 final ActivityStack stack3 = createTaskStackOnDisplay(mDisplayContent);
177 final Task task3 = createTaskInStack(stack3, 0 /* userId */);
178 final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);
179
180 // First organizer is registered, verify a task appears when changing windowing mode
181 stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700182 verify(organizer, times(1)).onTaskAppeared(any());
183 assertTrue(stack.isOrganized());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800184
185 // Now we replace the registration and1 verify the new organizer receives tasks
186 // newly entering the windowing mode.
187 final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);
188 stack2.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700189 verify(organizer2).onTaskAppeared(any());
190 assertTrue(stack2.isOrganized());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800191
192 // Now we unregister the second one, the first one should automatically be reregistered
193 // so we verify that it's now seeing changes.
194 mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer2);
195
196 stack3.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700197 verify(organizer, times(2)).onTaskAppeared(any());
198 assertTrue(stack3.isOrganized());
Robert Carr7d7c8ab2020-01-28 15:57:23 -0800199 }
200
201 @Test
Robert Carr8a2f9132019-11-11 15:03:15 -0800202 public void testRegisterTaskOrganizerStackWindowingModeChanges() throws RemoteException {
Robert Carr00c0dbe2020-01-24 15:30:24 -0800203 final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_PINNED);
Robert Carr8a2f9132019-11-11 15:03:15 -0800204
205 final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
206 final Task task = createTaskInStack(stack, 0 /* userId */);
207 final Task task2 = createTaskInStack(stack, 0 /* userId */);
208 stack.setWindowingMode(WINDOWING_MODE_PINNED);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700209 verify(organizer, times(1)).onTaskAppeared(any());
Robert Carr8a2f9132019-11-11 15:03:15 -0800210
211 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700212 verify(organizer, times(1)).onTaskVanished(any());
Robert Carr8a2f9132019-11-11 15:03:15 -0800213 }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800214
215 @Test
Winson Chung77338ab2020-03-09 16:32:34 -0700216 public void testRegisterTaskOrganizerWithExistingTasks() throws RemoteException {
217 final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
218 final Task task = createTaskInStack(stack, 0 /* userId */);
219 stack.setWindowingMode(WINDOWING_MODE_PINNED);
220
221 final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_PINNED);
Wale Ogunwaledec34082020-03-22 09:45:00 -0700222 verify(organizer, times(1)).onTaskAppeared(any());
Winson Chung77338ab2020-03-09 16:32:34 -0700223 }
224
225 @Test
Evan Rosky0037e5f2019-11-05 10:26:24 -0800226 public void testTaskTransaction() {
227 removeGlobalMinSizeRestriction();
228 final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
229 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
230 final Task task = stack.getTopMostTask();
231 WindowContainerTransaction t = new WindowContainerTransaction();
232 Rect newBounds = new Rect(10, 10, 100, 100);
233 t.setBounds(task.mRemoteToken, new Rect(10, 10, 100, 100));
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700234 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800235 assertEquals(newBounds, task.getBounds());
236 }
237
238 @Test
239 public void testStackTransaction() {
240 removeGlobalMinSizeRestriction();
241 final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
242 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
243 StackInfo info =
244 mWm.mAtmService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
245 WindowContainerTransaction t = new WindowContainerTransaction();
246 assertEquals(stack.mRemoteToken, info.stackToken);
247 Rect newBounds = new Rect(10, 10, 100, 100);
248 t.setBounds(info.stackToken, new Rect(10, 10, 100, 100));
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700249 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800250 assertEquals(newBounds, stack.getBounds());
251 }
252
253 @Test
Robert Carr2bed6212020-02-20 16:55:07 -0800254 public void testSetWindowingMode() {
255 final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
256 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
257 final WindowContainerTransaction t = new WindowContainerTransaction();
258
259 t.setWindowingMode(stack.mRemoteToken, WINDOWING_MODE_FULLSCREEN);
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700260 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Robert Carr2bed6212020-02-20 16:55:07 -0800261
262 assertEquals(WINDOWING_MODE_FULLSCREEN, stack.getWindowingMode());
263 }
264
265 @Test
266 public void testSetActivityWindowingMode() {
267 final ActivityRecord record = makePipableActivity();
268 final ActivityStack stack = record.getStack();
269 final WindowContainerTransaction t = new WindowContainerTransaction();
270
271 t.setWindowingMode(stack.mRemoteToken, WINDOWING_MODE_PINNED);
272 t.setActivityWindowingMode(stack.mRemoteToken, WINDOWING_MODE_FULLSCREEN);
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700273 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Robert Carr2bed6212020-02-20 16:55:07 -0800274
275 assertEquals(WINDOWING_MODE_FULLSCREEN, record.getWindowingMode());
276 assertEquals(WINDOWING_MODE_PINNED, stack.getWindowingMode());
277 }
278
279 @Test
Robert Carrf6878a42019-12-18 02:13:12 -0800280 public void testContainerFocusableChanges() {
Evan Rosky0037e5f2019-11-05 10:26:24 -0800281 removeGlobalMinSizeRestriction();
282 final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
283 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
284 final Task task = stack.getTopMostTask();
285 WindowContainerTransaction t = new WindowContainerTransaction();
286 assertTrue(task.isFocusable());
287 t.setFocusable(stack.mRemoteToken, false);
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700288 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800289 assertFalse(task.isFocusable());
Robert Carrf6878a42019-12-18 02:13:12 -0800290 t.setFocusable(stack.mRemoteToken, true);
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700291 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Robert Carrf6878a42019-12-18 02:13:12 -0800292 assertTrue(task.isFocusable());
293 }
294
295 @Test
296 public void testContainerHiddenChanges() {
297 removeGlobalMinSizeRestriction();
298 final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
299 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
300 WindowContainerTransaction t = new WindowContainerTransaction();
301 assertTrue(stack.shouldBeVisible(null));
302 t.setHidden(stack.mRemoteToken, true);
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700303 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Robert Carrf6878a42019-12-18 02:13:12 -0800304 assertFalse(stack.shouldBeVisible(null));
305 t.setHidden(stack.mRemoteToken, false);
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700306 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Robert Carrf6878a42019-12-18 02:13:12 -0800307 assertTrue(stack.shouldBeVisible(null));
Evan Rosky0037e5f2019-11-05 10:26:24 -0800308 }
309
310 @Test
Evan Rosky05ec8862020-02-28 19:37:04 -0800311 public void testOverrideConfigSize() {
312 removeGlobalMinSizeRestriction();
313 final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
314 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
315 final Task task = stack.getTopMostTask();
316 WindowContainerTransaction t = new WindowContainerTransaction();
317 t.setBounds(task.mRemoteToken, new Rect(10, 10, 100, 100));
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700318 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Evan Rosky05ec8862020-02-28 19:37:04 -0800319 final int origScreenWDp = task.getConfiguration().screenHeightDp;
320 final int origScreenHDp = task.getConfiguration().screenHeightDp;
321 t = new WindowContainerTransaction();
322 // verify that setting config overrides on parent restricts children.
323 t.setScreenSizeDp(stack.mRemoteToken, origScreenWDp, origScreenHDp);
324 t.setBounds(task.mRemoteToken, new Rect(10, 10, 150, 200));
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700325 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Evan Rosky05ec8862020-02-28 19:37:04 -0800326 assertEquals(origScreenHDp, task.getConfiguration().screenHeightDp);
327 t = new WindowContainerTransaction();
328 t.setScreenSizeDp(stack.mRemoteToken, Configuration.SCREEN_WIDTH_DP_UNDEFINED,
329 Configuration.SCREEN_HEIGHT_DP_UNDEFINED);
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700330 mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
Evan Rosky05ec8862020-02-28 19:37:04 -0800331 assertNotEquals(origScreenHDp, task.getConfiguration().screenHeightDp);
332 }
333
334 @Test
Evan Rosky0037e5f2019-11-05 10:26:24 -0800335 public void testCreateDeleteRootTasks() {
336 RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
337 Display.DEFAULT_DISPLAY,
338 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
339 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
340 info1.configuration.windowConfiguration.getWindowingMode());
341 assertEquals(ACTIVITY_TYPE_UNDEFINED, info1.topActivityType);
342
343 RunningTaskInfo info2 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
344 Display.DEFAULT_DISPLAY,
345 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
346 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
347 info2.configuration.windowConfiguration.getWindowingMode());
348 assertEquals(ACTIVITY_TYPE_UNDEFINED, info2.topActivityType);
349
350 DisplayContent dc = mWm.mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
Louis Changa009c762020-02-26 11:21:31 +0800351 List<Task> infos = getTasksCreatedByOrganizer(dc);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800352 assertEquals(2, infos.size());
353
354 assertTrue(mWm.mAtmService.mTaskOrganizerController.deleteRootTask(info1.token));
Louis Changa009c762020-02-26 11:21:31 +0800355 infos = getTasksCreatedByOrganizer(dc);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800356 assertEquals(1, infos.size());
357 assertEquals(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, infos.get(0).getWindowingMode());
358 }
359
360 @Test
361 public void testTileAddRemoveChild() {
Louis Changa009c762020-02-26 11:21:31 +0800362 ITaskOrganizer listener = new ITaskOrganizer.Stub() {
363 @Override
364 public void onTaskAppeared(RunningTaskInfo taskInfo) { }
365
366 @Override
367 public void onTaskVanished(RunningTaskInfo container) { }
368
369 @Override
370 public void onTaskInfoChanged(RunningTaskInfo info) throws RemoteException {
371 }
372 };
373 mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener,
374 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800375 RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
376 mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
377
378 final ActivityStack stack = createTaskStackOnDisplay(
379 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
380 assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode());
Louis Changa009c762020-02-26 11:21:31 +0800381 WindowContainerTransaction wct = new WindowContainerTransaction();
382 wct.reparent(stack.mRemoteToken, info1.token, true /* onTop */);
383 mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800384 assertEquals(info1.configuration.windowConfiguration.getWindowingMode(),
385 stack.getWindowingMode());
386
387 // Info should reflect new membership
Louis Changa009c762020-02-26 11:21:31 +0800388 List<Task> infos = getTasksCreatedByOrganizer(mDisplayContent);
389 info1 = infos.get(0).getTaskInfo();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800390 assertEquals(ACTIVITY_TYPE_STANDARD, info1.topActivityType);
391
392 // Children inherit configuration
393 Rect newSize = new Rect(10, 10, 300, 300);
Louis Changa009c762020-02-26 11:21:31 +0800394 Task task1 = WindowContainer.fromBinder(info1.token.asBinder()).asTask();
395 Configuration c = new Configuration(task1.getRequestedOverrideConfiguration());
Evan Rosky0037e5f2019-11-05 10:26:24 -0800396 c.windowConfiguration.setBounds(newSize);
Wale Ogunwale0d465192020-01-23 19:14:44 -0800397 doNothing().when(stack).adjustForMinimalTaskDimensions(any(), any());
Louis Changa009c762020-02-26 11:21:31 +0800398 task1.onRequestedOverrideConfigurationChanged(c);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800399 assertEquals(newSize, stack.getBounds());
400
Louis Changa009c762020-02-26 11:21:31 +0800401 wct = new WindowContainerTransaction();
402 wct.reparent(stack.mRemoteToken, null, true /* onTop */);
403 mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800404 assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode());
Louis Changa009c762020-02-26 11:21:31 +0800405 infos = getTasksCreatedByOrganizer(mDisplayContent);
406 info1 = infos.get(0).getTaskInfo();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800407 assertEquals(ACTIVITY_TYPE_UNDEFINED, info1.topActivityType);
408 }
409
410 @Test
411 public void testTaskInfoCallback() {
412 final ArrayList<RunningTaskInfo> lastReportedTiles = new ArrayList<>();
413 final boolean[] called = {false};
414 ITaskOrganizer listener = new ITaskOrganizer.Stub() {
415 @Override
Wale Ogunwaledec34082020-03-22 09:45:00 -0700416 public void onTaskAppeared(RunningTaskInfo taskInfo) { }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800417
418 @Override
Wale Ogunwaledec34082020-03-22 09:45:00 -0700419 public void onTaskVanished(RunningTaskInfo container) { }
Evan Rosky0037e5f2019-11-05 10:26:24 -0800420
421 @Override
Evan Rosky0037e5f2019-11-05 10:26:24 -0800422 public void onTaskInfoChanged(RunningTaskInfo info) throws RemoteException {
423 lastReportedTiles.add(info);
424 called[0] = true;
425 }
426 };
427 mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener,
428 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
429 RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
430 mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
431 lastReportedTiles.clear();
432 called[0] = false;
433
434 final ActivityStack stack = createTaskStackOnDisplay(
435 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
Louis Changa009c762020-02-26 11:21:31 +0800436 Task task1 = WindowContainer.fromBinder(info1.token.asBinder()).asTask();
437 WindowContainerTransaction wct = new WindowContainerTransaction();
438 wct.reparent(stack.mRemoteToken, info1.token, true /* onTop */);
439 mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800440 assertTrue(called[0]);
441 assertEquals(ACTIVITY_TYPE_STANDARD, lastReportedTiles.get(0).topActivityType);
442
443 lastReportedTiles.clear();
444 called[0] = false;
445 final ActivityStack stack2 = createTaskStackOnDisplay(
446 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mDisplayContent);
Louis Changa009c762020-02-26 11:21:31 +0800447 wct = new WindowContainerTransaction();
448 wct.reparent(stack2.mRemoteToken, info1.token, true /* onTop */);
449 mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800450 assertTrue(called[0]);
451 assertEquals(ACTIVITY_TYPE_HOME, lastReportedTiles.get(0).topActivityType);
452
453 lastReportedTiles.clear();
454 called[0] = false;
Louis Changa009c762020-02-26 11:21:31 +0800455 task1.positionChildAt(POSITION_TOP, stack, false /* includingParents */);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800456 assertTrue(called[0]);
457 assertEquals(ACTIVITY_TYPE_STANDARD, lastReportedTiles.get(0).topActivityType);
458
459 lastReportedTiles.clear();
460 called[0] = false;
Louis Changa009c762020-02-26 11:21:31 +0800461 wct = new WindowContainerTransaction();
462 wct.reparent(stack.mRemoteToken, null, true /* onTop */);
463 wct.reparent(stack2.mRemoteToken, null, true /* onTop */);
464 mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800465 assertTrue(called[0]);
466 assertEquals(ACTIVITY_TYPE_UNDEFINED, lastReportedTiles.get(0).topActivityType);
467 }
468
Evan Roskya8fde152020-01-07 19:09:13 -0800469 @Test
470 public void testHierarchyTransaction() {
471 final ArrayMap<IBinder, RunningTaskInfo> lastReportedTiles = new ArrayMap<>();
472 ITaskOrganizer listener = new ITaskOrganizer.Stub() {
473 @Override
Wale Ogunwaledec34082020-03-22 09:45:00 -0700474 public void onTaskAppeared(RunningTaskInfo taskInfo) { }
Evan Roskya8fde152020-01-07 19:09:13 -0800475
476 @Override
Wale Ogunwaledec34082020-03-22 09:45:00 -0700477 public void onTaskVanished(RunningTaskInfo container) { }
Evan Roskya8fde152020-01-07 19:09:13 -0800478
479 @Override
Evan Roskya8fde152020-01-07 19:09:13 -0800480 public void onTaskInfoChanged(RunningTaskInfo info) {
481 lastReportedTiles.put(info.token.asBinder(), info);
482 }
483 };
484 mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(
Louis Changa009c762020-02-26 11:21:31 +0800485 listener, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
486 mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(
Evan Roskya8fde152020-01-07 19:09:13 -0800487 listener, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
488 RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
Louis Changa009c762020-02-26 11:21:31 +0800489 mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
Evan Roskya8fde152020-01-07 19:09:13 -0800490 RunningTaskInfo info2 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
491 mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
492
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800493 final int initialRootTaskCount = mWm.mAtmService.mTaskOrganizerController.getRootTasks(
494 mDisplayContent.mDisplayId, null /* activityTypes */).size();
495
Evan Roskya8fde152020-01-07 19:09:13 -0800496 final ActivityStack stack = createTaskStackOnDisplay(
497 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
498 final ActivityStack stack2 = createTaskStackOnDisplay(
499 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mDisplayContent);
500
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800501 // Check getRootTasks works
502 List<RunningTaskInfo> roots = mWm.mAtmService.mTaskOrganizerController.getRootTasks(
503 mDisplayContent.mDisplayId, null /* activityTypes */);
504 assertEquals(initialRootTaskCount + 2, roots.size());
505
Evan Roskya8fde152020-01-07 19:09:13 -0800506 lastReportedTiles.clear();
507 WindowContainerTransaction wct = new WindowContainerTransaction();
508 wct.reparent(stack.mRemoteToken, info1.token, true /* onTop */);
509 wct.reparent(stack2.mRemoteToken, info2.token, true /* onTop */);
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700510 mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
Evan Roskya8fde152020-01-07 19:09:13 -0800511 assertFalse(lastReportedTiles.isEmpty());
512 assertEquals(ACTIVITY_TYPE_STANDARD,
513 lastReportedTiles.get(info1.token.asBinder()).topActivityType);
514 assertEquals(ACTIVITY_TYPE_HOME,
515 lastReportedTiles.get(info2.token.asBinder()).topActivityType);
516
517 lastReportedTiles.clear();
518 wct = new WindowContainerTransaction();
519 wct.reparent(stack2.mRemoteToken, info1.token, false /* onTop */);
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700520 mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
Evan Roskya8fde152020-01-07 19:09:13 -0800521 assertFalse(lastReportedTiles.isEmpty());
522 // Standard should still be on top of tile 1, so no change there
523 assertFalse(lastReportedTiles.containsKey(info1.token.asBinder()));
524 // But tile 2 has no children, so should become undefined
525 assertEquals(ACTIVITY_TYPE_UNDEFINED,
526 lastReportedTiles.get(info2.token.asBinder()).topActivityType);
527
528 // Check the getChildren call
529 List<RunningTaskInfo> children =
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800530 mWm.mAtmService.mTaskOrganizerController.getChildTasks(info1.token,
531 null /* activityTypes */);
Evan Roskya8fde152020-01-07 19:09:13 -0800532 assertEquals(2, children.size());
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800533 children = mWm.mAtmService.mTaskOrganizerController.getChildTasks(info2.token,
534 null /* activityTypes */);
Evan Roskya8fde152020-01-07 19:09:13 -0800535 assertEquals(0, children.size());
536
Evan Rosky29d4a0a2020-02-04 16:40:44 -0800537 // Check that getRootTasks doesn't include children of tiles
538 roots = mWm.mAtmService.mTaskOrganizerController.getRootTasks(mDisplayContent.mDisplayId,
539 null /* activityTypes */);
540 assertEquals(initialRootTaskCount, roots.size());
541
Evan Roskya8fde152020-01-07 19:09:13 -0800542 lastReportedTiles.clear();
543 wct = new WindowContainerTransaction();
544 wct.reorder(stack2.mRemoteToken, true /* onTop */);
Wale Ogunwale568f9f412020-03-21 22:27:35 -0700545 mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
Evan Roskya8fde152020-01-07 19:09:13 -0800546 // Home should now be on top. No change occurs in second tile, so not reported
547 assertEquals(1, lastReportedTiles.size());
548 assertEquals(ACTIVITY_TYPE_HOME,
549 lastReportedTiles.get(info1.token.asBinder()).topActivityType);
550 }
551
Louis Changa009c762020-02-26 11:21:31 +0800552 private List<Task> getTasksCreatedByOrganizer(DisplayContent dc) {
553 ArrayList<Task> out = new ArrayList<>();
Evan Rosky0037e5f2019-11-05 10:26:24 -0800554 for (int i = dc.getStackCount() - 1; i >= 0; --i) {
Louis Changa009c762020-02-26 11:21:31 +0800555 final Task t = dc.getStackAt(i);
556 if (t.mCreatedByOrganizer) out.add(t);
Evan Rosky0037e5f2019-11-05 10:26:24 -0800557 }
558 return out;
559 }
Robert Carre10ee3d2019-11-11 15:03:15 -0800560
561 @Test
562 public void testTrivialBLASTCallback() throws RemoteException {
563 final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
564 final Task task = createTaskInStack(stackController1, 0 /* userId */);
565 final ITaskOrganizer organizer = registerMockOrganizer();
566
Robert Carr8ccc4fc2020-03-13 10:48:49 -0700567 spyOn(task);
568 doReturn(true).when(task).isVisible();
569
Robert Carre10ee3d2019-11-11 15:03:15 -0800570 BLASTSyncEngine bse = new BLASTSyncEngine();
571
572 BLASTSyncEngine.TransactionReadyListener transactionListener =
573 mock(BLASTSyncEngine.TransactionReadyListener.class);
574
575 int id = bse.startSyncSet(transactionListener);
576 bse.addToSyncSet(id, task);
577 bse.setReady(id);
578 // Since this task has no windows the sync is trivial and completes immediately.
579 verify(transactionListener)
580 .transactionReady(anyInt(), any());
581 }
582
583 @Test
Robert Carr8ccc4fc2020-03-13 10:48:49 -0700584 public void testOverlappingBLASTCallback() throws RemoteException {
585 final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
586 final Task task = createTaskInStack(stackController1, 0 /* userId */);
587 final ITaskOrganizer organizer = registerMockOrganizer();
588
589 spyOn(task);
590 doReturn(true).when(task).isVisible();
591 final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");
592 makeWindowVisible(w);
593
594 BLASTSyncEngine bse = new BLASTSyncEngine();
595
596 BLASTSyncEngine.TransactionReadyListener transactionListener =
597 mock(BLASTSyncEngine.TransactionReadyListener.class);
598
599 int id = bse.startSyncSet(transactionListener);
600 assertEquals(true, bse.addToSyncSet(id, task));
601 bse.setReady(id);
602
603 int id2 = bse.startSyncSet(transactionListener);
604 // We should be rejected from the second sync since we are already
605 // in one.
606 assertEquals(false, bse.addToSyncSet(id2, task));
607 w.finishDrawing(null);
608 assertEquals(true, bse.addToSyncSet(id2, task));
609 bse.setReady(id2);
610 }
611
612 @Test
Robert Carre10ee3d2019-11-11 15:03:15 -0800613 public void testBLASTCallbackWithWindow() {
614 final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
615 final Task task = createTaskInStack(stackController1, 0 /* userId */);
616 final ITaskOrganizer organizer = registerMockOrganizer();
617 final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");
Rob Carrcba6a722020-03-10 12:41:06 -0700618 makeWindowVisible(w);
Robert Carre10ee3d2019-11-11 15:03:15 -0800619
620 BLASTSyncEngine bse = new BLASTSyncEngine();
621
622 BLASTSyncEngine.TransactionReadyListener transactionListener =
623 mock(BLASTSyncEngine.TransactionReadyListener.class);
624
625 int id = bse.startSyncSet(transactionListener);
626 bse.addToSyncSet(id, task);
627 bse.setReady(id);
628 // Since we have a window we have to wait for it to draw to finish sync.
629 verify(transactionListener, never())
630 .transactionReady(anyInt(), any());
631 w.finishDrawing(null);
632 verify(transactionListener)
633 .transactionReady(anyInt(), any());
634 }
Robert Carrf6690d12020-02-04 14:16:21 -0800635
Rob Carr25376512020-03-09 15:23:19 -0700636 @Test
Rob Carrcba6a722020-03-10 12:41:06 -0700637 public void testBLASTCallbackWithInvisibleWindow() {
638 final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
639 final Task task = createTaskInStack(stackController1, 0 /* userId */);
640 final ITaskOrganizer organizer = registerMockOrganizer();
641 final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");
642
643 BLASTSyncEngine bse = new BLASTSyncEngine();
644
645 BLASTSyncEngine.TransactionReadyListener transactionListener =
646 mock(BLASTSyncEngine.TransactionReadyListener.class);
647
648 int id = bse.startSyncSet(transactionListener);
649 bse.addToSyncSet(id, task);
650 bse.setReady(id);
651
652 // Since the window was invisible, the Task had no visible leaves and the sync should
653 // complete as soon as we call setReady.
654 verify(transactionListener)
655 .transactionReady(anyInt(), any());
656 }
657
658 @Test
Rob Carr25376512020-03-09 15:23:19 -0700659 public void testBLASTCallbackWithChildWindow() {
660 final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
661 final Task task = createTaskInStack(stackController1, 0 /* userId */);
662 final ITaskOrganizer organizer = registerMockOrganizer();
663 final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");
664 final WindowState child = createWindow(w, TYPE_APPLICATION, "Other Window");
665
666 w.mActivityRecord.setVisible(true);
667 makeWindowVisible(w, child);
668
669 BLASTSyncEngine bse = new BLASTSyncEngine();
670
671 BLASTSyncEngine.TransactionReadyListener transactionListener =
672 mock(BLASTSyncEngine.TransactionReadyListener.class);
673
674 int id = bse.startSyncSet(transactionListener);
675 assertEquals(true, bse.addToSyncSet(id, task));
676 bse.setReady(id);
677 w.finishDrawing(null);
678
679 // Since we have a child window we still shouldn't be done.
680 verify(transactionListener, never())
681 .transactionReady(anyInt(), any());
682 reset(transactionListener);
683
684 child.finishDrawing(null);
685 // Ah finally! Done
686 verify(transactionListener)
687 .transactionReady(anyInt(), any());
688 }
689
Robert Carrf6690d12020-02-04 14:16:21 -0800690 class StubOrganizer extends ITaskOrganizer.Stub {
691 RunningTaskInfo mInfo;
692
693 @Override
Wale Ogunwaledec34082020-03-22 09:45:00 -0700694 public void onTaskAppeared(RunningTaskInfo info) {
Robert Carrf6690d12020-02-04 14:16:21 -0800695 mInfo = info;
696 }
697 @Override
Wale Ogunwaledec34082020-03-22 09:45:00 -0700698 public void onTaskVanished(RunningTaskInfo info) {
Robert Carrf6690d12020-02-04 14:16:21 -0800699 }
700 @Override
Robert Carrf6690d12020-02-04 14:16:21 -0800701 public void onTaskInfoChanged(RunningTaskInfo info) {
702 }
703 };
704
705 private ActivityRecord makePipableActivity() {
706 final ActivityRecord record = createActivityRecord(mDisplayContent,
707 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
708 record.info.flags |= ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
709 spyOn(record);
710 doReturn(true).when(record).checkEnterPictureInPictureState(any(), anyBoolean());
711 return record;
712 }
713
714 @Test
715 public void testEnterPipParams() {
716 final StubOrganizer o = new StubOrganizer();
717 mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o, WINDOWING_MODE_PINNED);
718 final ActivityRecord record = makePipableActivity();
719
720 final PictureInPictureParams p =
721 new PictureInPictureParams.Builder().setAspectRatio(new Rational(1, 2)).build();
722 assertTrue(mWm.mAtmService.enterPictureInPictureMode(record.token, p));
723 waitUntilHandlersIdle();
724 assertNotNull(o.mInfo);
725 assertNotNull(o.mInfo.pictureInPictureParams);
726 }
727
728 @Test
729 public void testChangePipParams() {
730 class ChangeSavingOrganizer extends StubOrganizer {
731 RunningTaskInfo mChangedInfo;
732 @Override
733 public void onTaskInfoChanged(RunningTaskInfo info) {
734 mChangedInfo = info;
735 }
736 }
737 ChangeSavingOrganizer o = new ChangeSavingOrganizer();
738 mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o, WINDOWING_MODE_PINNED);
739
740 final ActivityRecord record = makePipableActivity();
741 final PictureInPictureParams p =
742 new PictureInPictureParams.Builder().setAspectRatio(new Rational(1, 2)).build();
743 assertTrue(mWm.mAtmService.enterPictureInPictureMode(record.token, p));
744 waitUntilHandlersIdle();
745 assertNotNull(o.mInfo);
746 assertNotNull(o.mInfo.pictureInPictureParams);
747
748 final PictureInPictureParams p2 =
749 new PictureInPictureParams.Builder().setAspectRatio(new Rational(3, 4)).build();
750 mWm.mAtmService.setPictureInPictureParams(record.token, p2);
751 waitUntilHandlersIdle();
752 assertNotNull(o.mChangedInfo);
753 assertNotNull(o.mChangedInfo.pictureInPictureParams);
754 final Rational ratio = o.mChangedInfo.pictureInPictureParams.getAspectRatioRational();
755 assertEquals(3, ratio.getNumerator());
756 assertEquals(4, ratio.getDenominator());
757 }
Robert Carr8a2f9132019-11-11 15:03:15 -0800758}