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 
17 package com.android.server.wm;
18 
19 import static android.app.AppOpsManager.OP_NONE;
20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
23 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
24 import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
25 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
26 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
27 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
28 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
29 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
30 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
31 import static android.os.Process.SYSTEM_UID;
32 import static android.view.View.VISIBLE;
33 import static android.view.ViewRootImpl.INSETS_LAYOUT_GENERALIZATION;
34 import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
35 import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
36 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
37 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
38 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
39 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
40 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
41 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
42 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
43 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
44 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
45 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
46 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
47 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
48 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
49 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
50 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
51 
52 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
53 
54 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
55 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
56 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
57 import static com.android.server.wm.StartingSurfaceController.DEBUG_ENABLE_SHELL_DRAWER;
58 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
59 import static com.android.server.wm.WindowContainer.POSITION_TOP;
60 import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
61 
62 import static org.junit.Assert.assertEquals;
63 import static org.junit.Assert.assertFalse;
64 import static org.mockito.ArgumentMatchers.any;
65 import static org.mockito.ArgumentMatchers.anyBoolean;
66 import static org.mockito.Mockito.mock;
67 
68 import android.annotation.IntDef;
69 import android.annotation.NonNull;
70 import android.annotation.Nullable;
71 import android.app.ActivityManager;
72 import android.app.ActivityOptions;
73 import android.app.IApplicationThread;
74 import android.app.WindowConfiguration;
75 import android.content.ComponentName;
76 import android.content.Context;
77 import android.content.Intent;
78 import android.content.pm.ActivityInfo;
79 import android.content.pm.ApplicationInfo;
80 import android.hardware.HardwareBuffer;
81 import android.hardware.display.DisplayManager;
82 import android.os.Build;
83 import android.os.Bundle;
84 import android.os.IBinder;
85 import android.os.RemoteException;
86 import android.os.UserHandle;
87 import android.service.voice.IVoiceInteractionSession;
88 import android.util.SparseArray;
89 import android.view.Display;
90 import android.view.DisplayInfo;
91 import android.view.Gravity;
92 import android.view.IDisplayWindowInsetsController;
93 import android.view.IWindow;
94 import android.view.InsetsSourceControl;
95 import android.view.InsetsState;
96 import android.view.Surface;
97 import android.view.SurfaceControl;
98 import android.view.SurfaceControl.Transaction;
99 import android.view.View;
100 import android.view.WindowManager;
101 import android.view.WindowManager.DisplayImePolicy;
102 import android.window.ITransitionPlayer;
103 import android.window.StartingWindowInfo;
104 import android.window.StartingWindowRemovalInfo;
105 import android.window.TaskFragmentOrganizer;
106 import android.window.TransitionInfo;
107 import android.window.TransitionRequestInfo;
108 
109 import com.android.internal.policy.AttributeCache;
110 import com.android.internal.util.ArrayUtils;
111 
112 import org.junit.After;
113 import org.junit.Before;
114 import org.junit.BeforeClass;
115 import org.junit.runner.Description;
116 import org.mockito.Mockito;
117 
118 import java.lang.annotation.ElementType;
119 import java.lang.annotation.Retention;
120 import java.lang.annotation.RetentionPolicy;
121 import java.lang.annotation.Target;
122 import java.util.HashMap;
123 
124 /** Common base class for window manager unit test classes. */
125 class WindowTestsBase extends SystemServiceTestsBase {
126     final Context mContext = getInstrumentation().getTargetContext();
127 
128     // Default package name
129     static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
130 
131     static final int DEFAULT_TASK_FRAGMENT_ORGANIZER_UID = 10000;
132     static final String DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME = "Test:TaskFragmentOrganizer";
133 
134     // Default base activity name
135     private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
136 
137     ActivityTaskManagerService mAtm;
138     RootWindowContainer mRootWindowContainer;
139     ActivityTaskSupervisor mSupervisor;
140     WindowManagerService mWm;
141     private final IWindow mIWindow = new TestIWindow();
142     private Session mMockSession;
143 
144     DisplayInfo mDisplayInfo = new DisplayInfo();
145     DisplayContent mDefaultDisplay;
146 
147     static final int STATUS_BAR_HEIGHT = 10;
148     static final int NAV_BAR_HEIGHT = 15;
149 
150     /**
151      * It is {@link #mDefaultDisplay} by default. If the test class or method is annotated with
152      * {@link UseTestDisplay}, it will be an additional display.
153      */
154     DisplayContent mDisplayContent;
155 
156     // The following fields are only available depending on the usage of annotation UseTestDisplay.
157     WindowState mWallpaperWindow;
158     WindowState mImeWindow;
159     WindowState mImeDialogWindow;
160     WindowState mStatusBarWindow;
161     WindowState mNotificationShadeWindow;
162     WindowState mDockedDividerWindow;
163     WindowState mNavBarWindow;
164     WindowState mAppWindow;
165     WindowState mChildAppWindowAbove;
166     WindowState mChildAppWindowBelow;
167 
168     /**
169      * Spied {@link Transaction} class than can be used to verify calls.
170      */
171     Transaction mTransaction;
172 
173     /**
174      * Whether device-specific global overrides have already been checked in
175      * {@link WindowTestsBase#setUpBase()}.
176      */
177     private static boolean sGlobalOverridesChecked;
178     /**
179      * Whether device-specific overrides have already been checked in
180      * {@link WindowTestsBase#setUpBase()} when the default display is used.
181      */
182     private static boolean sOverridesCheckedDefaultDisplay;
183     /**
184      * Whether device-specific overrides have already been checked in
185      * {@link WindowTestsBase#setUpBase()} when a {@link TestDisplayContent} is used.
186      */
187     private static boolean sOverridesCheckedTestDisplay;
188 
189     @BeforeClass
setUpOnceBase()190     public static void setUpOnceBase() {
191         AttributeCache.init(getInstrumentation().getTargetContext());
192     }
193 
194     @Before
setUpBase()195     public void setUpBase() {
196         mAtm = mSystemServicesTestRule.getActivityTaskManagerService();
197         mSupervisor = mAtm.mTaskSupervisor;
198         mRootWindowContainer = mAtm.mRootWindowContainer;
199         mWm = mSystemServicesTestRule.getWindowManagerService();
200         SystemServicesTestRule.checkHoldsLock(mWm.mGlobalLock);
201 
202         mDefaultDisplay = mWm.mRoot.getDefaultDisplay();
203         // Update the display policy to make the screen fully turned on so animation is allowed
204         final DisplayPolicy displayPolicy = mDefaultDisplay.getDisplayPolicy();
205         displayPolicy.screenTurnedOn(null /* screenOnListener */);
206         displayPolicy.finishKeyguardDrawn();
207         displayPolicy.finishWindowsDrawn();
208         displayPolicy.finishScreenTurningOn();
209 
210         mTransaction = mSystemServicesTestRule.mTransaction;
211         mMockSession = mock(Session.class);
212 
213         mContext.getSystemService(DisplayManager.class)
214                 .getDisplay(Display.DEFAULT_DISPLAY).getDisplayInfo(mDisplayInfo);
215 
216         // Only create an additional test display for annotated test class/method because it may
217         // significantly increase the execution time.
218         final Description description = mSystemServicesTestRule.getDescription();
219         UseTestDisplay testDisplayAnnotation = description.getAnnotation(UseTestDisplay.class);
220         if (testDisplayAnnotation == null) {
221             testDisplayAnnotation = description.getTestClass().getAnnotation(UseTestDisplay.class);
222         }
223         if (testDisplayAnnotation != null) {
224             createTestDisplay(testDisplayAnnotation);
225         } else {
226             mDisplayContent = mDefaultDisplay;
227         }
228 
229         // Ensure letterbox aspect ratio is not overridden on any device target.
230         // {@link com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}, is set
231         // on some device form factors.
232         mAtm.mWindowManager.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(0);
233         // Ensure letterbox position multiplier is not overridden on any device target.
234         // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier},
235         // may be set on some device form factors.
236         mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f);
237         // Ensure letterbox reachability treatment isn't overridden on any device target.
238         // {@link com.android.internal.R.bool.config_letterboxIsReachabilityEnabled},
239         // may be set on some device form factors.
240         mAtm.mWindowManager.mLetterboxConfiguration.setIsReachabilityEnabled(false);
241 
242         checkDeviceSpecificOverridesNotApplied();
243     }
244 
245     @After
tearDown()246     public void tearDown() throws Exception {
247         // Revert back to device overrides.
248         mAtm.mWindowManager.mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
249         mAtm.mWindowManager.mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
250         mAtm.mWindowManager.mLetterboxConfiguration.resetIsReachabilityEnabled();
251     }
252 
253     /**
254      * Check that device-specific overrides are not applied. Only need to check once during entire
255      * test run for each case: global overrides, default display, and test display.
256      */
checkDeviceSpecificOverridesNotApplied()257     private void checkDeviceSpecificOverridesNotApplied() {
258         // Check global overrides
259         if (!sGlobalOverridesChecked) {
260             assertEquals(0, mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(),
261                     0 /* delta */);
262             sGlobalOverridesChecked = true;
263         }
264         // Check display-specific overrides
265         if (!sOverridesCheckedDefaultDisplay && mDisplayContent == mDefaultDisplay) {
266             assertFalse(mDisplayContent.getIgnoreOrientationRequest());
267             sOverridesCheckedDefaultDisplay = true;
268         } else if (!sOverridesCheckedTestDisplay && mDisplayContent instanceof TestDisplayContent) {
269             assertFalse(mDisplayContent.getIgnoreOrientationRequest());
270             sOverridesCheckedTestDisplay = true;
271         }
272     }
273 
createTestDisplay(UseTestDisplay annotation)274     private void createTestDisplay(UseTestDisplay annotation) {
275         beforeCreateTestDisplay();
276         mDisplayContent = createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL);
277 
278         final boolean addAll = annotation.addAllCommonWindows();
279         final @CommonTypes int[] requestedWindows = annotation.addWindows();
280 
281         if (addAll || ArrayUtils.contains(requestedWindows, W_WALLPAPER)) {
282             mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
283         }
284         if (addAll || ArrayUtils.contains(requestedWindows, W_INPUT_METHOD)) {
285             mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow");
286             mDisplayContent.mInputMethodWindow = mImeWindow;
287         }
288         if (addAll || ArrayUtils.contains(requestedWindows, W_INPUT_METHOD_DIALOG)) {
289             mImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG,
290                     "mImeDialogWindow");
291         }
292         if (addAll || ArrayUtils.contains(requestedWindows, W_STATUS_BAR)) {
293             mStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "mStatusBarWindow");
294             if (INSETS_LAYOUT_GENERALIZATION) {
295                 mStatusBarWindow.mAttrs.height = STATUS_BAR_HEIGHT;
296                 mStatusBarWindow.mAttrs.gravity = Gravity.TOP;
297                 mStatusBarWindow.mAttrs.layoutInDisplayCutoutMode =
298                         LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
299                 mStatusBarWindow.setRequestedSize(WindowManager.LayoutParams.MATCH_PARENT,
300                         STATUS_BAR_HEIGHT);
301             }
302         }
303         if (addAll || ArrayUtils.contains(requestedWindows, W_NOTIFICATION_SHADE)) {
304             mNotificationShadeWindow = createCommonWindow(null, TYPE_NOTIFICATION_SHADE,
305                     "mNotificationShadeWindow");
306         }
307         if (addAll || ArrayUtils.contains(requestedWindows, W_NAVIGATION_BAR)) {
308             mNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "mNavBarWindow");
309             if (INSETS_LAYOUT_GENERALIZATION) {
310                 mNavBarWindow.mAttrs.height = NAV_BAR_HEIGHT;
311                 mNavBarWindow.mAttrs.gravity = Gravity.BOTTOM;
312                 mNavBarWindow.mAttrs.paramsForRotation = new WindowManager.LayoutParams[4];
313                 for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) {
314                     mNavBarWindow.mAttrs.paramsForRotation[rot] =
315                             getNavBarLayoutParamsForRotation(rot);
316                 }
317             }
318         }
319         if (addAll || ArrayUtils.contains(requestedWindows, W_DOCK_DIVIDER)) {
320             mDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER,
321                     "mDockedDividerWindow");
322         }
323         final boolean addAboveApp = ArrayUtils.contains(requestedWindows, W_ABOVE_ACTIVITY);
324         final boolean addBelowApp = ArrayUtils.contains(requestedWindows, W_BELOW_ACTIVITY);
325         if (addAll || addAboveApp || addBelowApp
326                 || ArrayUtils.contains(requestedWindows, W_ACTIVITY)) {
327             mAppWindow = createCommonWindow(null, TYPE_BASE_APPLICATION, "mAppWindow");
328         }
329         if (addAll || addAboveApp) {
330             mChildAppWindowAbove = createCommonWindow(mAppWindow, TYPE_APPLICATION_ATTACHED_DIALOG,
331                     "mChildAppWindowAbove");
332         }
333         if (addAll || addBelowApp) {
334             mChildAppWindowBelow = createCommonWindow(mAppWindow, TYPE_APPLICATION_MEDIA_OVERLAY,
335                     "mChildAppWindowBelow");
336         }
337 
338         mDisplayContent.getInsetsPolicy().setRemoteInsetsControllerControlsSystemBars(false);
339 
340         // Adding a display will cause freezing the display. Make sure to wait until it's
341         // unfrozen to not run into race conditions with the tests.
342         waitUntilHandlersIdle();
343     }
344 
getNavBarLayoutParamsForRotation(int rotation)345     private WindowManager.LayoutParams getNavBarLayoutParamsForRotation(int rotation) {
346         int width = WindowManager.LayoutParams.MATCH_PARENT;
347         int height = WindowManager.LayoutParams.MATCH_PARENT;
348         int gravity = Gravity.BOTTOM;
349         if (INSETS_LAYOUT_GENERALIZATION) {
350             switch (rotation) {
351                 case ROTATION_UNDEFINED:
352                 case Surface.ROTATION_0:
353                 case Surface.ROTATION_180:
354                     height = NAV_BAR_HEIGHT;
355                     break;
356                 case Surface.ROTATION_90:
357                     gravity = Gravity.RIGHT;
358                     width = NAV_BAR_HEIGHT;
359                     break;
360                 case Surface.ROTATION_270:
361                     gravity = Gravity.LEFT;
362                     width = NAV_BAR_HEIGHT;
363                     break;
364             }
365         }
366         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
367                 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR);
368         lp.width = width;
369         lp.height = height;
370         if (INSETS_LAYOUT_GENERALIZATION) {
371             lp.gravity = gravity;
372         }
373         return lp;
374     }
375 
beforeCreateTestDisplay()376     void beforeCreateTestDisplay() {
377         // Called before display is created.
378     }
379 
createCommonWindow(WindowState parent, int type, String name)380     private WindowState createCommonWindow(WindowState parent, int type, String name) {
381         final WindowState win = createWindow(parent, type, name);
382         // Prevent common windows from been IME targets.
383         win.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
384         return win;
385     }
386 
createWindowToken( DisplayContent dc, int windowingMode, int activityType, int type)387     private WindowToken createWindowToken(
388             DisplayContent dc, int windowingMode, int activityType, int type) {
389         if (type == TYPE_WALLPAPER) {
390             return createWallpaperToken(dc);
391         }
392         if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
393             return createTestWindowToken(type, dc);
394         }
395 
396         return createActivityRecord(dc, windowingMode, activityType);
397     }
398 
createWallpaperToken(DisplayContent dc)399     private WindowToken createWallpaperToken(DisplayContent dc) {
400         return new WallpaperWindowToken(mWm, mock(IBinder.class), true /* explicit */, dc,
401                 true /* ownerCanManageAppTokens */);
402     }
403 
createAppWindow(Task task, int type, String name)404     WindowState createAppWindow(Task task, int type, String name) {
405         final ActivityRecord activity = createNonAttachedActivityRecord(task.getDisplayContent());
406         task.addChild(activity, 0);
407         return createWindow(null, type, activity, name);
408     }
409 
410     // TODO: Move these calls to a builder?
createWindow(WindowState parent, int type, DisplayContent dc, String name, IWindow iwindow)411     WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
412             IWindow iwindow) {
413         final WindowToken token = createWindowToken(
414                 dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
415         return createWindow(parent, type, token, name, 0 /* ownerId */,
416                 false /* ownerCanAddInternalSystemWindow */, iwindow);
417     }
418 
createWindow(WindowState parent, int type, String name)419     WindowState createWindow(WindowState parent, int type, String name) {
420         return (parent == null)
421                 ? createWindow(parent, type, mDisplayContent, name)
422                 : createWindow(parent, type, parent.mToken, name);
423     }
424 
createWindow(WindowState parent, int type, String name, int ownerId)425     WindowState createWindow(WindowState parent, int type, String name, int ownerId) {
426         return (parent == null)
427                 ? createWindow(parent, type, mDisplayContent, name, ownerId)
428                 : createWindow(parent, type, parent.mToken, name, ownerId);
429     }
430 
createWindow(WindowState parent, int windowingMode, int activityType, int type, DisplayContent dc, String name)431     WindowState createWindow(WindowState parent, int windowingMode, int activityType,
432             int type, DisplayContent dc, String name) {
433         final WindowToken token = createWindowToken(dc, windowingMode, activityType, type);
434         return createWindow(parent, type, token, name);
435     }
436 
createWindow(WindowState parent, int type, DisplayContent dc, String name)437     WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
438         return createWindow(
439                 parent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type, dc, name);
440     }
441 
createWindow(WindowState parent, int type, DisplayContent dc, String name, int ownerId)442     WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
443             int ownerId) {
444         final WindowToken token = createWindowToken(
445                 dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
446         return createWindow(parent, type, token, name, ownerId);
447     }
448 
createWindow(WindowState parent, int type, DisplayContent dc, String name, boolean ownerCanAddInternalSystemWindow)449     WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
450             boolean ownerCanAddInternalSystemWindow) {
451         final WindowToken token = createWindowToken(
452                 dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
453         return createWindow(parent, type, token, name, 0 /* ownerId */,
454                 ownerCanAddInternalSystemWindow);
455     }
456 
createWindow(WindowState parent, int type, WindowToken token, String name)457     WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
458         return createWindow(parent, type, token, name, 0 /* ownerId */,
459                 false /* ownerCanAddInternalSystemWindow */);
460     }
461 
createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId)462     WindowState createWindow(WindowState parent, int type, WindowToken token, String name,
463             int ownerId) {
464         return createWindow(parent, type, token, name, ownerId,
465                 false /* ownerCanAddInternalSystemWindow */);
466     }
467 
createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId, boolean ownerCanAddInternalSystemWindow)468     WindowState createWindow(WindowState parent, int type, WindowToken token, String name,
469             int ownerId, boolean ownerCanAddInternalSystemWindow) {
470         return createWindow(parent, type, token, name, ownerId, ownerCanAddInternalSystemWindow,
471                 mIWindow);
472     }
473 
createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId, boolean ownerCanAddInternalSystemWindow, IWindow iwindow)474     WindowState createWindow(WindowState parent, int type, WindowToken token, String name,
475             int ownerId, boolean ownerCanAddInternalSystemWindow, IWindow iwindow) {
476         return createWindow(parent, type, token, name, ownerId, UserHandle.getUserId(ownerId),
477                 ownerCanAddInternalSystemWindow, mWm, mMockSession, iwindow,
478                 mSystemServicesTestRule.getPowerManagerWrapper());
479     }
480 
createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId, int userId, boolean ownerCanAddInternalSystemWindow, WindowManagerService service, Session session, IWindow iWindow, WindowState.PowerManagerWrapper powerManagerWrapper)481     static WindowState createWindow(WindowState parent, int type, WindowToken token,
482             String name, int ownerId, int userId, boolean ownerCanAddInternalSystemWindow,
483             WindowManagerService service, Session session, IWindow iWindow,
484             WindowState.PowerManagerWrapper powerManagerWrapper) {
485         SystemServicesTestRule.checkHoldsLock(service.mGlobalLock);
486 
487         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
488         attrs.setTitle(name);
489         attrs.packageName = "test";
490 
491         final WindowState w = new WindowState(service, session, iWindow, token, parent,
492                 OP_NONE, attrs, VISIBLE, ownerId, userId,
493                 ownerCanAddInternalSystemWindow,
494                 powerManagerWrapper);
495         // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
496         // adding it to the token...
497         token.addWindow(w);
498         return w;
499     }
500 
makeWindowVisible(WindowState... windows)501     static void makeWindowVisible(WindowState... windows) {
502         for (WindowState win : windows) {
503             win.mViewVisibility = View.VISIBLE;
504             win.mRelayoutCalled = true;
505             win.mHasSurface = true;
506             win.mHidden = false;
507             win.show(false /* doAnimation */, false /* requestAnim */);
508         }
509     }
510 
makeWindowVisibleAndDrawn(WindowState... windows)511     static void makeWindowVisibleAndDrawn(WindowState... windows) {
512         makeWindowVisible(windows);
513         for (WindowState win : windows) {
514             win.mWinAnimator.mDrawState = HAS_DRAWN;
515         }
516     }
517 
518     /**
519      * Gets the order of the given {@link Task} as its z-order in the hierarchy below this TDA.
520      * The Task can be a direct child of a child TaskDisplayArea. {@code -1} if not found.
521      */
getTaskIndexOf(TaskDisplayArea taskDisplayArea, Task task)522     static int getTaskIndexOf(TaskDisplayArea taskDisplayArea, Task task) {
523         int index = 0;
524         final int childCount = taskDisplayArea.getChildCount();
525         for (int i = 0; i < childCount; i++) {
526             final WindowContainer wc = taskDisplayArea.getChildAt(i);
527             if (wc.asTask() != null) {
528                 if (wc.asTask() == task) {
529                     return index;
530                 }
531                 index++;
532             } else {
533                 final TaskDisplayArea tda = wc.asTaskDisplayArea();
534                 final int subIndex = getTaskIndexOf(tda, task);
535                 if (subIndex > -1) {
536                     return index + subIndex;
537                 } else {
538                     index += tda.getRootTaskCount();
539                 }
540             }
541         }
542         return -1;
543     }
544 
545     /** Creates a {@link TaskDisplayArea} right above the default one. */
createTaskDisplayArea(DisplayContent displayContent, WindowManagerService service, String name, int displayAreaFeature)546     static TaskDisplayArea createTaskDisplayArea(DisplayContent displayContent,
547             WindowManagerService service, String name, int displayAreaFeature) {
548         final TaskDisplayArea newTaskDisplayArea = new TaskDisplayArea(
549                 displayContent, service, name, displayAreaFeature);
550         final TaskDisplayArea defaultTaskDisplayArea = displayContent.getDefaultTaskDisplayArea();
551 
552         // Insert the new TDA to the correct position.
553         defaultTaskDisplayArea.getParent().addChild(newTaskDisplayArea,
554                 defaultTaskDisplayArea.getParent().mChildren.indexOf(defaultTaskDisplayArea)
555                         + 1);
556         return newTaskDisplayArea;
557     }
558 
559     /**
560      *  Creates a {@link Task} with a simple {@link ActivityRecord} and adds to the given
561      *  {@link TaskDisplayArea}.
562      */
createTaskWithActivity(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop, boolean twoLevelTask)563     Task createTaskWithActivity(TaskDisplayArea taskDisplayArea,
564             int windowingMode, int activityType, boolean onTop, boolean twoLevelTask) {
565         return createTask(taskDisplayArea, windowingMode, activityType,
566                 onTop, true /* createActivity */, twoLevelTask);
567     }
568 
569     /** Creates a {@link Task} and adds to the given {@link DisplayContent}. */
createTask(DisplayContent dc)570     Task createTask(DisplayContent dc) {
571         return createTask(dc.getDefaultTaskDisplayArea(),
572                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
573     }
574 
createTask(DisplayContent dc, int windowingMode, int activityType)575     Task createTask(DisplayContent dc, int windowingMode, int activityType) {
576         return createTask(dc.getDefaultTaskDisplayArea(), windowingMode, activityType);
577     }
578 
createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType)579     Task createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType) {
580         return createTask(taskDisplayArea, windowingMode, activityType,
581                 true /* onTop */, false /* createActivity */, false /* twoLevelTask */);
582     }
583 
584     /** Creates a {@link Task} and adds to the given {@link TaskDisplayArea}. */
createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop, boolean createActivity, boolean twoLevelTask)585     Task createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType,
586             boolean onTop, boolean createActivity, boolean twoLevelTask) {
587         final TaskBuilder builder = new TaskBuilder(mSupervisor)
588                 .setTaskDisplayArea(taskDisplayArea)
589                 .setWindowingMode(windowingMode)
590                 .setActivityType(activityType)
591                 .setOnTop(onTop)
592                 .setCreateActivity(createActivity);
593         if (twoLevelTask) {
594             return builder
595                     .setCreateParentTask(true)
596                     .build()
597                     .getRootTask();
598         } else {
599             return builder.build();
600         }
601     }
602 
603     /** Creates a {@link Task} and adds to the given root {@link Task}. */
createTaskInRootTask(Task rootTask, int userId)604     Task createTaskInRootTask(Task rootTask, int userId) {
605         final Task task = new TaskBuilder(rootTask.mTaskSupervisor)
606                 .setUserId(userId)
607                 .setParentTaskFragment(rootTask)
608                 .build();
609         return task;
610     }
611 
612     /** Creates an {@link ActivityRecord}. */
createNonAttachedActivityRecord(DisplayContent dc)613     static ActivityRecord createNonAttachedActivityRecord(DisplayContent dc) {
614         final ActivityRecord activity = new ActivityBuilder(dc.mWmService.mAtmService)
615                 .setOnTop(true)
616                 .build();
617         postCreateActivitySetup(activity, dc);
618         return activity;
619     }
620 
621     /**
622      * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
623      * [Task] - [ActivityRecord]
624      */
createActivityRecord(DisplayContent dc)625     ActivityRecord createActivityRecord(DisplayContent dc) {
626         return createActivityRecord(dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
627     }
628 
629     /**
630      * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
631      * [Task] - [ActivityRecord]
632      */
createActivityRecord(DisplayContent dc, int windowingMode, int activityType)633     ActivityRecord createActivityRecord(DisplayContent dc, int windowingMode,
634             int activityType) {
635         final Task task = createTask(dc, windowingMode, activityType);
636         return createActivityRecord(dc, task);
637     }
638 
639     /**
640      *  Creates an {@link ActivityRecord} and adds it to the specified {@link Task}.
641      * [Task] - [ActivityRecord]
642      */
createActivityRecord(Task task)643     static ActivityRecord createActivityRecord(Task task) {
644         return createActivityRecord(task.getDisplayContent(), task);
645     }
646 
647     /**
648      * Creates an {@link ActivityRecord} and adds it to the specified {@link Task}.
649      * [Task] - [ActivityRecord]
650      */
createActivityRecord(DisplayContent dc, Task task)651     static ActivityRecord createActivityRecord(DisplayContent dc, Task task) {
652         final ActivityRecord activity = new ActivityBuilder(dc.mWmService.mAtmService)
653                 .setTask(task)
654                 .setOnTop(true)
655                 .build();
656         postCreateActivitySetup(activity, dc);
657         return activity;
658     }
659 
660     /**
661      * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
662      * Then adds the new created {@link Task} to a new created parent {@link Task}
663      * [Task1] - [Task2] - [ActivityRecord]
664      */
createActivityRecordWithParentTask(DisplayContent dc, int windowingMode, int activityType)665     ActivityRecord createActivityRecordWithParentTask(DisplayContent dc, int windowingMode,
666             int activityType) {
667         final Task task = createTask(dc, windowingMode, activityType);
668         return createActivityRecordWithParentTask(task);
669     }
670 
671     /**
672      * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
673      * Then adds the new created {@link Task} to the specified parent {@link Task}
674      * [Task1] - [Task2] - [ActivityRecord]
675      */
createActivityRecordWithParentTask(Task parentTask)676     static ActivityRecord createActivityRecordWithParentTask(Task parentTask) {
677         final ActivityRecord activity = new ActivityBuilder(parentTask.mAtmService)
678                 .setParentTask(parentTask)
679                 .setCreateTask(true)
680                 .setOnTop(true)
681                 .build();
682         postCreateActivitySetup(activity, parentTask.getDisplayContent());
683         return activity;
684     }
685 
postCreateActivitySetup(ActivityRecord activity, DisplayContent dc)686     private static void postCreateActivitySetup(ActivityRecord activity, DisplayContent dc) {
687         activity.onDisplayChanged(dc);
688         activity.setOccludesParent(true);
689         activity.setVisible(true);
690         activity.mVisibleRequested = true;
691     }
692 
693     /**
694      * Creates a {@link TaskFragment} and attach it to the {@code parentTask}.
695      *
696      * @param parentTask the {@link Task} this TaskFragment is going to be attached
697      * @param createEmbeddedTask Sets to {@code true} to create an embedded Task for this
698      *                           TaskFragment. Otherwise, create a {@link ActivityRecord}.
699      * @return the created TaskFragment
700      */
createTaskFragmentWithParentTask(@onNull Task parentTask, boolean createEmbeddedTask)701     static TaskFragment createTaskFragmentWithParentTask(@NonNull Task parentTask,
702             boolean createEmbeddedTask) {
703         final TaskFragmentBuilder builder = new TaskFragmentBuilder(parentTask.mAtmService)
704                 .setParentTask(parentTask);
705         if (createEmbeddedTask) {
706             builder.createEmbeddedTask();
707         } else {
708             builder.createActivityCount(1);
709         }
710         return builder.build();
711     }
712 
createTaskFragmentWithEmbeddedActivity(@onNull Task parentTask, TaskFragmentOrganizer organizer)713     static TaskFragment createTaskFragmentWithEmbeddedActivity(@NonNull Task parentTask,
714             TaskFragmentOrganizer organizer) {
715         return new TaskFragmentBuilder(parentTask.mAtmService)
716                 .setParentTask(parentTask)
717                 .createActivityCount(1)
718                 .setOrganizer(organizer)
719                 .build();
720     }
721 
722     /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
createNewDisplay()723     DisplayContent createNewDisplay() {
724         return createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL);
725     }
726 
727     /** Creates a {@link DisplayContent} and adds it to the system. */
createNewDisplayWithImeSupport(@isplayImePolicy int imePolicy)728     private DisplayContent createNewDisplayWithImeSupport(@DisplayImePolicy int imePolicy) {
729         return createNewDisplay(mDisplayInfo, imePolicy);
730     }
731 
732     /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
createNewDisplay(DisplayInfo info)733     DisplayContent createNewDisplay(DisplayInfo info) {
734         return createNewDisplay(info, DISPLAY_IME_POLICY_LOCAL);
735     }
736 
737     /** Creates a {@link DisplayContent} and adds it to the system. */
createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy)738     private DisplayContent createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy) {
739         final DisplayContent display =
740                 new TestDisplayContent.Builder(mAtm, info).build();
741         final DisplayContent dc = display.mDisplayContent;
742         // this display can show IME.
743         dc.mWmService.mDisplayWindowSettings.setDisplayImePolicy(dc, imePolicy);
744         return dc;
745     }
746 
747     /**
748      * Creates a {@link DisplayContent} with given display state and adds it to the system.
749      *
750      * @param displayState For initializing the state of the display. See
751      *                     {@link Display#getState()}.
752      */
createNewDisplay(int displayState)753     DisplayContent createNewDisplay(int displayState) {
754         // Leverage main display info & initialize it with display state for given displayId.
755         DisplayInfo displayInfo = new DisplayInfo();
756         displayInfo.copyFrom(mDisplayInfo);
757         displayInfo.state = displayState;
758         return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_LOCAL);
759     }
760 
761     /** Creates a {@link TestWindowState} */
createWindowState(WindowManager.LayoutParams attrs, WindowToken token)762     TestWindowState createWindowState(WindowManager.LayoutParams attrs, WindowToken token) {
763         SystemServicesTestRule.checkHoldsLock(mWm.mGlobalLock);
764 
765         return new TestWindowState(mWm, mMockSession, mIWindow, attrs, token);
766     }
767 
768     /** Creates a {@link DisplayContent} as parts of simulate display info for test. */
createMockSimulatedDisplay()769     DisplayContent createMockSimulatedDisplay() {
770         DisplayInfo displayInfo = new DisplayInfo();
771         displayInfo.copyFrom(mDisplayInfo);
772         displayInfo.type = Display.TYPE_VIRTUAL;
773         displayInfo.ownerUid = SYSTEM_UID;
774         return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_FALLBACK_DISPLAY);
775     }
776 
createDisplayWindowInsetsController()777     IDisplayWindowInsetsController createDisplayWindowInsetsController() {
778         return new IDisplayWindowInsetsController.Stub() {
779 
780             @Override
781             public void insetsChanged(InsetsState insetsState) throws RemoteException {
782             }
783 
784             @Override
785             public void insetsControlChanged(InsetsState insetsState,
786                     InsetsSourceControl[] insetsSourceControls) throws RemoteException {
787             }
788 
789             @Override
790             public void showInsets(int i, boolean b) throws RemoteException {
791             }
792 
793             @Override
794             public void hideInsets(int i, boolean b) throws RemoteException {
795             }
796 
797             @Override
798             public void topFocusedWindowChanged(String packageName) {
799             }
800         };
801     }
802 
createTestBLASTSyncEngine()803     BLASTSyncEngine createTestBLASTSyncEngine() {
804         return new BLASTSyncEngine(mWm) {
805             @Override
806             void scheduleTimeout(SyncGroup s, long timeoutMs) {
807                 // Disable timeout.
808             }
809         };
810     }
811 
812     /** Sets up a simple implementation of transition player for shell transitions. */
registerTestTransitionPlayer()813     TestTransitionPlayer registerTestTransitionPlayer() {
814         final TestTransitionPlayer testPlayer = new TestTransitionPlayer(
815                 mAtm.getTransitionController(), mAtm.mWindowOrganizerController);
816         testPlayer.mController.registerTransitionPlayer(testPlayer, null /* appThread */);
817         return testPlayer;
818     }
819 
820     /**
821      * Avoids rotating screen disturbed by some conditions. It is usually used for the default
822      * display that is not the instance of {@link TestDisplayContent} (it bypasses the conditions).
823      *
824      * @see DisplayRotation#updateRotationUnchecked
825      */
unblockDisplayRotation(DisplayContent dc)826     void unblockDisplayRotation(DisplayContent dc) {
827         mWm.stopFreezingDisplayLocked();
828         // The rotation animation won't actually play, it needs to be cleared manually.
829         dc.setRotationAnimation(null);
830     }
831 
832     // The window definition for UseTestDisplay#addWindows. The test can declare to add only
833     // necessary windows, that avoids adding unnecessary overhead of unused windows.
834     static final int W_NOTIFICATION_SHADE = TYPE_NOTIFICATION_SHADE;
835     static final int W_STATUS_BAR = TYPE_STATUS_BAR;
836     static final int W_NAVIGATION_BAR = TYPE_NAVIGATION_BAR;
837     static final int W_INPUT_METHOD_DIALOG = TYPE_INPUT_METHOD_DIALOG;
838     static final int W_INPUT_METHOD = TYPE_INPUT_METHOD;
839     static final int W_DOCK_DIVIDER = TYPE_DOCK_DIVIDER;
840     static final int W_ABOVE_ACTIVITY = TYPE_APPLICATION_ATTACHED_DIALOG;
841     static final int W_ACTIVITY = TYPE_BASE_APPLICATION;
842     static final int W_BELOW_ACTIVITY = TYPE_APPLICATION_MEDIA_OVERLAY;
843     static final int W_WALLPAPER = TYPE_WALLPAPER;
844 
845     /** The common window types supported by {@link UseTestDisplay}. */
846     @Retention(RetentionPolicy.RUNTIME)
847     @IntDef(value = {
848             W_NOTIFICATION_SHADE,
849             W_STATUS_BAR,
850             W_NAVIGATION_BAR,
851             W_INPUT_METHOD_DIALOG,
852             W_INPUT_METHOD,
853             W_DOCK_DIVIDER,
854             W_ABOVE_ACTIVITY,
855             W_ACTIVITY,
856             W_BELOW_ACTIVITY,
857             W_WALLPAPER,
858     })
859     @interface CommonTypes {
860     }
861 
862     /**
863      * The annotation for class and method (higher priority) to create a non-default display that
864      * will be assigned to {@link #mDisplayContent}. It is used if the test needs
865      * <ul>
866      * <li>Pure empty display.</li>
867      * <li>Configured common windows.</li>
868      * <li>Independent and customizable orientation.</li>
869      * <li>Cross display operation.</li>
870      * </ul>
871      *
872      * @see TestDisplayContent
873      * @see #createTestDisplay
874      **/
875     @Target({ ElementType.METHOD, ElementType.TYPE })
876     @Retention(RetentionPolicy.RUNTIME)
877     @interface UseTestDisplay {
addAllCommonWindows()878         boolean addAllCommonWindows() default false;
addWindows()879         @CommonTypes int[] addWindows() default {};
880     }
881 
882     /** Creates and adds a {@link TestDisplayContent} to supervisor at the given position. */
addNewDisplayContentAt(int position)883     TestDisplayContent addNewDisplayContentAt(int position) {
884         return new TestDisplayContent.Builder(mAtm, 1000, 1500).setPosition(position).build();
885     }
886 
887     /** Sets the default minimum task size to 1 so that tests can use small task sizes */
removeGlobalMinSizeRestriction()888     public void removeGlobalMinSizeRestriction() {
889         mAtm.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
890     }
891 
892     /** Mocks the behavior of taking a snapshot. */
mockSurfaceFreezerSnapshot(SurfaceFreezer surfaceFreezer)893     void mockSurfaceFreezerSnapshot(SurfaceFreezer surfaceFreezer) {
894         final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
895                 mock(SurfaceControl.ScreenshotHardwareBuffer.class);
896         final HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class);
897         spyOn(surfaceFreezer);
898         doReturn(screenshotBuffer).when(surfaceFreezer)
899                 .createSnapshotBufferInner(any(), any());
900         doReturn(null).when(surfaceFreezer)
901                 .createFromHardwareBufferInner(any());
902         doReturn(hardwareBuffer).when(screenshotBuffer).getHardwareBuffer();
903         doReturn(100).when(hardwareBuffer).getWidth();
904         doReturn(100).when(hardwareBuffer).getHeight();
905     }
906 
907     /**
908      * Builder for creating new activities.
909      */
910     protected static class ActivityBuilder {
911         static final int DEFAULT_FAKE_UID = 12345;
912         // An id appended to the end of the component name to make it unique
913         private static int sCurrentActivityId = 0;
914 
915         private final ActivityTaskManagerService mService;
916 
917         private ComponentName mComponent;
918         private String mTargetActivity;
919         private Task mTask;
920         private String mProcessName = "name";
921         private String mAffinity;
922         private int mUid = DEFAULT_FAKE_UID;
923         private boolean mCreateTask = false;
924         private Task mParentTask;
925         private int mActivityFlags;
926         private int mLaunchMode;
927         private int mResizeMode = RESIZE_MODE_RESIZEABLE;
928         private float mMaxAspectRatio;
929         private float mMinAspectRatio;
930         private boolean mSupportsSizeChanges;
931         private int mScreenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
932         private boolean mLaunchTaskBehind = false;
933         private int mConfigChanges;
934         private int mLaunchedFromPid;
935         private int mLaunchedFromUid;
936         private String mLaunchedFromPackage;
937         private WindowProcessController mWpc;
938         private Bundle mIntentExtras;
939         private boolean mOnTop = false;
940         private ActivityInfo.WindowLayout mWindowLayout;
941         private boolean mVisible = true;
942 
ActivityBuilder(ActivityTaskManagerService service)943         ActivityBuilder(ActivityTaskManagerService service) {
944             mService = service;
945         }
946 
setComponent(ComponentName component)947         ActivityBuilder setComponent(ComponentName component) {
948             mComponent = component;
949             return this;
950         }
951 
setTargetActivity(String targetActivity)952         ActivityBuilder setTargetActivity(String targetActivity) {
953             mTargetActivity = targetActivity;
954             return this;
955         }
956 
setIntentExtras(Bundle extras)957         ActivityBuilder setIntentExtras(Bundle extras) {
958             mIntentExtras = extras;
959             return this;
960         }
961 
getDefaultComponent()962         static ComponentName getDefaultComponent() {
963             return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
964                     DEFAULT_COMPONENT_PACKAGE_NAME);
965         }
966 
setTask(Task task)967         ActivityBuilder setTask(Task task) {
968             mTask = task;
969             return this;
970         }
971 
setActivityFlags(int flags)972         ActivityBuilder setActivityFlags(int flags) {
973             mActivityFlags = flags;
974             return this;
975         }
976 
setLaunchMode(int launchMode)977         ActivityBuilder setLaunchMode(int launchMode) {
978             mLaunchMode = launchMode;
979             return this;
980         }
981 
setParentTask(Task parentTask)982         ActivityBuilder setParentTask(Task parentTask) {
983             mParentTask = parentTask;
984             return this;
985         }
986 
setCreateTask(boolean createTask)987         ActivityBuilder setCreateTask(boolean createTask) {
988             mCreateTask = createTask;
989             return this;
990         }
991 
setProcessName(String name)992         ActivityBuilder setProcessName(String name) {
993             mProcessName = name;
994             return this;
995         }
996 
setUid(int uid)997         ActivityBuilder setUid(int uid) {
998             mUid = uid;
999             return this;
1000         }
1001 
setResizeMode(int resizeMode)1002         ActivityBuilder setResizeMode(int resizeMode) {
1003             mResizeMode = resizeMode;
1004             return this;
1005         }
1006 
setMaxAspectRatio(float maxAspectRatio)1007         ActivityBuilder setMaxAspectRatio(float maxAspectRatio) {
1008             mMaxAspectRatio = maxAspectRatio;
1009             return this;
1010         }
1011 
setMinAspectRatio(float minAspectRatio)1012         ActivityBuilder setMinAspectRatio(float minAspectRatio) {
1013             mMinAspectRatio = minAspectRatio;
1014             return this;
1015         }
1016 
setSupportsSizeChanges(boolean supportsSizeChanges)1017         ActivityBuilder setSupportsSizeChanges(boolean supportsSizeChanges) {
1018             mSupportsSizeChanges = supportsSizeChanges;
1019             return this;
1020         }
1021 
setScreenOrientation(int screenOrientation)1022         ActivityBuilder setScreenOrientation(int screenOrientation) {
1023             mScreenOrientation = screenOrientation;
1024             return this;
1025         }
1026 
setLaunchTaskBehind(boolean launchTaskBehind)1027         ActivityBuilder setLaunchTaskBehind(boolean launchTaskBehind) {
1028             mLaunchTaskBehind = launchTaskBehind;
1029             return this;
1030         }
1031 
setConfigChanges(int configChanges)1032         ActivityBuilder setConfigChanges(int configChanges) {
1033             mConfigChanges = configChanges;
1034             return this;
1035         }
1036 
setLaunchedFromPid(int pid)1037         ActivityBuilder setLaunchedFromPid(int pid) {
1038             mLaunchedFromPid = pid;
1039             return this;
1040         }
1041 
setLaunchedFromUid(int uid)1042         ActivityBuilder setLaunchedFromUid(int uid) {
1043             mLaunchedFromUid = uid;
1044             return this;
1045         }
1046 
setLaunchedFromPackage(String packageName)1047         ActivityBuilder setLaunchedFromPackage(String packageName) {
1048             mLaunchedFromPackage = packageName;
1049             return this;
1050         }
1051 
setUseProcess(WindowProcessController wpc)1052         ActivityBuilder setUseProcess(WindowProcessController wpc) {
1053             mWpc = wpc;
1054             return this;
1055         }
1056 
setAffinity(String affinity)1057         ActivityBuilder setAffinity(String affinity) {
1058             mAffinity = affinity;
1059             return this;
1060         }
1061 
setOnTop(boolean onTop)1062         ActivityBuilder setOnTop(boolean onTop) {
1063             mOnTop = onTop;
1064             return this;
1065         }
1066 
setWindowLayout(ActivityInfo.WindowLayout windowLayout)1067         ActivityBuilder setWindowLayout(ActivityInfo.WindowLayout windowLayout) {
1068             mWindowLayout = windowLayout;
1069             return this;
1070         }
1071 
setVisible(boolean visible)1072         ActivityBuilder setVisible(boolean visible) {
1073             mVisible = visible;
1074             return this;
1075         }
1076 
build()1077         ActivityRecord build() {
1078             SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock);
1079             try {
1080                 mService.deferWindowLayout();
1081                 return buildInner();
1082             } finally {
1083                 mService.continueWindowLayout();
1084             }
1085         }
1086 
buildInner()1087         ActivityRecord buildInner() {
1088             if (mComponent == null) {
1089                 final int id = sCurrentActivityId++;
1090                 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
1091                         DEFAULT_COMPONENT_CLASS_NAME + id);
1092             }
1093 
1094             Intent intent = new Intent();
1095             intent.setComponent(mComponent);
1096             if (mIntentExtras != null) {
1097                 intent.putExtras(mIntentExtras);
1098             }
1099             final ActivityInfo aInfo = new ActivityInfo();
1100             aInfo.applicationInfo = new ApplicationInfo();
1101             aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1102             aInfo.applicationInfo.packageName = mComponent.getPackageName();
1103             aInfo.applicationInfo.uid = mUid;
1104             aInfo.processName = mProcessName;
1105             aInfo.packageName = mComponent.getPackageName();
1106             aInfo.name = mComponent.getClassName();
1107             if (mTargetActivity != null) {
1108                 aInfo.targetActivity = mTargetActivity;
1109             }
1110             aInfo.flags |= mActivityFlags;
1111             aInfo.launchMode = mLaunchMode;
1112             aInfo.resizeMode = mResizeMode;
1113             aInfo.setMaxAspectRatio(mMaxAspectRatio);
1114             aInfo.setMinAspectRatio(mMinAspectRatio);
1115             aInfo.supportsSizeChanges = mSupportsSizeChanges;
1116             aInfo.screenOrientation = mScreenOrientation;
1117             aInfo.configChanges |= mConfigChanges;
1118             aInfo.taskAffinity = mAffinity;
1119             aInfo.windowLayout = mWindowLayout;
1120 
1121             if (mCreateTask) {
1122                 mTask = new TaskBuilder(mService.mTaskSupervisor)
1123                         .setComponent(mComponent)
1124                         // Apply the root activity info and intent
1125                         .setActivityInfo(aInfo)
1126                         .setIntent(intent)
1127                         .setParentTaskFragment(mParentTask).build();
1128             } else if (mTask == null && mParentTask != null && DisplayContent.alwaysCreateRootTask(
1129                     mParentTask.getWindowingMode(), mParentTask.getActivityType())) {
1130                 // The parent task can be the task root.
1131                 mTask = mParentTask;
1132             }
1133 
1134             ActivityOptions options = null;
1135             if (mLaunchTaskBehind) {
1136                 options = ActivityOptions.makeTaskLaunchBehind();
1137             }
1138             final ActivityRecord activity = new ActivityRecord.Builder(mService)
1139                     .setLaunchedFromPid(mLaunchedFromPid)
1140                     .setLaunchedFromUid(mLaunchedFromUid)
1141                     .setLaunchedFromPackage(mLaunchedFromPackage)
1142                     .setIntent(intent)
1143                     .setActivityInfo(aInfo)
1144                     .setActivityOptions(options)
1145                     .build();
1146 
1147             spyOn(activity);
1148             if (mTask != null) {
1149                 // fullscreen value is normally read from resources in ctor, so for testing we need
1150                 // to set it somewhere else since we can't mock resources.
1151                 doReturn(true).when(activity).occludesParent();
1152                 doReturn(true).when(activity).fillsParent();
1153                 mTask.addChild(activity);
1154                 if (mOnTop) {
1155                     // Move the task to front after activity is added.
1156                     // Or {@link TaskDisplayArea#mPreferredTopFocusableRootTask} could be other
1157                     // root tasks (e.g. home root task).
1158                     mTask.moveToFront("createActivity");
1159                 }
1160                 if (mVisible) {
1161                     activity.mVisibleRequested = true;
1162                     activity.setVisible(true);
1163                 }
1164             }
1165 
1166             final WindowProcessController wpc;
1167             if (mWpc != null) {
1168                 wpc = mWpc;
1169             } else {
1170                 wpc = new WindowProcessController(mService,
1171                         aInfo.applicationInfo, mProcessName, mUid,
1172                         UserHandle.getUserId(mUid), mock(Object.class),
1173                         mock(WindowProcessListener.class));
1174                 wpc.setThread(mock(IApplicationThread.class));
1175             }
1176             wpc.setThread(mock(IApplicationThread.class));
1177             activity.setProcess(wpc);
1178             doReturn(wpc).when(mService).getProcessController(
1179                     activity.processName, activity.info.applicationInfo.uid);
1180 
1181             // Resume top activities to make sure all other signals in the system are connected.
1182             mService.mRootWindowContainer.resumeFocusedTasksTopActivities();
1183             return activity;
1184         }
1185     }
1186 
1187     static class TaskFragmentBuilder {
1188         private final ActivityTaskManagerService mAtm;
1189         private Task mParentTask;
1190         private boolean mCreateParentTask;
1191         private boolean mCreateEmbeddedTask;
1192         private int mCreateActivityCount = 0;
1193         @Nullable
1194         private TaskFragmentOrganizer mOrganizer;
1195         private IBinder mFragmentToken;
1196 
TaskFragmentBuilder(ActivityTaskManagerService service)1197         TaskFragmentBuilder(ActivityTaskManagerService service) {
1198             mAtm = service;
1199         }
1200 
setCreateParentTask()1201         TaskFragmentBuilder setCreateParentTask() {
1202             mCreateParentTask = true;
1203             return this;
1204         }
1205 
setParentTask(Task task)1206         TaskFragmentBuilder setParentTask(Task task) {
1207             mParentTask = task;
1208             return this;
1209         }
1210 
1211         /** Creates a child embedded Task and its Activity */
createEmbeddedTask()1212         TaskFragmentBuilder createEmbeddedTask() {
1213             mCreateEmbeddedTask = true;
1214             return this;
1215         }
1216 
createActivityCount(int count)1217         TaskFragmentBuilder createActivityCount(int count) {
1218             mCreateActivityCount = count;
1219             return this;
1220         }
1221 
setOrganizer(@ullable TaskFragmentOrganizer organizer)1222         TaskFragmentBuilder setOrganizer(@Nullable TaskFragmentOrganizer organizer) {
1223             mOrganizer = organizer;
1224             return this;
1225         }
1226 
setFragmentToken(@ullable IBinder fragmentToken)1227         TaskFragmentBuilder setFragmentToken(@Nullable IBinder fragmentToken) {
1228             mFragmentToken = fragmentToken;
1229             return this;
1230         }
1231 
build()1232         TaskFragment build() {
1233             SystemServicesTestRule.checkHoldsLock(mAtm.mGlobalLock);
1234 
1235             final TaskFragment taskFragment = new TaskFragment(mAtm, mFragmentToken,
1236                     mOrganizer != null);
1237             if (mParentTask == null && mCreateParentTask) {
1238                 mParentTask = new TaskBuilder(mAtm.mTaskSupervisor).build();
1239             }
1240             if (mParentTask != null) {
1241                 mParentTask.addChild(taskFragment, POSITION_TOP);
1242             }
1243             if (mCreateEmbeddedTask) {
1244                 new TaskBuilder(mAtm.mTaskSupervisor)
1245                         .setParentTaskFragment(taskFragment)
1246                         .setCreateActivity(true)
1247                         .build();
1248             }
1249             while (mCreateActivityCount > 0) {
1250                 final ActivityRecord activity = new ActivityBuilder(mAtm).build();
1251                 taskFragment.addChild(activity);
1252                 mCreateActivityCount--;
1253             }
1254             if (mOrganizer != null) {
1255                 taskFragment.setTaskFragmentOrganizer(
1256                         mOrganizer.getOrganizerToken(), DEFAULT_TASK_FRAGMENT_ORGANIZER_UID,
1257                         DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME);
1258             }
1259             return taskFragment;
1260         }
1261     }
1262 
1263     /**
1264      * Builder for creating new tasks.
1265      */
1266     protected static class TaskBuilder {
1267         private final ActivityTaskSupervisor mSupervisor;
1268 
1269         private TaskDisplayArea mTaskDisplayArea;
1270         private ComponentName mComponent;
1271         private String mPackage;
1272         private int mFlags = 0;
1273         private int mTaskId = -1;
1274         private int mUserId = 0;
1275         private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
1276         private int mActivityType = ACTIVITY_TYPE_STANDARD;
1277         private ActivityInfo mActivityInfo;
1278         private Intent mIntent;
1279         private boolean mOnTop = true;
1280         private IVoiceInteractionSession mVoiceSession;
1281 
1282         private boolean mCreateParentTask = false;
1283         private TaskFragment mParentTaskFragment;
1284 
1285         private boolean mCreateActivity = false;
1286 
TaskBuilder(ActivityTaskSupervisor supervisor)1287         TaskBuilder(ActivityTaskSupervisor supervisor) {
1288             mSupervisor = supervisor;
1289             mTaskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
1290         }
1291 
1292         /**
1293          * Set the parent {@link DisplayContent} and use the default task display area. Overrides
1294          * the task display area, if was set before.
1295          */
setDisplay(DisplayContent display)1296         TaskBuilder setDisplay(DisplayContent display) {
1297             mTaskDisplayArea = display.getDefaultTaskDisplayArea();
1298             return this;
1299         }
1300 
1301         /** Set the parent {@link TaskDisplayArea}. Overrides the display, if was set before. */
setTaskDisplayArea(TaskDisplayArea taskDisplayArea)1302         TaskBuilder setTaskDisplayArea(TaskDisplayArea taskDisplayArea) {
1303             mTaskDisplayArea = taskDisplayArea;
1304             return this;
1305         }
1306 
setComponent(ComponentName component)1307         TaskBuilder setComponent(ComponentName component) {
1308             mComponent = component;
1309             return this;
1310         }
1311 
setPackage(String packageName)1312         TaskBuilder setPackage(String packageName) {
1313             mPackage = packageName;
1314             return this;
1315         }
1316 
setFlags(int flags)1317         TaskBuilder setFlags(int flags) {
1318             mFlags = flags;
1319             return this;
1320         }
1321 
setTaskId(int taskId)1322         TaskBuilder setTaskId(int taskId) {
1323             mTaskId = taskId;
1324             return this;
1325         }
1326 
setUserId(int userId)1327         TaskBuilder setUserId(int userId) {
1328             mUserId = userId;
1329             return this;
1330         }
1331 
setWindowingMode(int windowingMode)1332         TaskBuilder setWindowingMode(int windowingMode) {
1333             mWindowingMode = windowingMode;
1334             return this;
1335         }
1336 
setActivityType(int activityType)1337         TaskBuilder setActivityType(int activityType) {
1338             mActivityType = activityType;
1339             return this;
1340         }
1341 
setActivityInfo(ActivityInfo info)1342         TaskBuilder setActivityInfo(ActivityInfo info) {
1343             mActivityInfo = info;
1344             return this;
1345         }
1346 
setIntent(Intent intent)1347         TaskBuilder setIntent(Intent intent) {
1348             mIntent = intent;
1349             return this;
1350         }
1351 
setOnTop(boolean onTop)1352         TaskBuilder setOnTop(boolean onTop) {
1353             mOnTop = onTop;
1354             return this;
1355         }
1356 
setVoiceSession(IVoiceInteractionSession session)1357         TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
1358             mVoiceSession = session;
1359             return this;
1360         }
1361 
setCreateParentTask(boolean createParentTask)1362         TaskBuilder setCreateParentTask(boolean createParentTask) {
1363             mCreateParentTask = createParentTask;
1364             return this;
1365         }
1366 
setParentTaskFragment(TaskFragment parentTaskFragment)1367         TaskBuilder setParentTaskFragment(TaskFragment parentTaskFragment) {
1368             mParentTaskFragment = parentTaskFragment;
1369             return this;
1370         }
1371 
setCreateActivity(boolean createActivity)1372         TaskBuilder setCreateActivity(boolean createActivity) {
1373             mCreateActivity = createActivity;
1374             return this;
1375         }
1376 
build()1377         Task build() {
1378             SystemServicesTestRule.checkHoldsLock(mSupervisor.mService.mGlobalLock);
1379 
1380             // Create parent task.
1381             if (mParentTaskFragment == null && mCreateParentTask) {
1382                 mParentTaskFragment = mTaskDisplayArea.createRootTask(
1383                         WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
1384             }
1385             if (mParentTaskFragment != null
1386                     && !Mockito.mockingDetails(mParentTaskFragment).isSpy()) {
1387                 spyOn(mParentTaskFragment);
1388             }
1389 
1390             // Create task.
1391             if (mActivityInfo == null) {
1392                 mActivityInfo = new ActivityInfo();
1393                 mActivityInfo.applicationInfo = new ApplicationInfo();
1394                 mActivityInfo.applicationInfo.packageName = mPackage;
1395             }
1396 
1397             if (mIntent == null) {
1398                 mIntent = new Intent();
1399                 if (mComponent == null) {
1400                     mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
1401                             DEFAULT_COMPONENT_CLASS_NAME);
1402                 }
1403                 mIntent.setComponent(mComponent);
1404                 mIntent.setFlags(mFlags);
1405             }
1406 
1407             final Task.Builder builder = new Task.Builder(mSupervisor.mService)
1408                     .setTaskId(mTaskId >= 0 ? mTaskId : mTaskDisplayArea.getNextRootTaskId())
1409                     .setWindowingMode(mWindowingMode)
1410                     .setActivityInfo(mActivityInfo)
1411                     .setIntent(mIntent)
1412                     .setOnTop(mOnTop)
1413                     .setVoiceSession(mVoiceSession);
1414             final Task task;
1415             if (mParentTaskFragment == null) {
1416                 task = builder.setActivityType(mActivityType)
1417                         .setParent(mTaskDisplayArea)
1418                         .build();
1419             } else {
1420                 task = builder.setParent(mParentTaskFragment).build();
1421                 if (mParentTaskFragment.asTask() != null) {
1422                     mParentTaskFragment.asTask().moveToFront("build-task");
1423                 }
1424             }
1425             spyOn(task);
1426             task.mUserId = mUserId;
1427             final Task rootTask = task.getRootTask();
1428             if (task != rootTask && !Mockito.mockingDetails(rootTask).isSpy()) {
1429                 spyOn(rootTask);
1430             }
1431             doNothing().when(rootTask).startActivityLocked(
1432                     any(), any(), anyBoolean(), anyBoolean(), any(), any());
1433 
1434             // Create child task with activity.
1435             if (mCreateActivity) {
1436                 new ActivityBuilder(mSupervisor.mService)
1437                         .setTask(task)
1438                         .build();
1439                 if (mOnTop) {
1440                     // We move the task to front again in order to regain focus after activity
1441                     // is added. Or {@link TaskDisplayArea#mPreferredTopFocusableRootTask} could be
1442                     // other root tasks (e.g. home root task).
1443                     task.moveToFront("createActivityTask");
1444                 } else {
1445                     task.moveToBack("createActivityTask", null);
1446                 }
1447             }
1448 
1449             return task;
1450         }
1451     }
1452 
1453     static class TestStartingWindowOrganizer extends WindowOrganizerTests.StubOrganizer {
1454         private final ActivityTaskManagerService mAtm;
1455         private final WindowManagerService mWMService;
1456         private final WindowState.PowerManagerWrapper mPowerManagerWrapper;
1457 
1458         private Runnable mRunnableWhenAddingSplashScreen;
1459         private final SparseArray<IBinder> mTaskAppMap = new SparseArray<>();
1460         private final HashMap<IBinder, WindowState> mAppWindowMap = new HashMap<>();
1461 
TestStartingWindowOrganizer(ActivityTaskManagerService service, WindowState.PowerManagerWrapper powerManagerWrapper)1462         TestStartingWindowOrganizer(ActivityTaskManagerService service,
1463                 WindowState.PowerManagerWrapper powerManagerWrapper) {
1464             mAtm = service;
1465             mWMService = mAtm.mWindowManager;
1466             mPowerManagerWrapper = powerManagerWrapper;
1467             if (DEBUG_ENABLE_SHELL_DRAWER) {
1468                 mAtm.mTaskOrganizerController.setDeferTaskOrgCallbacksConsumer(Runnable::run);
1469                 mAtm.mTaskOrganizerController.registerTaskOrganizer(this);
1470             }
1471         }
1472 
setRunnableWhenAddingSplashScreen(Runnable r)1473         void setRunnableWhenAddingSplashScreen(Runnable r) {
1474             if (DEBUG_ENABLE_SHELL_DRAWER) {
1475                 mRunnableWhenAddingSplashScreen = r;
1476             } else {
1477                 ((TestWindowManagerPolicy) mWMService.mPolicy).setRunnableWhenAddingSplashScreen(r);
1478             }
1479         }
1480 
1481         @Override
addStartingWindow(StartingWindowInfo info, IBinder appToken)1482         public void addStartingWindow(StartingWindowInfo info, IBinder appToken) {
1483             synchronized (mWMService.mGlobalLock) {
1484                 final ActivityRecord activity = mWMService.mRoot.getActivityRecord(
1485                         appToken);
1486                 IWindow iWindow = mock(IWindow.class);
1487                 doReturn(mock(IBinder.class)).when(iWindow).asBinder();
1488                 final WindowState window = WindowTestsBase.createWindow(null,
1489                         TYPE_APPLICATION_STARTING, activity,
1490                         "Starting window", 0 /* ownerId */, 0 /* userId*/,
1491                         false /* internalWindows */, mWMService, mock(Session.class),
1492                         iWindow,
1493                         mPowerManagerWrapper);
1494                 activity.mStartingWindow = window;
1495                 mAppWindowMap.put(appToken, window);
1496                 mTaskAppMap.put(info.taskInfo.taskId, appToken);
1497             }
1498             if (mRunnableWhenAddingSplashScreen != null) {
1499                 mRunnableWhenAddingSplashScreen.run();
1500                 mRunnableWhenAddingSplashScreen = null;
1501             }
1502         }
1503         @Override
removeStartingWindow(StartingWindowRemovalInfo removalInfo)1504         public void removeStartingWindow(StartingWindowRemovalInfo removalInfo) {
1505             synchronized (mWMService.mGlobalLock) {
1506                 final IBinder appToken = mTaskAppMap.get(removalInfo.taskId);
1507                 if (appToken != null) {
1508                     mTaskAppMap.remove(removalInfo.taskId);
1509                     final ActivityRecord activity = mWMService.mRoot.getActivityRecord(
1510                             appToken);
1511                     WindowState win = mAppWindowMap.remove(appToken);
1512                     activity.removeChild(win);
1513                     activity.mStartingWindow = null;
1514                 }
1515             }
1516         }
1517     }
1518 
1519     static class TestSplitOrganizer extends WindowOrganizerTests.StubOrganizer {
1520         final ActivityTaskManagerService mService;
1521         Task mPrimary;
1522         Task mSecondary;
1523         boolean mInSplit = false;
1524         // moves everything to secondary. Most tests expect this since sysui usually does it.
1525         boolean mMoveToSecondaryOnEnter = true;
1526         int mDisplayId;
1527         private static final int[] CONTROLLED_ACTIVITY_TYPES = {
1528                 ACTIVITY_TYPE_STANDARD,
1529                 ACTIVITY_TYPE_HOME,
1530                 ACTIVITY_TYPE_RECENTS,
1531                 ACTIVITY_TYPE_UNDEFINED
1532         };
1533         private static final int[] CONTROLLED_WINDOWING_MODES = {
1534                 WINDOWING_MODE_FULLSCREEN,
1535                 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
1536                 WINDOWING_MODE_UNDEFINED
1537         };
TestSplitOrganizer(ActivityTaskManagerService service, DisplayContent display)1538         TestSplitOrganizer(ActivityTaskManagerService service, DisplayContent display) {
1539             mService = service;
1540             mDisplayId = display.mDisplayId;
1541             mService.mTaskOrganizerController.registerTaskOrganizer(this);
1542             mPrimary = mService.mTaskOrganizerController.createRootTask(
1543                     display, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, null);
1544             mSecondary = mService.mTaskOrganizerController.createRootTask(
1545                     display, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);;
1546         }
TestSplitOrganizer(ActivityTaskManagerService service)1547         TestSplitOrganizer(ActivityTaskManagerService service) {
1548             this(service, service.mTaskSupervisor.mRootWindowContainer.getDefaultDisplay());
1549         }
setMoveToSecondaryOnEnter(boolean move)1550         public void setMoveToSecondaryOnEnter(boolean move) {
1551             mMoveToSecondaryOnEnter = move;
1552         }
1553 
1554         @Override
onTaskInfoChanged(ActivityManager.RunningTaskInfo info)1555         public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
1556             if (mInSplit) {
1557                 return;
1558             }
1559             if (info.topActivityType == ACTIVITY_TYPE_UNDEFINED) {
1560                 // Not populated
1561                 return;
1562             }
1563             if (info.configuration.windowConfiguration.getWindowingMode()
1564                     != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1565                 return;
1566             }
1567             mInSplit = true;
1568             if (!mMoveToSecondaryOnEnter) {
1569                 return;
1570             }
1571             DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId);
1572             dc.getDefaultTaskDisplayArea().setLaunchRootTask(
1573                     mSecondary, CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES);
1574             dc.forAllRootTasks(rootTask -> {
1575                 if (!WindowConfiguration.isSplitScreenWindowingMode(rootTask.getWindowingMode())) {
1576                     rootTask.reparent(mSecondary, POSITION_BOTTOM);
1577                 }
1578             });
1579         }
1580     }
1581 
createTestWindowToken(int type, DisplayContent dc)1582     static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {
1583         return createTestWindowToken(type, dc, false /* persistOnEmpty */);
1584     }
1585 
createTestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty)1586     static TestWindowToken createTestWindowToken(int type, DisplayContent dc,
1587             boolean persistOnEmpty) {
1588         SystemServicesTestRule.checkHoldsLock(dc.mWmService.mGlobalLock);
1589 
1590         return new TestWindowToken(type, dc, persistOnEmpty);
1591     }
1592 
1593     /** Used so we can gain access to some protected members of the {@link WindowToken} class */
1594     static class TestWindowToken extends WindowToken {
1595 
TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty)1596         private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
1597             super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc,
1598                     false /* ownerCanManageAppTokens */);
1599         }
1600 
getWindowsCount()1601         int getWindowsCount() {
1602             return mChildren.size();
1603         }
1604 
hasWindow(WindowState w)1605         boolean hasWindow(WindowState w) {
1606             return mChildren.contains(w);
1607         }
1608     }
1609 
1610     /** Used to track resize reports. */
1611     static class TestWindowState extends WindowState {
1612         boolean mResizeReported;
1613 
TestWindowState(WindowManagerService service, Session session, IWindow window, WindowManager.LayoutParams attrs, WindowToken token)1614         TestWindowState(WindowManagerService service, Session session, IWindow window,
1615                 WindowManager.LayoutParams attrs, WindowToken token) {
1616             super(service, session, window, token, null, OP_NONE, attrs, 0, 0, 0,
1617                     false /* ownerCanAddInternalSystemWindow */);
1618         }
1619 
1620         @Override
reportResized()1621         void reportResized() {
1622             super.reportResized();
1623             mResizeReported = true;
1624         }
1625 
1626         @Override
isGoneForLayout()1627         public boolean isGoneForLayout() {
1628             return false;
1629         }
1630 
1631         @Override
updateResizingWindowIfNeeded()1632         void updateResizingWindowIfNeeded() {
1633             // Used in AppWindowTokenTests#testLandscapeSeascapeRotationRelayout to deceive
1634             // the system that it can actually update the window.
1635             boolean hadSurface = mHasSurface;
1636             mHasSurface = true;
1637 
1638             super.updateResizingWindowIfNeeded();
1639 
1640             mHasSurface = hadSurface;
1641         }
1642     }
1643 
1644     static class TestTransitionPlayer extends ITransitionPlayer.Stub {
1645         final TransitionController mController;
1646         final WindowOrganizerController mOrganizer;
1647         Transition mLastTransit = null;
1648         TransitionRequestInfo mLastRequest = null;
1649         TransitionInfo mLastReady = null;
1650 
TestTransitionPlayer(@onNull TransitionController controller, @NonNull WindowOrganizerController organizer)1651         TestTransitionPlayer(@NonNull TransitionController controller,
1652                 @NonNull WindowOrganizerController organizer) {
1653             mController = controller;
1654             mOrganizer = organizer;
1655         }
1656 
clear()1657         void clear() {
1658             mLastTransit = null;
1659             mLastReady = null;
1660             mLastRequest = null;
1661         }
1662 
1663         @Override
onTransitionReady(IBinder transitToken, TransitionInfo transitionInfo, SurfaceControl.Transaction transaction, SurfaceControl.Transaction finishT)1664         public void onTransitionReady(IBinder transitToken, TransitionInfo transitionInfo,
1665                 SurfaceControl.Transaction transaction, SurfaceControl.Transaction finishT)
1666                 throws RemoteException {
1667             mLastTransit = Transition.fromBinder(transitToken);
1668             mLastReady = transitionInfo;
1669         }
1670 
1671         @Override
requestStartTransition(IBinder transitToken, TransitionRequestInfo request)1672         public void requestStartTransition(IBinder transitToken,
1673                 TransitionRequestInfo request) throws RemoteException {
1674             mLastTransit = Transition.fromBinder(transitToken);
1675             mLastRequest = request;
1676         }
1677 
start()1678         public void start() {
1679             mOrganizer.startTransition(mLastRequest.getType(), mLastTransit, null);
1680             mLastTransit.onTransactionReady(mLastTransit.getSyncId(),
1681                     mock(SurfaceControl.Transaction.class));
1682         }
1683 
finish()1684         public void finish() {
1685             mController.finishTransition(mLastTransit);
1686         }
1687     }
1688 }
1689