xref: /aosp_15_r20/frameworks/base/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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_DREAM;
21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
22 import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
23 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
24 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
25 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
26 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
27 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
28 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
29 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
30 import static android.os.Process.SYSTEM_UID;
31 import static android.view.View.VISIBLE;
32 import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
33 import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
34 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
35 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
36 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
37 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
38 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
39 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
40 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
41 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
42 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
43 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
44 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
45 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
46 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
47 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
48 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
49 
50 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
51 
52 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
53 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
54 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
55 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
56 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
57 import static com.android.server.wm.WindowContainer.POSITION_TOP;
58 import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
59 import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
60 
61 import static org.junit.Assert.assertEquals;
62 import static org.junit.Assert.assertFalse;
63 import static org.mockito.ArgumentMatchers.any;
64 import static org.mockito.ArgumentMatchers.anyBoolean;
65 import static org.mockito.ArgumentMatchers.anyInt;
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.ActivityOptions;
72 import android.content.ComponentName;
73 import android.content.ContentResolver;
74 import android.content.Context;
75 import android.content.Intent;
76 import android.content.pm.ActivityInfo;
77 import android.content.pm.ApplicationInfo;
78 import android.content.res.Configuration;
79 import android.graphics.Insets;
80 import android.graphics.Rect;
81 import android.hardware.HardwareBuffer;
82 import android.hardware.display.DisplayManager;
83 import android.os.Binder;
84 import android.os.Build;
85 import android.os.Bundle;
86 import android.os.Handler;
87 import android.os.IBinder;
88 import android.os.RemoteException;
89 import android.os.UserHandle;
90 import android.provider.Settings;
91 import android.service.voice.IVoiceInteractionSession;
92 import android.util.MergedConfiguration;
93 import android.util.SparseArray;
94 import android.view.Display;
95 import android.view.DisplayInfo;
96 import android.view.Gravity;
97 import android.view.IDisplayWindowInsetsController;
98 import android.view.IWindow;
99 import android.view.IWindowSessionCallback;
100 import android.view.InsetsFrameProvider;
101 import android.view.InsetsSourceControl;
102 import android.view.InsetsState;
103 import android.view.Surface;
104 import android.view.SurfaceControl;
105 import android.view.SurfaceControl.Transaction;
106 import android.view.View;
107 import android.view.WindowInsets;
108 import android.view.WindowManager;
109 import android.view.WindowManager.DisplayImePolicy;
110 import android.view.inputmethod.ImeTracker;
111 import android.window.ActivityWindowInfo;
112 import android.window.ClientWindowFrames;
113 import android.window.ITaskFragmentOrganizer;
114 import android.window.ITransitionPlayer;
115 import android.window.ScreenCapture;
116 import android.window.StartingWindowInfo;
117 import android.window.StartingWindowRemovalInfo;
118 import android.window.TaskFragmentOrganizer;
119 import android.window.TransitionInfo;
120 import android.window.TransitionRequestInfo;
121 import android.window.WindowContainerTransaction;
122 
123 import com.android.internal.policy.AttributeCache;
124 import com.android.internal.util.ArrayUtils;
125 import com.android.internal.util.test.FakeSettingsProvider;
126 import com.android.server.wallpaper.WallpaperCropper.WallpaperCropUtils;
127 import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry;
128 
129 import org.junit.After;
130 import org.junit.Before;
131 import org.junit.BeforeClass;
132 import org.junit.runner.Description;
133 import org.mockito.Mockito;
134 
135 import java.lang.annotation.Annotation;
136 import java.lang.annotation.ElementType;
137 import java.lang.annotation.Retention;
138 import java.lang.annotation.RetentionPolicy;
139 import java.lang.annotation.Target;
140 import java.util.ArrayList;
141 import java.util.HashMap;
142 import java.util.List;
143 
144 /** Common base class for window manager unit test classes. */
145 public class WindowTestsBase extends SystemServiceTestsBase {
146     protected final Context mContext = getInstrumentation().getTargetContext();
147 
148     // Default package name
149     static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
150 
151     static final int DEFAULT_TASK_FRAGMENT_ORGANIZER_UID = 10000;
152     static final String DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME = "Test:TaskFragmentOrganizer";
153 
154     // Default base activity name
155     private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
156 
157     // An id appended to the end of the component name to make it unique
158     static int sCurrentActivityId = 0;
159 
160     ActivityTaskManagerService mAtm;
161     RootWindowContainer mRootWindowContainer;
162     ActivityTaskSupervisor mSupervisor;
163     ClientLifecycleManager mClientLifecycleManager;
164     WindowManagerService mWm;
165     private final IWindow mIWindow = new TestIWindow();
166     private Session mTestSession;
167     private boolean mUseFakeSettingsProvider;
168 
169     DisplayInfo mDisplayInfo = new DisplayInfo();
170     DisplayContent mDefaultDisplay;
171 
172     static final int STATUS_BAR_HEIGHT = 10;
173     static final int NAV_BAR_HEIGHT = 15;
174 
175     /**
176      * It is {@link #mDefaultDisplay} by default. If the test class or method is annotated with
177      * {@link UseTestDisplay}, it will be an additional display.
178      */
179     DisplayContent mDisplayContent;
180 
181     // The following fields are only available depending on the usage of annotation UseTestDisplay
182     // and UseCommonWindows.
183     WindowState mWallpaperWindow;
184     WindowState mImeWindow;
185     WindowState mImeDialogWindow;
186     WindowState mStatusBarWindow;
187     WindowState mNotificationShadeWindow;
188     WindowState mDockedDividerWindow;
189     WindowState mNavBarWindow;
190     WindowState mAppWindow;
191     WindowState mChildAppWindowAbove;
192     WindowState mChildAppWindowBelow;
193 
194     /**
195      * Spied {@link Transaction} class than can be used to verify calls.
196      */
197     Transaction mTransaction;
198 
199     /**
200      * Whether device-specific global overrides have already been checked in
201      * {@link WindowTestsBase#setUpBase()}.
202      */
203     private static boolean sGlobalOverridesChecked;
204     /**
205      * Whether device-specific overrides have already been checked in
206      * {@link WindowTestsBase#setUpBase()} when the default display is used.
207      */
208     private static boolean sOverridesCheckedDefaultDisplay;
209     /**
210      * Whether device-specific overrides have already been checked in
211      * {@link WindowTestsBase#setUpBase()} when a {@link TestDisplayContent} is used.
212      */
213     private static boolean sOverridesCheckedTestDisplay;
214 
215     private boolean mOriginalPerDisplayFocusEnabled;
216 
217     @BeforeClass
setUpOnceBase()218     public static void setUpOnceBase() {
219         AttributeCache.init(getInstrumentation().getTargetContext());
220     }
221 
222     @Before
setUpBase()223     public void setUpBase() {
224         mAtm = mSystemServicesTestRule.getActivityTaskManagerService();
225         mSupervisor = mAtm.mTaskSupervisor;
226         mRootWindowContainer = mAtm.mRootWindowContainer;
227         mClientLifecycleManager = mAtm.getLifecycleManager();
228         mWm = mSystemServicesTestRule.getWindowManagerService();
229         mOriginalPerDisplayFocusEnabled = mWm.mPerDisplayFocusEnabled;
230         SystemServicesTestRule.checkHoldsLock(mWm.mGlobalLock);
231 
232         mDefaultDisplay = mWm.mRoot.getDefaultDisplay();
233         // Update the display policy to make the screen fully turned on so animation is allowed
234         final DisplayPolicy displayPolicy = mDefaultDisplay.getDisplayPolicy();
235         displayPolicy.screenTurningOn(null /* screenOnListener */);
236         displayPolicy.finishKeyguardDrawn();
237         displayPolicy.finishWindowsDrawn();
238         displayPolicy.finishScreenTurningOn();
239 
240         final InsetsPolicy insetsPolicy = mDefaultDisplay.getInsetsPolicy();
241         suppressInsetsAnimation(insetsPolicy.getTransientControlTarget());
242         suppressInsetsAnimation(insetsPolicy.getPermanentControlTarget());
243 
244         mTransaction = mSystemServicesTestRule.mTransaction;
245 
246         mContext.getSystemService(DisplayManager.class)
247                 .getDisplay(Display.DEFAULT_DISPLAY).getDisplayInfo(mDisplayInfo);
248 
249         // Only create an additional test display for annotated test class/method because it may
250         // significantly increase the execution time.
251         final Description description = mSystemServicesTestRule.getDescription();
252         final UseTestDisplay useTestDisplay = getAnnotation(description, UseTestDisplay.class);
253         if (useTestDisplay != null) {
254             createTestDisplay(useTestDisplay);
255         } else {
256             mDisplayContent = mDefaultDisplay;
257             final SetupWindows setupWindows = getAnnotation(description, SetupWindows.class);
258             if (setupWindows != null) {
259                 addCommonWindows(setupWindows.addAllCommonWindows(), setupWindows.addWindows());
260             }
261         }
262 
263         // Ensure letterbox aspect ratio is not overridden on any device target.
264         // {@link com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}, is set
265         // on some device form factors.
266         mAtm.mWindowManager.mAppCompatConfiguration.setFixedOrientationLetterboxAspectRatio(0);
267         // Ensure letterbox horizontal position multiplier is not overridden on any device target.
268         // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier},
269         // may be set on some device form factors.
270         mAtm.mWindowManager.mAppCompatConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f);
271         // Ensure letterbox vertical position multiplier is not overridden on any device target.
272         // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier},
273         // may be set on some device form factors.
274         mAtm.mWindowManager.mAppCompatConfiguration.setLetterboxVerticalPositionMultiplier(0.0f);
275         // Ensure letterbox horizontal reachability treatment isn't overridden on any device target.
276         // {@link com.android.internal.R.bool.config_letterboxIsHorizontalReachabilityEnabled},
277         // may be set on some device form factors.
278         mAtm.mWindowManager.mAppCompatConfiguration.setIsHorizontalReachabilityEnabled(false);
279         // Ensure letterbox vertical reachability treatment isn't overridden on any device target.
280         // {@link com.android.internal.R.bool.config_letterboxIsVerticalReachabilityEnabled},
281         // may be set on some device form factors.
282         mAtm.mWindowManager.mAppCompatConfiguration.setIsVerticalReachabilityEnabled(false);
283         // Ensure aspect ratio for unresizable apps isn't overridden on any device target.
284         // {@link com.android.internal.R.bool
285         // .config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled}, may be set on some
286         // device form factors.
287         mAtm.mWindowManager.mAppCompatConfiguration
288                 .setIsSplitScreenAspectRatioForUnresizableAppsEnabled(false);
289         // Ensure aspect ratio for al apps isn't overridden on any device target.
290         // {@link com.android.internal.R.bool
291         // .config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled}, may be set on
292         // some device form factors.
293         mAtm.mWindowManager.mAppCompatConfiguration
294                 .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(false);
295 
296         // Setup WallpaperController crop utils with a simple center-align strategy
297         WallpaperCropUtils cropUtils = (displaySize, bitmapSize, suggestedCrops, rtl) -> {
298             Rect crop = new Rect(0, 0, displaySize.x, displaySize.y);
299             crop.scale(Math.min(
300                     ((float) bitmapSize.x) / displaySize.x,
301                     ((float) bitmapSize.y) / displaySize.y));
302             crop.offset((bitmapSize.x - crop.width()) / 2, (bitmapSize.y - crop.height()) / 2);
303             return crop;
304         };
305         mDisplayContent.mWallpaperController.setWallpaperCropUtils(cropUtils);
306         mDefaultDisplay.mWallpaperController.setWallpaperCropUtils(cropUtils);
307 
308         checkDeviceSpecificOverridesNotApplied();
309     }
310 
311     /**
312      * The test doesn't create real SurfaceControls, but mocked ones. This prevents the target from
313      * controlling them, or it will cause {@link NullPointerException}.
314      */
suppressInsetsAnimation(InsetsControlTarget target)315     static void suppressInsetsAnimation(InsetsControlTarget target) {
316         spyOn(target);
317         Mockito.doNothing().when(target).notifyInsetsControlChanged(anyInt());
318     }
319 
320     @After
tearDown()321     public void tearDown() throws Exception {
322         if (mUseFakeSettingsProvider) {
323             FakeSettingsProvider.clearSettingsProvider();
324         }
325         mWm.mPerDisplayFocusEnabled = mOriginalPerDisplayFocusEnabled;
326     }
327 
328     /**
329      * Check that device-specific overrides are not applied. Only need to check once during entire
330      * test run for each case: global overrides, default display, and test display.
331      */
checkDeviceSpecificOverridesNotApplied()332     private void checkDeviceSpecificOverridesNotApplied() {
333         // Check global overrides
334         if (!sGlobalOverridesChecked) {
335             assertEquals(0, mWm.mAppCompatConfiguration.getFixedOrientationLetterboxAspectRatio(),
336                     0 /* delta */);
337             sGlobalOverridesChecked = true;
338         }
339         // Check display-specific overrides
340         if (!sOverridesCheckedDefaultDisplay && mDisplayContent == mDefaultDisplay) {
341             assertFalse(mDisplayContent.getIgnoreOrientationRequest());
342             sOverridesCheckedDefaultDisplay = true;
343         } else if (!sOverridesCheckedTestDisplay && mDisplayContent instanceof TestDisplayContent) {
344             assertFalse(mDisplayContent.getIgnoreOrientationRequest());
345             sOverridesCheckedTestDisplay = true;
346         }
347     }
348 
createTestDisplay(UseTestDisplay annotation)349     private void createTestDisplay(UseTestDisplay annotation) {
350         beforeCreateTestDisplay();
351         mDisplayContent = createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL);
352         addCommonWindows(annotation.addAllCommonWindows(), annotation.addWindows());
353         mDisplayContent.getDisplayPolicy().setRemoteInsetsControllerControlsSystemBars(false);
354 
355         // Adding a display will cause freezing the display. Make sure to wait until it's
356         // unfrozen to not run into race conditions with the tests.
357         waitUntilHandlersIdle();
358     }
359 
addCommonWindows(boolean addAll, @CommonTypes int[] requestedWindows)360     private void addCommonWindows(boolean addAll, @CommonTypes int[] requestedWindows) {
361         if (addAll || ArrayUtils.contains(requestedWindows, W_WALLPAPER)) {
362             mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
363         }
364         if (addAll || ArrayUtils.contains(requestedWindows, W_INPUT_METHOD)) {
365             mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow");
366             mDisplayContent.mInputMethodWindow = mImeWindow;
367         }
368         if (addAll || ArrayUtils.contains(requestedWindows, W_INPUT_METHOD_DIALOG)) {
369             mImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG,
370                     "mImeDialogWindow");
371         }
372         if (addAll || ArrayUtils.contains(requestedWindows, W_STATUS_BAR)) {
373             mStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "mStatusBarWindow");
374             mStatusBarWindow.mAttrs.height = STATUS_BAR_HEIGHT;
375             mStatusBarWindow.mAttrs.gravity = Gravity.TOP;
376             mStatusBarWindow.mAttrs.layoutInDisplayCutoutMode =
377                     LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
378             mStatusBarWindow.mAttrs.setFitInsetsTypes(0);
379             final IBinder owner = new Binder();
380             mStatusBarWindow.mAttrs.providedInsets = new InsetsFrameProvider[] {
381                     new InsetsFrameProvider(owner, 0, WindowInsets.Type.statusBars()),
382                     new InsetsFrameProvider(owner, 0, WindowInsets.Type.tappableElement()),
383                     new InsetsFrameProvider(owner, 0, WindowInsets.Type.mandatorySystemGestures())
384             };
385         }
386         if (addAll || ArrayUtils.contains(requestedWindows, W_NOTIFICATION_SHADE)) {
387             mNotificationShadeWindow = createCommonWindow(null, TYPE_NOTIFICATION_SHADE,
388                     "mNotificationShadeWindow");
389         }
390         if (addAll || ArrayUtils.contains(requestedWindows, W_NAVIGATION_BAR)) {
391             mNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "mNavBarWindow");
392             mNavBarWindow.mAttrs.height = NAV_BAR_HEIGHT;
393             mNavBarWindow.mAttrs.gravity = Gravity.BOTTOM;
394             mNavBarWindow.mAttrs.paramsForRotation = new WindowManager.LayoutParams[4];
395             mNavBarWindow.mAttrs.setFitInsetsTypes(0);
396             mNavBarWindow.mAttrs.layoutInDisplayCutoutMode =
397                     LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
398             mNavBarWindow.mAttrs.privateFlags |=
399                     WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
400             final IBinder owner = new Binder();
401             mNavBarWindow.mAttrs.providedInsets = new InsetsFrameProvider[] {
402                     new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars()),
403                     new InsetsFrameProvider(owner, 0, WindowInsets.Type.tappableElement()),
404                     new InsetsFrameProvider(owner, 0, WindowInsets.Type.mandatorySystemGestures())
405             };
406             // If the navigation bar cannot move then it is always at the bottom.
407             if (mDisplayContent.getDisplayPolicy().navigationBarCanMove()) {
408                 for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) {
409                     mNavBarWindow.mAttrs.paramsForRotation[rot] =
410                             getNavBarLayoutParamsForRotation(rot, owner);
411                 }
412             }
413         }
414         if (addAll || ArrayUtils.contains(requestedWindows, W_DOCK_DIVIDER)) {
415             mDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER,
416                     "mDockedDividerWindow");
417         }
418         final boolean addAboveApp = ArrayUtils.contains(requestedWindows, W_ABOVE_ACTIVITY);
419         final boolean addBelowApp = ArrayUtils.contains(requestedWindows, W_BELOW_ACTIVITY);
420         if (addAll || addAboveApp || addBelowApp
421                 || ArrayUtils.contains(requestedWindows, W_ACTIVITY)) {
422             mAppWindow = createCommonWindow(null, TYPE_BASE_APPLICATION, "mAppWindow");
423         }
424         if (addAll || addAboveApp) {
425             mChildAppWindowAbove = createCommonWindow(mAppWindow, TYPE_APPLICATION_ATTACHED_DIALOG,
426                     "mChildAppWindowAbove");
427         }
428         if (addAll || addBelowApp) {
429             mChildAppWindowBelow = createCommonWindow(mAppWindow, TYPE_APPLICATION_MEDIA_OVERLAY,
430                     "mChildAppWindowBelow");
431         }
432     }
433 
getNavBarLayoutParamsForRotation( int rotation, IBinder owner)434     private WindowManager.LayoutParams getNavBarLayoutParamsForRotation(
435             int rotation, IBinder owner) {
436         int width = WindowManager.LayoutParams.MATCH_PARENT;
437         int height = WindowManager.LayoutParams.MATCH_PARENT;
438         int gravity = Gravity.BOTTOM;
439         switch (rotation) {
440             case ROTATION_UNDEFINED:
441             case Surface.ROTATION_0:
442             case Surface.ROTATION_180:
443                 height = NAV_BAR_HEIGHT;
444                 break;
445             case Surface.ROTATION_90:
446                 gravity = Gravity.RIGHT;
447                 width = NAV_BAR_HEIGHT;
448                 break;
449             case Surface.ROTATION_270:
450                 gravity = Gravity.LEFT;
451                 width = NAV_BAR_HEIGHT;
452                 break;
453         }
454         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
455                 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR);
456         lp.width = width;
457         lp.height = height;
458         lp.gravity = gravity;
459         lp.setFitInsetsTypes(0);
460         lp.privateFlags |=
461                 WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
462         lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
463         lp.providedInsets = new InsetsFrameProvider[] {
464                 new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars()),
465                 new InsetsFrameProvider(owner, 0, WindowInsets.Type.tappableElement()),
466                 new InsetsFrameProvider(owner, 0, WindowInsets.Type.mandatorySystemGestures())
467         };
468         return lp;
469     }
470 
beforeCreateTestDisplay()471     void beforeCreateTestDisplay() {
472         // Called before display is created.
473     }
474 
475     /** Avoid writing values to real Settings. */
useFakeSettingsProvider()476     ContentResolver useFakeSettingsProvider() {
477         mUseFakeSettingsProvider = true;
478         FakeSettingsProvider.clearSettingsProvider();
479         final FakeSettingsProvider provider = new FakeSettingsProvider();
480         // SystemServicesTestRule#setUpSystemCore has called spyOn for the ContentResolver.
481         final ContentResolver resolver = mContext.getContentResolver();
482         doReturn(provider.getIContentProvider()).when(resolver).acquireProvider(Settings.AUTHORITY);
483         return resolver;
484     }
485 
createCommonWindow(WindowState parent, int type, String name)486     private WindowState createCommonWindow(WindowState parent, int type, String name) {
487         final WindowState win = createWindow(parent, type, name);
488         // Prevent common windows from been IME targets.
489         win.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
490         return win;
491     }
492 
createWindowToken( DisplayContent dc, int windowingMode, int activityType, int type)493     private WindowToken createWindowToken(
494             DisplayContent dc, int windowingMode, int activityType, int type) {
495         if (type == TYPE_WALLPAPER) {
496             return createWallpaperToken(dc);
497         }
498         if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
499             return createTestWindowToken(type, dc);
500         }
501 
502         return createActivityRecord(dc, windowingMode, activityType);
503     }
504 
createWallpaperToken(DisplayContent dc)505     private WindowToken createWallpaperToken(DisplayContent dc) {
506         return new WallpaperWindowToken(mWm, mock(IBinder.class), true /* explicit */, dc,
507                 true /* ownerCanManageAppTokens */);
508     }
509 
createNavBarWithProvidedInsets(DisplayContent dc)510     WindowState createNavBarWithProvidedInsets(DisplayContent dc) {
511         final WindowState navbar = createWindow(null, TYPE_NAVIGATION_BAR, dc, "navbar");
512         final Binder owner = new Binder();
513         navbar.mAttrs.providedInsets = new InsetsFrameProvider[] {
514                 new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars())
515                         .setInsetsSize(Insets.of(0, 0, 0, NAV_BAR_HEIGHT))
516         };
517         dc.getDisplayPolicy().addWindowLw(navbar, navbar.mAttrs);
518         return navbar;
519     }
520 
createStatusBarWithProvidedInsets(DisplayContent dc)521     WindowState createStatusBarWithProvidedInsets(DisplayContent dc) {
522         final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, dc, "statusBar");
523         final Binder owner = new Binder();
524         statusBar.mAttrs.providedInsets = new InsetsFrameProvider[] {
525                 new InsetsFrameProvider(owner, 0, WindowInsets.Type.statusBars())
526                         .setInsetsSize(Insets.of(0, STATUS_BAR_HEIGHT, 0, 0))
527         };
528         statusBar.mAttrs.setFitInsetsTypes(0);
529         dc.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
530         return statusBar;
531     }
532 
getTestSession()533     Session getTestSession() {
534         if (mTestSession != null) {
535             return mTestSession;
536         }
537         mTestSession = createTestSession(mAtm);
538         return mTestSession;
539     }
540 
getTestSession(WindowToken token)541     private Session getTestSession(WindowToken token) {
542         final ActivityRecord r = token.asActivityRecord();
543         if (r == null || r.app == null) {
544             return getTestSession();
545         }
546         // If the activity has a process, let the window session belonging to activity use the
547         // process of the activity.
548         int pid = r.app.getPid();
549         if (pid == 0) {
550             // See SystemServicesTestRule#addProcess, pid 0 isn't added to the map. So generate
551             // a non-zero pid to initialize it.
552             final int numPid = mAtm.mProcessMap.getPidMap().size();
553             pid = numPid > 0 ? mAtm.mProcessMap.getPidMap().keyAt(numPid - 1) + 1 : 1;
554             r.app.setPid(pid);
555             mAtm.mProcessMap.put(pid, r.app);
556         } else {
557             final WindowState win = mRootWindowContainer.getWindow(w -> w.getProcess() == r.app);
558             if (win != null) {
559                 // Reuse the same Session if there is a window uses the same process.
560                 return win.mSession;
561             }
562         }
563         return createTestSession(mAtm, pid, r.getUid());
564     }
565 
createTestSession(ActivityTaskManagerService atms)566     static Session createTestSession(ActivityTaskManagerService atms) {
567         return createTestSession(atms, WindowManagerService.MY_PID, WindowManagerService.MY_UID);
568     }
569 
createTestSession(ActivityTaskManagerService atms, int pid, int uid)570     static Session createTestSession(ActivityTaskManagerService atms, int pid, int uid) {
571         if (atms.mProcessMap.getProcess(pid) == null) {
572             SystemServicesTestRule.addProcess(atms, "testPkg", "testProc", pid, uid);
573         }
574         return new Session(atms.mWindowManager, new IWindowSessionCallback.Stub() {
575             @Override
576             public void onAnimatorScaleChanged(float scale) {
577             }
578         }, pid, uid);
579     }
580 
createAppWindow(Task task, int type, String name)581     WindowState createAppWindow(Task task, int type, String name) {
582         final ActivityRecord activity = createNonAttachedActivityRecord(task.getDisplayContent());
583         task.addChild(activity, 0);
584         return createWindow(null, type, activity, name);
585     }
586 
createDreamWindow(WindowState parent, int type, String name)587     WindowState createDreamWindow(WindowState parent, int type, String name) {
588         final WindowToken token = createWindowToken(
589                 mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, type);
590         return createWindow(parent, type, token, name);
591     }
592 
593     // TODO: Move these calls to a builder?
createWindow(WindowState parent, int type, DisplayContent dc, String name, IWindow iwindow)594     WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
595             IWindow iwindow) {
596         final WindowToken token = createWindowToken(
597                 dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
598         return createWindow(parent, type, token, name, 0 /* ownerId */,
599                 false /* ownerCanAddInternalSystemWindow */, iwindow);
600     }
601 
createWindow(WindowState parent, int type, String name)602     WindowState createWindow(WindowState parent, int type, String name) {
603         return (parent == null)
604                 ? createWindow(parent, type, mDisplayContent, name)
605                 : createWindow(parent, type, parent.mToken, name);
606     }
607 
createWindow(WindowState parent, int type, String name, int ownerId)608     WindowState createWindow(WindowState parent, int type, String name, int ownerId) {
609         return (parent == null)
610                 ? createWindow(parent, type, mDisplayContent, name, ownerId)
611                 : createWindow(parent, type, parent.mToken, name, ownerId);
612     }
613 
createWindow(WindowState parent, int windowingMode, int activityType, int type, DisplayContent dc, String name)614     WindowState createWindow(WindowState parent, int windowingMode, int activityType,
615             int type, DisplayContent dc, String name) {
616         final WindowToken token = createWindowToken(dc, windowingMode, activityType, type);
617         return createWindow(parent, type, token, name);
618     }
619 
createWindow(WindowState parent, int type, DisplayContent dc, String name)620     WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
621         return createWindow(
622                 parent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type, dc, name);
623     }
624 
createWindow(WindowState parent, int type, DisplayContent dc, String name, int ownerId)625     WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
626             int ownerId) {
627         final WindowToken token = createWindowToken(
628                 dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
629         return createWindow(parent, type, token, name, ownerId);
630     }
631 
createWindow(WindowState parent, int type, DisplayContent dc, String name, boolean ownerCanAddInternalSystemWindow)632     WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
633             boolean ownerCanAddInternalSystemWindow) {
634         final WindowToken token = createWindowToken(
635                 dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
636         return createWindow(parent, type, token, name, 0 /* ownerId */,
637                 ownerCanAddInternalSystemWindow);
638     }
639 
createWindow(WindowState parent, int type, WindowToken token, String name)640     WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
641         return createWindow(parent, type, token, name, 0 /* ownerId */,
642                 false /* ownerCanAddInternalSystemWindow */);
643     }
644 
createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId)645     WindowState createWindow(WindowState parent, int type, WindowToken token, String name,
646             int ownerId) {
647         return createWindow(parent, type, token, name, ownerId,
648                 false /* ownerCanAddInternalSystemWindow */);
649     }
650 
createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId, boolean ownerCanAddInternalSystemWindow)651     WindowState createWindow(WindowState parent, int type, WindowToken token, String name,
652             int ownerId, boolean ownerCanAddInternalSystemWindow) {
653         return createWindow(parent, type, token, name, ownerId, ownerCanAddInternalSystemWindow,
654                 mIWindow);
655     }
656 
createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId, boolean ownerCanAddInternalSystemWindow, IWindow iwindow)657     WindowState createWindow(WindowState parent, int type, WindowToken token, String name,
658             int ownerId, boolean ownerCanAddInternalSystemWindow, IWindow iwindow) {
659         return createWindow(parent, type, token, name, ownerId, UserHandle.getUserId(ownerId),
660                 ownerCanAddInternalSystemWindow, mWm, getTestSession(token), iwindow);
661     }
662 
createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId, int userId, boolean ownerCanAddInternalSystemWindow, WindowManagerService service, Session session, IWindow iWindow)663     static WindowState createWindow(WindowState parent, int type, WindowToken token,
664             String name, int ownerId, int userId, boolean ownerCanAddInternalSystemWindow,
665             WindowManagerService service, Session session, IWindow iWindow) {
666         SystemServicesTestRule.checkHoldsLock(service.mGlobalLock);
667 
668         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
669         attrs.setTitle(name);
670         attrs.packageName = "test";
671 
672         final WindowState w = new WindowState(service, session, iWindow, token, parent,
673                 OP_NONE, attrs, VISIBLE, ownerId, userId, ownerCanAddInternalSystemWindow);
674         // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
675         // adding it to the token...
676         token.addWindow(w);
677         return w;
678     }
679 
makeWindowVisible(WindowState... windows)680     static void makeWindowVisible(WindowState... windows) {
681         for (WindowState win : windows) {
682             win.mViewVisibility = View.VISIBLE;
683             win.mRelayoutCalled = true;
684             win.mHasSurface = true;
685             win.mHidden = false;
686             win.show(false /* doAnimation */, false /* requestAnim */);
687         }
688     }
689 
makeWindowVisibleAndDrawn(WindowState... windows)690     static void makeWindowVisibleAndDrawn(WindowState... windows) {
691         makeWindowVisible(windows);
692         for (WindowState win : windows) {
693             win.mWinAnimator.mDrawState = HAS_DRAWN;
694         }
695     }
696 
makeWindowVisibleAndNotDrawn(WindowState... windows)697     static void makeWindowVisibleAndNotDrawn(WindowState... windows) {
698         makeWindowVisible(windows);
699         for (WindowState win : windows) {
700             win.mWinAnimator.mDrawState = DRAW_PENDING;
701         }
702     }
703 
makeLastConfigReportedToClient(WindowState w, boolean visible)704     static void makeLastConfigReportedToClient(WindowState w, boolean visible) {
705         w.fillClientWindowFramesAndConfiguration(new ClientWindowFrames(),
706                 new MergedConfiguration(), new ActivityWindowInfo(), true /* useLatestConfig */,
707                 visible);
708     }
709 
710     /**
711      * Gets the order of the given {@link Task} as its z-order in the hierarchy below this TDA.
712      * The Task can be a direct child of a child TaskDisplayArea. {@code -1} if not found.
713      */
getTaskIndexOf(TaskDisplayArea taskDisplayArea, Task task)714     static int getTaskIndexOf(TaskDisplayArea taskDisplayArea, Task task) {
715         int index = 0;
716         final int childCount = taskDisplayArea.getChildCount();
717         for (int i = 0; i < childCount; i++) {
718             final WindowContainer wc = taskDisplayArea.getChildAt(i);
719             if (wc.asTask() != null) {
720                 if (wc.asTask() == task) {
721                     return index;
722                 }
723                 index++;
724             } else {
725                 final TaskDisplayArea tda = wc.asTaskDisplayArea();
726                 final int subIndex = getTaskIndexOf(tda, task);
727                 if (subIndex > -1) {
728                     return index + subIndex;
729                 } else {
730                     index += tda.getRootTaskCount();
731                 }
732             }
733         }
734         return -1;
735     }
736 
737     /** Creates a {@link TaskDisplayArea} right above the default one. */
createTaskDisplayArea(DisplayContent displayContent, WindowManagerService service, String name, int displayAreaFeature)738     static TaskDisplayArea createTaskDisplayArea(DisplayContent displayContent,
739             WindowManagerService service, String name, int displayAreaFeature) {
740         final TaskDisplayArea newTaskDisplayArea = new TaskDisplayArea(
741                 displayContent, service, name, displayAreaFeature);
742         final TaskDisplayArea defaultTaskDisplayArea = displayContent.getDefaultTaskDisplayArea();
743 
744         // Insert the new TDA to the correct position.
745         defaultTaskDisplayArea.getParent().addChild(newTaskDisplayArea,
746                 defaultTaskDisplayArea.getParent().mChildren.indexOf(defaultTaskDisplayArea)
747                         + 1);
748         return newTaskDisplayArea;
749     }
750 
751     /**
752      *  Creates a {@link Task} with a simple {@link ActivityRecord} and adds to the given
753      *  {@link TaskDisplayArea}.
754      */
createTaskWithActivity(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop, boolean twoLevelTask)755     Task createTaskWithActivity(TaskDisplayArea taskDisplayArea,
756             int windowingMode, int activityType, boolean onTop, boolean twoLevelTask) {
757         return createTask(taskDisplayArea, windowingMode, activityType,
758                 onTop, true /* createActivity */, twoLevelTask);
759     }
760 
761     /** Creates a {@link Task} and adds to the given {@link DisplayContent}. */
createTask(DisplayContent dc)762     Task createTask(DisplayContent dc) {
763         return createTask(dc.getDefaultTaskDisplayArea(),
764                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
765     }
766 
createTask(DisplayContent dc, int windowingMode, int activityType)767     Task createTask(DisplayContent dc, int windowingMode, int activityType) {
768         return createTask(dc.getDefaultTaskDisplayArea(), windowingMode, activityType);
769     }
770 
createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType)771     Task createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType) {
772         return createTask(taskDisplayArea, windowingMode, activityType,
773                 true /* onTop */, false /* createActivity */, false /* twoLevelTask */);
774     }
775 
776     /** Creates a {@link Task} and adds to the given {@link TaskDisplayArea}. */
createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop, boolean createActivity, boolean twoLevelTask)777     Task createTask(TaskDisplayArea taskDisplayArea, int windowingMode, int activityType,
778             boolean onTop, boolean createActivity, boolean twoLevelTask) {
779         final TaskBuilder builder = new TaskBuilder(mSupervisor)
780                 .setTaskDisplayArea(taskDisplayArea)
781                 .setWindowingMode(windowingMode)
782                 .setActivityType(activityType)
783                 .setOnTop(onTop)
784                 .setCreateActivity(createActivity);
785         if (twoLevelTask) {
786             return builder
787                     .setCreateParentTask(true)
788                     .build()
789                     .getRootTask();
790         } else {
791             return builder.build();
792         }
793     }
794 
795     /** Creates a {@link Task} and adds to the given root {@link Task}. */
createTaskInRootTask(Task rootTask, int userId)796     Task createTaskInRootTask(Task rootTask, int userId) {
797         final Task task = new TaskBuilder(rootTask.mTaskSupervisor)
798                 .setUserId(userId)
799                 .setParentTask(rootTask)
800                 .build();
801         return task;
802     }
803 
804     /** Creates an {@link ActivityRecord}. */
createNonAttachedActivityRecord(DisplayContent dc)805     static ActivityRecord createNonAttachedActivityRecord(DisplayContent dc) {
806         final ActivityRecord activity = new ActivityBuilder(dc.mWmService.mAtmService)
807                 .setOnTop(true)
808                 .build();
809         postCreateActivitySetup(activity, dc);
810         return activity;
811     }
812 
813     /**
814      * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
815      * [Task] - [ActivityRecord]
816      */
createActivityRecord(DisplayContent dc)817     ActivityRecord createActivityRecord(DisplayContent dc) {
818         return createActivityRecord(dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
819     }
820 
821     /**
822      * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
823      * [Task] - [ActivityRecord]
824      */
createActivityRecord(DisplayContent dc, int windowingMode, int activityType)825     ActivityRecord createActivityRecord(DisplayContent dc, int windowingMode,
826             int activityType) {
827         final Task task = createTask(dc, windowingMode, activityType);
828         return createActivityRecord(dc, task);
829     }
830 
831     /**
832      *  Creates an {@link ActivityRecord} and adds it to the specified {@link Task}.
833      * [Task] - [ActivityRecord]
834      */
createActivityRecord(Task task)835     static ActivityRecord createActivityRecord(Task task) {
836         return createActivityRecord(task.getDisplayContent(), task);
837     }
838 
839     /**
840      * Creates an {@link ActivityRecord} and adds it to the specified {@link Task}.
841      * [Task] - [ActivityRecord]
842      */
createActivityRecord(DisplayContent dc, Task task)843     static ActivityRecord createActivityRecord(DisplayContent dc, Task task) {
844         final ActivityRecord activity = new ActivityBuilder(dc.mWmService.mAtmService)
845                 .setTask(task)
846                 .setOnTop(true)
847                 .build();
848         postCreateActivitySetup(activity, dc);
849         return activity;
850     }
851 
852     /**
853      * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
854      * Then adds the new created {@link Task} to a new created parent {@link Task}
855      * [Task1] - [Task2] - [ActivityRecord]
856      */
createActivityRecordWithParentTask(DisplayContent dc, int windowingMode, int activityType)857     ActivityRecord createActivityRecordWithParentTask(DisplayContent dc, int windowingMode,
858             int activityType) {
859         final Task task = createTask(dc, windowingMode, activityType);
860         return createActivityRecordWithParentTask(task);
861     }
862 
863     /**
864      * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
865      * Then adds the new created {@link Task} to the specified parent {@link Task}
866      * [Task1] - [Task2] - [ActivityRecord]
867      */
createActivityRecordWithParentTask(Task parentTask)868     static ActivityRecord createActivityRecordWithParentTask(Task parentTask) {
869         final ActivityRecord activity = new ActivityBuilder(parentTask.mAtmService)
870                 .setParentTask(parentTask)
871                 .setCreateTask(true)
872                 .setOnTop(true)
873                 .build();
874         postCreateActivitySetup(activity, parentTask.getDisplayContent());
875         return activity;
876     }
877 
postCreateActivitySetup(ActivityRecord activity, DisplayContent dc)878     private static void postCreateActivitySetup(ActivityRecord activity, DisplayContent dc) {
879         activity.onDisplayChanged(dc);
880         activity.setOccludesParent(true);
881         activity.setVisible(true);
882         activity.setVisibleRequested(true);
883     }
884 
885     /**
886      * Creates a {@link TaskFragment} with {@link ActivityRecord}, and attaches it to the
887      * {@code parentTask}.
888      *
889      * @param parentTask the {@link Task} this {@link TaskFragment} is going to be attached.
890      * @return the created {@link TaskFragment}
891      */
createTaskFragmentWithActivity(@onNull Task parentTask)892     static TaskFragment createTaskFragmentWithActivity(@NonNull Task parentTask) {
893         return new TaskFragmentBuilder(parentTask.mAtmService)
894                 .setParentTask(parentTask)
895                 .createActivityCount(1)
896                 .build();
897     }
898 
899     /**
900      * Creates an embedded {@link TaskFragment} organized by {@code organizer} with
901      * {@link ActivityRecord}, and attaches it to the {@code parentTask}.
902      *
903      * @param parentTask the {@link Task} this {@link TaskFragment} is going to be attached.
904      * @param organizer  the {@link TaskFragmentOrganizer} this {@link TaskFragment} is going to be
905      *                   organized by.
906      * @return the created {@link TaskFragment}
907      */
createTaskFragmentWithEmbeddedActivity(@onNull Task parentTask, @NonNull TaskFragmentOrganizer organizer)908     static TaskFragment createTaskFragmentWithEmbeddedActivity(@NonNull Task parentTask,
909             @NonNull TaskFragmentOrganizer organizer) {
910         final IBinder fragmentToken = new Binder();
911         final TaskFragment taskFragment = new TaskFragmentBuilder(parentTask.mAtmService)
912                 .setParentTask(parentTask)
913                 .createActivityCount(1)
914                 .setOrganizer(organizer)
915                 .setFragmentToken(fragmentToken)
916                 .build();
917         parentTask.mAtmService.mWindowOrganizerController.mLaunchTaskFragments
918                 .put(fragmentToken, taskFragment);
919         return taskFragment;
920     }
921 
922     /** @see TaskFragmentOrganizerController#registerOrganizer */
registerTaskFragmentOrganizer(@onNull ITaskFragmentOrganizer organizer)923     void registerTaskFragmentOrganizer(@NonNull ITaskFragmentOrganizer organizer) {
924         registerTaskFragmentOrganizer(organizer, false /* isSystemOrganizer */);
925     }
926 
927     /** @see TaskFragmentOrganizerController#registerOrganizer */
registerTaskFragmentOrganizer(@onNull ITaskFragmentOrganizer organizer, boolean isSystemOrganizer)928     void registerTaskFragmentOrganizer(@NonNull ITaskFragmentOrganizer organizer,
929             boolean isSystemOrganizer) {
930         // Ensure there is an IApplicationThread to dispatch TaskFragmentTransaction.
931         if (mAtm.mProcessMap.getProcess(WindowManagerService.MY_PID) == null) {
932             mSystemServicesTestRule.addProcess("pkgName", "procName",
933                     WindowManagerService.MY_PID, WindowManagerService.MY_UID);
934         }
935         mAtm.mTaskFragmentOrganizerController.registerOrganizer(organizer, isSystemOrganizer,
936                 new Bundle());
937     }
938 
939     /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
createNewDisplay()940     DisplayContent createNewDisplay() {
941         return createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL);
942     }
943 
944     /** Creates a {@link DisplayContent} and adds it to the system. */
createNewDisplayWithImeSupport(@isplayImePolicy int imePolicy)945     private DisplayContent createNewDisplayWithImeSupport(@DisplayImePolicy int imePolicy) {
946         return createNewDisplay(mDisplayInfo, imePolicy, /* overrideSettings */ null);
947     }
948 
949     /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
createNewDisplay(DisplayInfo info)950     DisplayContent createNewDisplay(DisplayInfo info) {
951         return createNewDisplay(info, DISPLAY_IME_POLICY_LOCAL, /* overrideSettings */ null);
952     }
953 
954     /** Creates a {@link DisplayContent} and adds it to the system. */
createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy, @Nullable SettingsEntry overrideSettings)955     private DisplayContent createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy,
956             @Nullable SettingsEntry overrideSettings) {
957         final DisplayContent display =
958                 new TestDisplayContent.Builder(mAtm, info)
959                         .setOverrideSettings(overrideSettings)
960                         .build();
961         final DisplayContent dc = display.mDisplayContent;
962         // this display can show IME.
963         dc.mWmService.mDisplayWindowSettings.setDisplayImePolicy(dc, imePolicy);
964         return dc;
965     }
966 
967     /**
968      * Creates a {@link DisplayContent} with given display state and adds it to the system.
969      *
970      * @param displayState For initializing the state of the display. See
971      *                     {@link Display#getState()}.
972      */
createNewDisplay(int displayState)973     DisplayContent createNewDisplay(int displayState) {
974         // Leverage main display info & initialize it with display state for given displayId.
975         DisplayInfo displayInfo = new DisplayInfo();
976         displayInfo.copyFrom(mDisplayInfo);
977         displayInfo.state = displayState;
978         return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_LOCAL, /* overrideSettings */ null);
979     }
980 
981     /** Creates a {@link TestWindowState} */
createWindowState(WindowManager.LayoutParams attrs, WindowToken token)982     TestWindowState createWindowState(WindowManager.LayoutParams attrs, WindowToken token) {
983         SystemServicesTestRule.checkHoldsLock(mWm.mGlobalLock);
984 
985         return new TestWindowState(mWm, getTestSession(), mIWindow, attrs, token);
986     }
987 
988     /** Creates a {@link DisplayContent} as parts of simulate display info for test. */
createMockSimulatedDisplay()989     DisplayContent createMockSimulatedDisplay() {
990         return createMockSimulatedDisplay(/* overrideSettings */ null);
991     }
992 
createMockSimulatedDisplay(@ullable SettingsEntry overrideSettings)993     DisplayContent createMockSimulatedDisplay(@Nullable SettingsEntry overrideSettings) {
994         DisplayInfo displayInfo = new DisplayInfo();
995         displayInfo.copyFrom(mDisplayInfo);
996         displayInfo.type = Display.TYPE_VIRTUAL;
997         displayInfo.state = Display.STATE_ON;
998         displayInfo.ownerUid = SYSTEM_UID;
999         return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_FALLBACK_DISPLAY, overrideSettings);
1000     }
1001 
createDisplayWindowInsetsController()1002     IDisplayWindowInsetsController createDisplayWindowInsetsController() {
1003         return new IDisplayWindowInsetsController.Stub() {
1004 
1005             @Override
1006             public void insetsChanged(InsetsState insetsState) throws RemoteException {
1007             }
1008 
1009             @Override
1010             public void insetsControlChanged(InsetsState insetsState,
1011                     InsetsSourceControl[] insetsSourceControls) throws RemoteException {
1012             }
1013 
1014             @Override
1015             public void showInsets(int i, boolean b, @Nullable ImeTracker.Token t)
1016                     throws RemoteException {
1017             }
1018 
1019             @Override
1020             public void hideInsets(int i, boolean b, @Nullable ImeTracker.Token t)
1021                     throws RemoteException {
1022             }
1023 
1024             @Override
1025             public void topFocusedWindowChanged(ComponentName component,
1026                     int requestedVisibleTypes) {
1027             }
1028 
1029             @Override
1030             public void setImeInputTargetRequestedVisibility(boolean visible,
1031                     @NonNull ImeTracker.Token statsToken) {
1032             }
1033         };
1034     }
1035 
createTestBLASTSyncEngine()1036     BLASTSyncEngine createTestBLASTSyncEngine() {
1037         return createTestBLASTSyncEngine(mWm.mH);
1038     }
1039 
createTestBLASTSyncEngine(Handler handler)1040     BLASTSyncEngine createTestBLASTSyncEngine(Handler handler) {
1041         return new BLASTSyncEngine(mWm, handler) {
1042             @Override
1043             void scheduleTimeout(SyncGroup s, long timeoutMs) {
1044                 // Disable timeout.
1045             }
1046         };
1047     }
1048 
1049     /** Sets up a simple implementation of transition player for shell transitions. */
registerTestTransitionPlayer()1050     TestTransitionPlayer registerTestTransitionPlayer() {
1051         final TestTransitionPlayer testPlayer = new TestTransitionPlayer(
1052                 mAtm.getTransitionController(), mAtm.mWindowOrganizerController);
1053         testPlayer.mController.registerTransitionPlayer(testPlayer, null /* playerProc */);
1054         return testPlayer;
1055     }
1056 
1057     /** Overrides the behavior of config_reverseDefaultRotation for the given display. */
setReverseDefaultRotation(DisplayContent dc, boolean reverse)1058     void setReverseDefaultRotation(DisplayContent dc, boolean reverse) {
1059         final DisplayRotation displayRotation = dc.getDisplayRotation();
1060         if (!Mockito.mockingDetails(displayRotation).isSpy()) {
1061             spyOn(displayRotation);
1062         }
1063         doAnswer(invocation -> {
1064             invocation.callRealMethod();
1065             final int w = invocation.getArgument(0);
1066             final int h = invocation.getArgument(1);
1067             if (w > h) {
1068                 if (reverse) {
1069                     displayRotation.mPortraitRotation = Surface.ROTATION_90;
1070                     displayRotation.mUpsideDownRotation = Surface.ROTATION_270;
1071                 } else {
1072                     displayRotation.mPortraitRotation = Surface.ROTATION_270;
1073                     displayRotation.mUpsideDownRotation = Surface.ROTATION_90;
1074                 }
1075             } else {
1076                 if (reverse) {
1077                     displayRotation.mLandscapeRotation = Surface.ROTATION_270;
1078                     displayRotation.mSeascapeRotation = Surface.ROTATION_90;
1079                 } else {
1080                     displayRotation.mLandscapeRotation = Surface.ROTATION_90;
1081                     displayRotation.mSeascapeRotation = Surface.ROTATION_270;
1082                 }
1083             }
1084             return null;
1085         }).when(displayRotation).configure(anyInt(), anyInt());
1086         displayRotation.configure(dc.mBaseDisplayWidth, dc.mBaseDisplayHeight);
1087     }
1088 
1089     /**
1090      * Performs surface placement and waits for WindowAnimator to complete the frame. It is used
1091      * to execute the callbacks if the surface placement is expected to add some callbacks via
1092      * {@link WindowAnimator#addAfterPrepareSurfacesRunnable}.
1093      */
performSurfacePlacementAndWaitForWindowAnimator()1094     void performSurfacePlacementAndWaitForWindowAnimator() {
1095         mWm.mAnimator.ready();
1096         if (!mWm.mWindowPlacerLocked.isTraversalScheduled()) {
1097             mRootWindowContainer.performSurfacePlacement();
1098         } else {
1099             waitHandlerIdle(mWm.mAnimationHandler);
1100         }
1101         waitUntilWindowAnimatorIdle();
1102     }
1103 
1104     /**
1105      * Avoids rotating screen disturbed by some conditions. It is usually used for the default
1106      * display that is not the instance of {@link TestDisplayContent} (it bypasses the conditions).
1107      *
1108      * @see DisplayRotation#updateRotationUnchecked
1109      */
unblockDisplayRotation(DisplayContent dc)1110     void unblockDisplayRotation(DisplayContent dc) {
1111         dc.mOpeningApps.clear();
1112         mWm.mAppsFreezingScreen = 0;
1113         mWm.stopFreezingDisplayLocked();
1114         // The rotation animation won't actually play, it needs to be cleared manually.
1115         dc.setRotationAnimation(null);
1116     }
1117 
resizeDisplay(DisplayContent displayContent, int width, int height)1118     static void resizeDisplay(DisplayContent displayContent, int width, int height) {
1119         displayContent.updateBaseDisplayMetrics(width, height, displayContent.mBaseDisplayDensity,
1120                 displayContent.mBaseDisplayPhysicalXDpi, displayContent.mBaseDisplayPhysicalYDpi);
1121         displayContent.getDisplayRotation().configure(width, height);
1122         final Configuration c = new Configuration();
1123         displayContent.computeScreenConfiguration(c);
1124         displayContent.onRequestedOverrideConfigurationChanged(c);
1125     }
1126 
makeDisplayLargeScreen(DisplayContent displayContent)1127     static void makeDisplayLargeScreen(DisplayContent displayContent) {
1128         final int swDp = displayContent.getConfiguration().smallestScreenWidthDp;
1129         if (swDp < WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP) {
1130             final int height = 100 + (int) (displayContent.getDisplayMetrics().density
1131                     * WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP);
1132             resizeDisplay(displayContent, 100 + height, height);
1133         }
1134     }
1135 
1136     /** Used for the tests that assume the display is portrait by default. */
makeDisplayPortrait(DisplayContent displayContent)1137     static void makeDisplayPortrait(DisplayContent displayContent) {
1138         if (displayContent.mBaseDisplayHeight <= displayContent.mBaseDisplayWidth) {
1139             resizeDisplay(displayContent, 500, 1000);
1140         }
1141     }
1142 
1143     // The window definition for UseTestDisplay#addWindows. The test can declare to add only
1144     // necessary windows, that avoids adding unnecessary overhead of unused windows.
1145     static final int W_NOTIFICATION_SHADE = TYPE_NOTIFICATION_SHADE;
1146     static final int W_STATUS_BAR = TYPE_STATUS_BAR;
1147     static final int W_NAVIGATION_BAR = TYPE_NAVIGATION_BAR;
1148     static final int W_INPUT_METHOD_DIALOG = TYPE_INPUT_METHOD_DIALOG;
1149     static final int W_INPUT_METHOD = TYPE_INPUT_METHOD;
1150     static final int W_DOCK_DIVIDER = TYPE_DOCK_DIVIDER;
1151     static final int W_ABOVE_ACTIVITY = TYPE_APPLICATION_ATTACHED_DIALOG;
1152     static final int W_ACTIVITY = TYPE_BASE_APPLICATION;
1153     static final int W_BELOW_ACTIVITY = TYPE_APPLICATION_MEDIA_OVERLAY;
1154     static final int W_WALLPAPER = TYPE_WALLPAPER;
1155 
1156     /** The common window types supported by {@link UseTestDisplay}. */
1157     @Retention(RetentionPolicy.RUNTIME)
1158     @IntDef(value = {
1159             W_NOTIFICATION_SHADE,
1160             W_STATUS_BAR,
1161             W_NAVIGATION_BAR,
1162             W_INPUT_METHOD_DIALOG,
1163             W_INPUT_METHOD,
1164             W_DOCK_DIVIDER,
1165             W_ABOVE_ACTIVITY,
1166             W_ACTIVITY,
1167             W_BELOW_ACTIVITY,
1168             W_WALLPAPER,
1169     })
1170     @interface CommonTypes {
1171     }
1172 
1173     /**
1174      * The annotation to provide common windows on default display. This is mutually exclusive
1175      * with {@link UseTestDisplay}.
1176      */
1177     @Target({ ElementType.METHOD, ElementType.TYPE })
1178     @Retention(RetentionPolicy.RUNTIME)
1179     @interface SetupWindows {
addAllCommonWindows()1180         boolean addAllCommonWindows() default false;
addWindows()1181         @CommonTypes int[] addWindows() default {};
1182     }
1183 
1184     /**
1185      * The annotation for class and method (higher priority) to create a non-default display that
1186      * will be assigned to {@link #mDisplayContent}. It is used if the test needs
1187      * <ul>
1188      * <li>Pure empty display.</li>
1189      * <li>Independent and customizable orientation.</li>
1190      * <li>Cross display operation.</li>
1191      * </ul>
1192      *
1193      * @see TestDisplayContent
1194      * @see #createTestDisplay
1195      **/
1196     @Target({ ElementType.METHOD, ElementType.TYPE })
1197     @Retention(RetentionPolicy.RUNTIME)
1198     @interface UseTestDisplay {
addAllCommonWindows()1199         boolean addAllCommonWindows() default false;
addWindows()1200         @CommonTypes int[] addWindows() default {};
1201     }
1202 
getAnnotation(Description desc, Class<T> type)1203     static <T extends Annotation> T getAnnotation(Description desc, Class<T> type) {
1204         final T annotation = desc.getAnnotation(type);
1205         if (annotation != null) return annotation;
1206         return desc.getTestClass().getAnnotation(type);
1207     }
1208 
1209     /** Creates and adds a {@link TestDisplayContent} to supervisor at the given position. */
addNewDisplayContentAt(int position)1210     TestDisplayContent addNewDisplayContentAt(int position) {
1211         return new TestDisplayContent.Builder(mAtm, 1000, 1500).setPosition(position).build();
1212     }
1213 
1214     /** Sets the default minimum task size to 1 so that tests can use small task sizes */
removeGlobalMinSizeRestriction()1215     public void removeGlobalMinSizeRestriction() {
1216         mAtm.mRootWindowContainer.forAllDisplays(
1217                 displayContent -> displayContent.mMinSizeOfResizeableTaskDp = 1);
1218     }
1219 
1220     /** Mocks the behavior of taking a snapshot. */
mockSurfaceFreezerSnapshot(SurfaceFreezer surfaceFreezer)1221     void mockSurfaceFreezerSnapshot(SurfaceFreezer surfaceFreezer) {
1222         final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
1223                 mock(ScreenCapture.ScreenshotHardwareBuffer.class);
1224         final HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class);
1225         spyOn(surfaceFreezer);
1226         doReturn(screenshotBuffer).when(surfaceFreezer)
1227                 .createSnapshotBufferInner(any(), any());
1228         doReturn(null).when(surfaceFreezer)
1229                 .createFromHardwareBufferInner(any());
1230         doReturn(hardwareBuffer).when(screenshotBuffer).getHardwareBuffer();
1231         doReturn(100).when(hardwareBuffer).getWidth();
1232         doReturn(100).when(hardwareBuffer).getHeight();
1233     }
1234 
getUniqueComponentName()1235     static ComponentName getUniqueComponentName() {
1236         return getUniqueComponentName(DEFAULT_COMPONENT_PACKAGE_NAME);
1237     }
1238 
getUniqueComponentName(String packageName)1239     static ComponentName getUniqueComponentName(String packageName) {
1240         if (packageName == null) {
1241             packageName = DEFAULT_COMPONENT_PACKAGE_NAME;
1242         }
1243         return ComponentName.createRelative(packageName,
1244                 DEFAULT_COMPONENT_CLASS_NAME + sCurrentActivityId++);
1245     }
1246 
1247     /**
1248      * Builder for creating new activities.
1249      */
1250     protected static class ActivityBuilder {
1251         static final int DEFAULT_FAKE_UID = 12345;
1252         static final String DEFAULT_PROCESS_NAME = "procName";
1253         static int sProcNameSeq;
1254 
1255         private final ActivityTaskManagerService mService;
1256 
1257         private ComponentName mComponent;
1258         private String mTargetActivity;
1259         private Task mTask;
1260         private String mProcessName = DEFAULT_PROCESS_NAME;
1261         private String mAffinity;
1262         private int mUid = DEFAULT_FAKE_UID;
1263         private boolean mCreateTask = false;
1264         private Task mParentTask;
1265         private int mActivityFlags;
1266         private int mActivityTheme;
1267         private int mLaunchMode;
1268         private int mResizeMode = RESIZE_MODE_RESIZEABLE;
1269         private float mMaxAspectRatio;
1270         private float mMinAspectRatio;
1271         private boolean mSupportsSizeChanges;
1272         private int mScreenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
1273         private boolean mLaunchTaskBehind = false;
1274         private int mConfigChanges;
1275         private int mLaunchedFromPid;
1276         private int mLaunchedFromUid;
1277         private String mLaunchedFromPackage;
1278         private WindowProcessController mWpc;
1279         private Bundle mIntentExtras;
1280         private boolean mOnTop = false;
1281         private ActivityInfo.WindowLayout mWindowLayout;
1282         private boolean mVisible = true;
1283         private String mRequiredDisplayCategory;
1284         private ActivityOptions mActivityOpts;
1285 
ActivityBuilder(ActivityTaskManagerService service)1286         ActivityBuilder(ActivityTaskManagerService service) {
1287             mService = service;
1288         }
1289 
setComponent(ComponentName component)1290         ActivityBuilder setComponent(ComponentName component) {
1291             mComponent = component;
1292             return this;
1293         }
1294 
setTargetActivity(String targetActivity)1295         ActivityBuilder setTargetActivity(String targetActivity) {
1296             mTargetActivity = targetActivity;
1297             return this;
1298         }
1299 
setIntentExtras(Bundle extras)1300         ActivityBuilder setIntentExtras(Bundle extras) {
1301             mIntentExtras = extras;
1302             return this;
1303         }
1304 
getDefaultComponent()1305         static ComponentName getDefaultComponent() {
1306             return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
1307                     DEFAULT_COMPONENT_PACKAGE_NAME);
1308         }
1309 
setTask(Task task)1310         ActivityBuilder setTask(Task task) {
1311             mTask = task;
1312             return this;
1313         }
1314 
setActivityTheme(int theme)1315         ActivityBuilder setActivityTheme(int theme) {
1316             mActivityTheme = theme;
1317             // Use the real package of test so it can get a valid context for theme.
1318             mComponent = getUniqueComponentName(mService.mContext.getPackageName());
1319             return this;
1320         }
1321 
setActivityFlags(int flags)1322         ActivityBuilder setActivityFlags(int flags) {
1323             mActivityFlags = flags;
1324             return this;
1325         }
1326 
setLaunchMode(int launchMode)1327         ActivityBuilder setLaunchMode(int launchMode) {
1328             mLaunchMode = launchMode;
1329             return this;
1330         }
1331 
setParentTask(Task parentTask)1332         ActivityBuilder setParentTask(Task parentTask) {
1333             mParentTask = parentTask;
1334             return this;
1335         }
1336 
setCreateTask(boolean createTask)1337         ActivityBuilder setCreateTask(boolean createTask) {
1338             mCreateTask = createTask;
1339             return this;
1340         }
1341 
setProcessName(String name)1342         ActivityBuilder setProcessName(String name) {
1343             mProcessName = name;
1344             return this;
1345         }
1346 
setUid(int uid)1347         ActivityBuilder setUid(int uid) {
1348             mUid = uid;
1349             return this;
1350         }
1351 
setResizeMode(int resizeMode)1352         ActivityBuilder setResizeMode(int resizeMode) {
1353             mResizeMode = resizeMode;
1354             return this;
1355         }
1356 
setMaxAspectRatio(float maxAspectRatio)1357         ActivityBuilder setMaxAspectRatio(float maxAspectRatio) {
1358             mMaxAspectRatio = maxAspectRatio;
1359             return this;
1360         }
1361 
setMinAspectRatio(float minAspectRatio)1362         ActivityBuilder setMinAspectRatio(float minAspectRatio) {
1363             mMinAspectRatio = minAspectRatio;
1364             return this;
1365         }
1366 
setSupportsSizeChanges(boolean supportsSizeChanges)1367         ActivityBuilder setSupportsSizeChanges(boolean supportsSizeChanges) {
1368             mSupportsSizeChanges = supportsSizeChanges;
1369             return this;
1370         }
1371 
setScreenOrientation(int screenOrientation)1372         ActivityBuilder setScreenOrientation(int screenOrientation) {
1373             mScreenOrientation = screenOrientation;
1374             return this;
1375         }
1376 
setLaunchTaskBehind(boolean launchTaskBehind)1377         ActivityBuilder setLaunchTaskBehind(boolean launchTaskBehind) {
1378             mLaunchTaskBehind = launchTaskBehind;
1379             return this;
1380         }
1381 
setConfigChanges(int configChanges)1382         ActivityBuilder setConfigChanges(int configChanges) {
1383             mConfigChanges = configChanges;
1384             return this;
1385         }
1386 
setLaunchedFromPid(int pid)1387         ActivityBuilder setLaunchedFromPid(int pid) {
1388             mLaunchedFromPid = pid;
1389             return this;
1390         }
1391 
setLaunchedFromUid(int uid)1392         ActivityBuilder setLaunchedFromUid(int uid) {
1393             mLaunchedFromUid = uid;
1394             return this;
1395         }
1396 
setLaunchedFromPackage(String packageName)1397         ActivityBuilder setLaunchedFromPackage(String packageName) {
1398             mLaunchedFromPackage = packageName;
1399             return this;
1400         }
1401 
setUseProcess(WindowProcessController wpc)1402         ActivityBuilder setUseProcess(WindowProcessController wpc) {
1403             mWpc = wpc;
1404             return this;
1405         }
1406 
setAffinity(String affinity)1407         ActivityBuilder setAffinity(String affinity) {
1408             mAffinity = affinity;
1409             return this;
1410         }
1411 
setOnTop(boolean onTop)1412         ActivityBuilder setOnTop(boolean onTop) {
1413             mOnTop = onTop;
1414             return this;
1415         }
1416 
setWindowLayout(ActivityInfo.WindowLayout windowLayout)1417         ActivityBuilder setWindowLayout(ActivityInfo.WindowLayout windowLayout) {
1418             mWindowLayout = windowLayout;
1419             return this;
1420         }
1421 
setVisible(boolean visible)1422         ActivityBuilder setVisible(boolean visible) {
1423             mVisible = visible;
1424             return this;
1425         }
1426 
setActivityOptions(ActivityOptions opts)1427         ActivityBuilder setActivityOptions(ActivityOptions opts) {
1428             mActivityOpts = opts;
1429             return this;
1430         }
1431 
setRequiredDisplayCategory(String requiredDisplayCategory)1432         ActivityBuilder setRequiredDisplayCategory(String requiredDisplayCategory) {
1433             mRequiredDisplayCategory = requiredDisplayCategory;
1434             return this;
1435         }
1436 
build()1437         ActivityRecord build() {
1438             SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock);
1439             try {
1440                 mService.deferWindowLayout();
1441                 return buildInner();
1442             } finally {
1443                 mService.continueWindowLayout();
1444             }
1445         }
1446 
buildInner()1447         ActivityRecord buildInner() {
1448             if (mComponent == null) {
1449                 mComponent = getUniqueComponentName();
1450             }
1451 
1452             Intent intent = new Intent();
1453             intent.setComponent(mComponent);
1454             if (mIntentExtras != null) {
1455                 intent.putExtras(mIntentExtras);
1456             }
1457             final ActivityInfo aInfo = new ActivityInfo();
1458             aInfo.applicationInfo = new ApplicationInfo();
1459             aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1460             aInfo.applicationInfo.packageName = mComponent.getPackageName();
1461             aInfo.applicationInfo.uid = mUid;
1462             if (DEFAULT_PROCESS_NAME.equals(mProcessName)) {
1463                 mProcessName += ++sProcNameSeq;
1464             }
1465             aInfo.processName = mProcessName;
1466             aInfo.packageName = mComponent.getPackageName();
1467             aInfo.name = mComponent.getClassName();
1468             if (mTargetActivity != null) {
1469                 aInfo.targetActivity = mTargetActivity;
1470             }
1471             if (mActivityTheme != 0) {
1472                 aInfo.theme = mActivityTheme;
1473             }
1474             aInfo.flags |= mActivityFlags;
1475             aInfo.launchMode = mLaunchMode;
1476             aInfo.resizeMode = mResizeMode;
1477             aInfo.setMaxAspectRatio(mMaxAspectRatio);
1478             aInfo.setMinAspectRatio(mMinAspectRatio);
1479             aInfo.supportsSizeChanges = mSupportsSizeChanges;
1480             aInfo.screenOrientation = mScreenOrientation;
1481             aInfo.configChanges |= mConfigChanges;
1482             aInfo.taskAffinity = mAffinity;
1483             aInfo.windowLayout = mWindowLayout;
1484             if (mRequiredDisplayCategory != null) {
1485                 aInfo.requiredDisplayCategory = mRequiredDisplayCategory;
1486             }
1487 
1488             if (mCreateTask) {
1489                 mTask = new TaskBuilder(mService.mTaskSupervisor)
1490                         .setComponent(mComponent)
1491                         // Apply the root activity info and intent
1492                         .setActivityInfo(aInfo)
1493                         .setIntent(intent)
1494                         .setParentTask(mParentTask).build();
1495             } else if (mTask == null && mParentTask != null && DisplayContent.alwaysCreateRootTask(
1496                     mParentTask.getWindowingMode(), mParentTask.getActivityType())) {
1497                 // The parent task can be the task root.
1498                 mTask = mParentTask;
1499             }
1500 
1501             ActivityOptions options = null;
1502             if (mActivityOpts != null) {
1503                 options = mActivityOpts;
1504             } else if (mLaunchTaskBehind) {
1505                 options = ActivityOptions.makeTaskLaunchBehind();
1506             }
1507             final ActivityRecord activity = new ActivityRecord.Builder(mService)
1508                     .setLaunchedFromPid(mLaunchedFromPid)
1509                     .setLaunchedFromUid(mLaunchedFromUid)
1510                     .setLaunchedFromPackage(mLaunchedFromPackage)
1511                     .setIntent(intent)
1512                     .setActivityInfo(aInfo)
1513                     .setActivityOptions(options)
1514                     .build();
1515 
1516             spyOn(activity);
1517             if (mTask != null) {
1518                 mTask.addChild(activity);
1519                 if (mOnTop) {
1520                     // Move the task to front after activity is added.
1521                     // Or {@link TaskDisplayArea#mPreferredTopFocusableRootTask} could be other
1522                     // root tasks (e.g. home root task).
1523                     mTask.moveToFront("createActivity");
1524                 }
1525                 if (mVisible) {
1526                     activity.setVisibleRequested(true);
1527                     activity.setVisible(true);
1528                 }
1529             }
1530 
1531             final WindowProcessController wpc;
1532             if (mWpc != null) {
1533                 wpc = mWpc;
1534             } else {
1535                 final WindowProcessController p = mService.getProcessController(mProcessName, mUid);
1536                 wpc = p != null ? p : SystemServicesTestRule.addProcess(
1537                         mService, aInfo.applicationInfo, mProcessName, 0 /* pid */);
1538             }
1539             activity.setProcess(wpc);
1540 
1541             // Resume top activities to make sure all other signals in the system are connected.
1542             mService.mRootWindowContainer.resumeFocusedTasksTopActivities();
1543             return activity;
1544         }
1545     }
1546 
1547     static class TaskFragmentBuilder {
1548         private final ActivityTaskManagerService mAtm;
1549         private Task mParentTask;
1550         private boolean mCreateParentTask;
1551         private int mCreateActivityCount = 0;
1552         @Nullable
1553         private TaskFragmentOrganizer mOrganizer;
1554         private IBinder mFragmentToken;
1555         private Rect mBounds;
1556 
TaskFragmentBuilder(ActivityTaskManagerService service)1557         TaskFragmentBuilder(ActivityTaskManagerService service) {
1558             mAtm = service;
1559         }
1560 
setCreateParentTask()1561         TaskFragmentBuilder setCreateParentTask() {
1562             mCreateParentTask = true;
1563             return this;
1564         }
1565 
setParentTask(Task task)1566         TaskFragmentBuilder setParentTask(Task task) {
1567             mParentTask = task;
1568             return this;
1569         }
1570 
createActivityCount(int count)1571         TaskFragmentBuilder createActivityCount(int count) {
1572             mCreateActivityCount = count;
1573             return this;
1574         }
1575 
setOrganizer(@ullable TaskFragmentOrganizer organizer)1576         TaskFragmentBuilder setOrganizer(@Nullable TaskFragmentOrganizer organizer) {
1577             mOrganizer = organizer;
1578             return this;
1579         }
1580 
setFragmentToken(@ullable IBinder fragmentToken)1581         TaskFragmentBuilder setFragmentToken(@Nullable IBinder fragmentToken) {
1582             mFragmentToken = fragmentToken;
1583             return this;
1584         }
1585 
setBounds(@ullable Rect bounds)1586         TaskFragmentBuilder setBounds(@Nullable Rect bounds) {
1587             mBounds = bounds;
1588             return this;
1589         }
1590 
build()1591         TaskFragment build() {
1592             SystemServicesTestRule.checkHoldsLock(mAtm.mGlobalLock);
1593 
1594             final TaskFragment taskFragment = new TaskFragment(mAtm, mFragmentToken,
1595                     mOrganizer != null);
1596             if (mParentTask == null && mCreateParentTask) {
1597                 mParentTask = new TaskBuilder(mAtm.mTaskSupervisor).build();
1598             }
1599             if (mParentTask != null) {
1600                 mParentTask.addChild(taskFragment, POSITION_TOP);
1601             }
1602             while (mCreateActivityCount > 0) {
1603                 final ActivityRecord activity = new ActivityBuilder(mAtm).build();
1604                 taskFragment.addChild(activity);
1605                 mCreateActivityCount--;
1606             }
1607             if (mOrganizer != null) {
1608                 taskFragment.setTaskFragmentOrganizer(
1609                         mOrganizer.getOrganizerToken(), DEFAULT_TASK_FRAGMENT_ORGANIZER_UID,
1610                         DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME);
1611             }
1612             if (mBounds != null && !mBounds.isEmpty()) {
1613                 taskFragment.setBounds(mBounds);
1614             }
1615             spyOn(taskFragment);
1616             return taskFragment;
1617         }
1618     }
1619 
1620     /**
1621      * Builder for creating new tasks.
1622      */
1623     protected static class TaskBuilder {
1624         private final ActivityTaskSupervisor mSupervisor;
1625 
1626         private TaskDisplayArea mTaskDisplayArea;
1627         private ComponentName mComponent;
1628         private String mPackage;
1629         private int mFlags = 0;
1630         private int mTaskId = -1;
1631         private int mUserId = 0;
1632         private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
1633         private int mActivityType = ACTIVITY_TYPE_STANDARD;
1634         private ActivityInfo mActivityInfo;
1635         private Intent mIntent;
1636         private boolean mOnTop = true;
1637         private IVoiceInteractionSession mVoiceSession;
1638 
1639         private boolean mCreateParentTask = false;
1640         private Task mParentTask;
1641 
1642         private boolean mCreateActivity = false;
1643         private boolean mCreatedByOrganizer = false;
1644 
TaskBuilder(ActivityTaskSupervisor supervisor)1645         TaskBuilder(ActivityTaskSupervisor supervisor) {
1646             mSupervisor = supervisor;
1647             mTaskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
1648         }
1649 
1650         /**
1651          * Set the parent {@link DisplayContent} and use the default task display area. Overrides
1652          * the task display area, if was set before.
1653          */
setDisplay(DisplayContent display)1654         TaskBuilder setDisplay(DisplayContent display) {
1655             mTaskDisplayArea = display.getDefaultTaskDisplayArea();
1656             return this;
1657         }
1658 
1659         /** Set the parent {@link TaskDisplayArea}. Overrides the display, if was set before. */
setTaskDisplayArea(TaskDisplayArea taskDisplayArea)1660         TaskBuilder setTaskDisplayArea(TaskDisplayArea taskDisplayArea) {
1661             mTaskDisplayArea = taskDisplayArea;
1662             return this;
1663         }
1664 
setComponent(ComponentName component)1665         TaskBuilder setComponent(ComponentName component) {
1666             mComponent = component;
1667             return this;
1668         }
1669 
setPackage(String packageName)1670         TaskBuilder setPackage(String packageName) {
1671             mPackage = packageName;
1672             return this;
1673         }
1674 
setFlags(int flags)1675         TaskBuilder setFlags(int flags) {
1676             mFlags = flags;
1677             return this;
1678         }
1679 
setTaskId(int taskId)1680         TaskBuilder setTaskId(int taskId) {
1681             mTaskId = taskId;
1682             return this;
1683         }
1684 
setUserId(int userId)1685         TaskBuilder setUserId(int userId) {
1686             mUserId = userId;
1687             return this;
1688         }
1689 
setWindowingMode(int windowingMode)1690         TaskBuilder setWindowingMode(int windowingMode) {
1691             mWindowingMode = windowingMode;
1692             return this;
1693         }
1694 
setActivityType(int activityType)1695         TaskBuilder setActivityType(int activityType) {
1696             mActivityType = activityType;
1697             return this;
1698         }
1699 
setActivityInfo(ActivityInfo info)1700         TaskBuilder setActivityInfo(ActivityInfo info) {
1701             mActivityInfo = info;
1702             return this;
1703         }
1704 
setIntent(Intent intent)1705         TaskBuilder setIntent(Intent intent) {
1706             mIntent = intent;
1707             return this;
1708         }
1709 
setOnTop(boolean onTop)1710         TaskBuilder setOnTop(boolean onTop) {
1711             mOnTop = onTop;
1712             return this;
1713         }
1714 
setVoiceSession(IVoiceInteractionSession session)1715         TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
1716             mVoiceSession = session;
1717             return this;
1718         }
1719 
setCreateParentTask(boolean createParentTask)1720         TaskBuilder setCreateParentTask(boolean createParentTask) {
1721             mCreateParentTask = createParentTask;
1722             return this;
1723         }
1724 
setParentTask(Task parentTask)1725         TaskBuilder setParentTask(Task parentTask) {
1726             mParentTask = parentTask;
1727             return this;
1728         }
1729 
setCreateActivity(boolean createActivity)1730         TaskBuilder setCreateActivity(boolean createActivity) {
1731             mCreateActivity = createActivity;
1732             return this;
1733         }
1734 
setCreatedByOrganizer(boolean createdByOrganizer)1735         TaskBuilder setCreatedByOrganizer(boolean createdByOrganizer) {
1736             mCreatedByOrganizer = createdByOrganizer;
1737             return this;
1738         }
1739 
build()1740         Task build() {
1741             SystemServicesTestRule.checkHoldsLock(mSupervisor.mService.mGlobalLock);
1742 
1743             // Create parent task.
1744             if (mParentTask == null && mCreateParentTask) {
1745                 mParentTask = mTaskDisplayArea.createRootTask(
1746                         WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
1747             }
1748             if (mParentTask != null && !Mockito.mockingDetails(mParentTask).isSpy()) {
1749                 spyOn(mParentTask);
1750             }
1751 
1752             // Create task.
1753             if (mActivityInfo == null) {
1754                 mActivityInfo = new ActivityInfo();
1755                 mActivityInfo.applicationInfo = new ApplicationInfo();
1756                 mActivityInfo.applicationInfo.packageName = mPackage;
1757             }
1758 
1759             if (mIntent == null) {
1760                 mIntent = new Intent();
1761                 if (mComponent == null) {
1762                     mComponent = getUniqueComponentName(mPackage);
1763                 }
1764                 mIntent.setComponent(mComponent);
1765                 mIntent.setFlags(mFlags);
1766             }
1767 
1768             final Task.Builder builder = new Task.Builder(mSupervisor.mService)
1769                     .setTaskId(mTaskId >= 0 ? mTaskId : mTaskDisplayArea.getNextRootTaskId())
1770                     .setWindowingMode(mWindowingMode)
1771                     .setActivityInfo(mActivityInfo)
1772                     .setIntent(mIntent)
1773                     .setOnTop(mOnTop)
1774                     .setVoiceSession(mVoiceSession)
1775                     .setCreatedByOrganizer(mCreatedByOrganizer);
1776             final Task task;
1777             if (mParentTask == null) {
1778                 task = builder.setActivityType(mActivityType)
1779                         .setParent(mTaskDisplayArea)
1780                         .build();
1781             } else {
1782                 task = builder.setParent(mParentTask).build();
1783                 mParentTask.moveToFront("build-task");
1784             }
1785             spyOn(task);
1786             task.mUserId = mUserId;
1787             final Task rootTask = task.getRootTask();
1788             if (task != rootTask && !Mockito.mockingDetails(rootTask).isSpy()) {
1789                 spyOn(rootTask);
1790             }
1791             doNothing().when(rootTask).startActivityLocked(
1792                     any(), any(), anyBoolean(), anyBoolean(), any(), any());
1793 
1794             // Create child activity.
1795             if (mCreateActivity) {
1796                 new ActivityBuilder(mSupervisor.mService)
1797                         .setTask(task)
1798                         .setComponent(mComponent)
1799                         .build();
1800                 if (mOnTop) {
1801                     // We move the task to front again in order to regain focus after activity
1802                     // is added. Or {@link TaskDisplayArea#mPreferredTopFocusableRootTask} could be
1803                     // other root tasks (e.g. home root task).
1804                     task.moveToFront("createActivityTask");
1805                 } else {
1806                     task.moveToBack("createActivityTask", null);
1807                 }
1808             }
1809 
1810             return task;
1811         }
1812     }
1813 
1814     static class TestStartingWindowOrganizer extends WindowOrganizerTests.StubOrganizer {
1815         private final ActivityTaskManagerService mAtm;
1816         private final WindowManagerService mWMService;
1817         private final SparseArray<IBinder> mTaskAppMap = new SparseArray<>();
1818         private final HashMap<IBinder, WindowState> mAppWindowMap = new HashMap<>();
1819 
TestStartingWindowOrganizer(ActivityTaskManagerService service)1820         TestStartingWindowOrganizer(ActivityTaskManagerService service) {
1821             mAtm = service;
1822             mWMService = mAtm.mWindowManager;
1823             mAtm.mTaskOrganizerController.registerTaskOrganizer(this);
1824         }
1825 
1826         @Override
addStartingWindow(StartingWindowInfo info)1827         public void addStartingWindow(StartingWindowInfo info) {
1828             synchronized (mWMService.mGlobalLock) {
1829                 final ActivityRecord activity = ActivityRecord.forTokenLocked(info.appToken);
1830                 IWindow iWindow = mock(IWindow.class);
1831                 doReturn(mock(IBinder.class)).when(iWindow).asBinder();
1832                 final WindowState window = WindowTestsBase.createWindow(null,
1833                         TYPE_APPLICATION_STARTING, activity,
1834                         "Starting window", 0 /* ownerId */, 0 /* userId*/,
1835                         false /* internalWindows */, mWMService, createTestSession(mAtm), iWindow);
1836                 activity.mStartingWindow = window;
1837                 mAppWindowMap.put(info.appToken, window);
1838                 mTaskAppMap.put(info.taskInfo.taskId, info.appToken);
1839             }
1840         }
1841         @Override
removeStartingWindow(StartingWindowRemovalInfo removalInfo)1842         public void removeStartingWindow(StartingWindowRemovalInfo removalInfo) {
1843             synchronized (mWMService.mGlobalLock) {
1844                 final IBinder appToken = mTaskAppMap.get(removalInfo.taskId);
1845                 if (appToken != null) {
1846                     mTaskAppMap.remove(removalInfo.taskId);
1847                     final ActivityRecord activity = ActivityRecord.forTokenLocked(appToken);
1848                     WindowState win = mAppWindowMap.remove(appToken);
1849                     activity.removeChild(win);
1850                     activity.mStartingWindow = null;
1851                 }
1852             }
1853         }
1854     }
1855 
1856     static class TestSplitOrganizer extends WindowOrganizerTests.StubOrganizer {
1857         final ActivityTaskManagerService mService;
1858         final TaskDisplayArea mDefaultTDA;
1859         Task mPrimary;
1860         Task mSecondary;
1861         int mDisplayId;
1862 
TestSplitOrganizer(ActivityTaskManagerService service, DisplayContent display)1863         TestSplitOrganizer(ActivityTaskManagerService service, DisplayContent display) {
1864             mService = service;
1865             mDefaultTDA = display.getDefaultTaskDisplayArea();
1866             mDisplayId = display.mDisplayId;
1867             mService.mTaskOrganizerController.registerTaskOrganizer(this);
1868             mPrimary = mService.mTaskOrganizerController.createRootTask(
1869                     display, WINDOWING_MODE_MULTI_WINDOW, null);
1870             mSecondary = mService.mTaskOrganizerController.createRootTask(
1871                     display, WINDOWING_MODE_MULTI_WINDOW, null);
1872 
1873             mPrimary.setAdjacentTaskFragment(mSecondary);
1874             display.getDefaultTaskDisplayArea().setLaunchAdjacentFlagRootTask(mSecondary);
1875 
1876             final Rect primaryBounds = new Rect();
1877             final Rect secondaryBounds = new Rect();
1878             if (display.getConfiguration().orientation == ORIENTATION_LANDSCAPE) {
1879                 display.getBounds().splitVertically(primaryBounds, secondaryBounds);
1880             } else {
1881                 display.getBounds().splitHorizontally(primaryBounds, secondaryBounds);
1882             }
1883             mPrimary.setBounds(primaryBounds);
1884             mSecondary.setBounds(secondaryBounds);
1885 
1886             spyOn(mPrimary);
1887             spyOn(mSecondary);
1888         }
1889 
TestSplitOrganizer(ActivityTaskManagerService service)1890         TestSplitOrganizer(ActivityTaskManagerService service) {
1891             this(service, service.mTaskSupervisor.mRootWindowContainer.getDefaultDisplay());
1892         }
1893 
createTaskToPrimary(boolean onTop)1894         public Task createTaskToPrimary(boolean onTop) {
1895             final Task primaryTask = mDefaultTDA.createRootTask(
1896                     WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, onTop);
1897             putTaskToPrimary(primaryTask, onTop);
1898             return primaryTask;
1899         }
1900 
createTaskToSecondary(boolean onTop)1901         public Task createTaskToSecondary(boolean onTop) {
1902             final Task secondaryTask = mDefaultTDA.createRootTask(
1903                     WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, onTop);
1904             putTaskToSecondary(secondaryTask, onTop);
1905             return secondaryTask;
1906         }
1907 
putTaskToPrimary(Task task, boolean onTop)1908         public void putTaskToPrimary(Task task, boolean onTop) {
1909             task.reparent(mPrimary, onTop ? POSITION_TOP : POSITION_BOTTOM);
1910         }
1911 
putTaskToSecondary(Task task, boolean onTop)1912         public void putTaskToSecondary(Task task, boolean onTop) {
1913             task.reparent(mSecondary, onTop ? POSITION_TOP : POSITION_BOTTOM);
1914         }
1915     }
1916 
1917     static class TestDesktopOrganizer extends WindowOrganizerTests.StubOrganizer {
1918         final int mDesktopModeDefaultWidthDp = 840;
1919         final int mDesktopModeDefaultHeightDp = 630;
1920         final int mDesktopDensity = 284;
1921         final int mOverrideDensity = 285;
1922 
1923         final ActivityTaskManagerService mService;
1924         final TaskDisplayArea mDefaultTDA;
1925         List<Task> mTasks;
1926         final DisplayContent mDisplay;
1927         Rect mStableBounds;
1928         Task mHomeTask;
1929 
TestDesktopOrganizer(ActivityTaskManagerService service, DisplayContent display)1930         TestDesktopOrganizer(ActivityTaskManagerService service, DisplayContent display) {
1931             mService = service;
1932             mDefaultTDA = display.getDefaultTaskDisplayArea();
1933             mDisplay = display;
1934             mService.mTaskOrganizerController.registerTaskOrganizer(this);
1935             mTasks = new ArrayList<>();
1936             mStableBounds = display.getBounds();
1937             mHomeTask =  mDefaultTDA.getRootHomeTask();
1938         }
TestDesktopOrganizer(ActivityTaskManagerService service)1939         TestDesktopOrganizer(ActivityTaskManagerService service) {
1940             this(service, service.mTaskSupervisor.mRootWindowContainer.getDefaultDisplay());
1941         }
1942 
createTask(Rect bounds)1943         public Task createTask(Rect bounds) {
1944             Task task = mService.mTaskOrganizerController.createRootTask(
1945                     mDisplay, WINDOWING_MODE_FREEFORM, null);
1946             task.setBounds(bounds);
1947             mTasks.add(task);
1948             spyOn(task);
1949             return task;
1950         }
1951 
getDefaultDesktopTaskBounds()1952         public Rect getDefaultDesktopTaskBounds() {
1953             int width = (int) (mDesktopModeDefaultWidthDp
1954                     * (mOverrideDensity / mDesktopDensity) + 0.5f);
1955             int height = (int) (mDesktopModeDefaultHeightDp
1956                     * (mOverrideDensity / mDesktopDensity) + 0.5f);
1957             Rect outBounds = new Rect();
1958 
1959             outBounds.set(0, 0, width, height);
1960             // Center the task in stable bounds
1961             outBounds.offset(
1962                     mStableBounds.centerX() - outBounds.centerX(),
1963                     mStableBounds.centerY() - outBounds.centerY()
1964             );
1965             return outBounds;
1966         }
1967 
createFreeformTasksWithActivities(TestDesktopOrganizer desktopOrganizer, List<ActivityRecord> activityRecords, int numberOfTasks)1968         public void createFreeformTasksWithActivities(TestDesktopOrganizer desktopOrganizer,
1969                 List<ActivityRecord> activityRecords, int numberOfTasks) {
1970             for (int i = 0; i < numberOfTasks; i++) {
1971                 Rect bounds = new Rect(desktopOrganizer.getDefaultDesktopTaskBounds());
1972                 bounds.offset(20 * i, 20 * i);
1973                 desktopOrganizer.createTask(bounds);
1974             }
1975 
1976             for (int i = 0; i < numberOfTasks; i++) {
1977                 activityRecords.add(new TaskBuilder(mService.mTaskSupervisor)
1978                         .setParentTask(desktopOrganizer.mTasks.get(i))
1979                         .setCreateActivity(true)
1980                         .build()
1981                         .getTopMostActivity());
1982             }
1983 
1984             for (int i = 0; i < numberOfTasks; i++) {
1985                 activityRecords.get(i).setVisibleRequested(true);
1986             }
1987 
1988             for (int i = 0; i < numberOfTasks; i++) {
1989                 assertEquals(desktopOrganizer.mTasks.get(i), activityRecords.get(i).getRootTask());
1990             }
1991         }
1992 
bringHomeToFront()1993         public void bringHomeToFront() {
1994             WindowContainerTransaction wct = new WindowContainerTransaction();
1995             wct.reorder(mHomeTask.getTaskInfo().token, true /* onTop */);
1996             applyTransaction(wct);
1997         }
1998 
bringDesktopTasksToFront(WindowContainerTransaction wct)1999         public void bringDesktopTasksToFront(WindowContainerTransaction wct) {
2000             for (Task task: mTasks) {
2001                 wct.reorder(task.getTaskInfo().token, true /* onTop */);
2002             }
2003         }
2004 
addMoveToDesktopChanges(WindowContainerTransaction wct, Task task, boolean overrideDensity)2005         public void addMoveToDesktopChanges(WindowContainerTransaction wct, Task task,
2006                 boolean overrideDensity) {
2007             wct.setWindowingMode(task.getTaskInfo().token, WINDOWING_MODE_FREEFORM);
2008             wct.reorder(task.getTaskInfo().token, true /* onTop */);
2009             if (overrideDensity) {
2010                 wct.setDensityDpi(task.getTaskInfo().token, mOverrideDensity);
2011             }
2012         }
2013 
addMoveToFullscreen(WindowContainerTransaction wct, Task task, boolean overrideDensity)2014         public void addMoveToFullscreen(WindowContainerTransaction wct, Task task,
2015                 boolean overrideDensity) {
2016             wct.setWindowingMode(task.getTaskInfo().token, WINDOWING_MODE_FULLSCREEN);
2017             wct.setBounds(task.getTaskInfo().token, new Rect());
2018             if (overrideDensity) {
2019                 wct.setDensityDpi(task.getTaskInfo().token, mOverrideDensity);
2020             }
2021         }
2022 
applyTransaction(@ndroidx.annotation.NonNull WindowContainerTransaction wct)2023         private void applyTransaction(@androidx.annotation.NonNull WindowContainerTransaction wct) {
2024             if (!wct.isEmpty()) {
2025                 mService.mWindowOrganizerController.applyTransaction(wct);
2026             }
2027         }
2028     }
2029 
2030 
createTestWindowToken(int type, DisplayContent dc)2031     static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {
2032         return createTestWindowToken(type, dc, false /* persistOnEmpty */);
2033     }
2034 
createTestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty)2035     static TestWindowToken createTestWindowToken(int type, DisplayContent dc,
2036             boolean persistOnEmpty) {
2037         SystemServicesTestRule.checkHoldsLock(dc.mWmService.mGlobalLock);
2038 
2039         return new TestWindowToken(type, dc, persistOnEmpty);
2040     }
2041 
createTestClientWindowToken(int type, DisplayContent dc)2042     static TestWindowToken createTestClientWindowToken(int type, DisplayContent dc) {
2043         SystemServicesTestRule.checkHoldsLock(dc.mWmService.mGlobalLock);
2044 
2045         return new TestWindowToken(type, dc, false /* persistOnEmpty */, true /* fromClient */);
2046     }
2047 
2048     /** Used so we can gain access to some protected members of the {@link WindowToken} class */
2049     static class TestWindowToken extends WindowToken {
2050 
TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty, boolean fromClient)2051         private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty,
2052                 boolean fromClient) {
2053             super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc,
2054                     false /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */,
2055                     fromClient /* fromClientToken */, null /* options */);
2056         }
2057 
TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty)2058         private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
2059             super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc,
2060                     false /* ownerCanManageAppTokens */);
2061         }
2062 
getWindowsCount()2063         int getWindowsCount() {
2064             return mChildren.size();
2065         }
2066 
hasWindow(WindowState w)2067         boolean hasWindow(WindowState w) {
2068             return mChildren.contains(w);
2069         }
2070     }
2071 
2072     /** Used to track resize reports. */
2073     static class TestWindowState extends WindowState {
2074         boolean mResizeReported;
2075 
TestWindowState(WindowManagerService service, Session session, IWindow window, WindowManager.LayoutParams attrs, WindowToken token)2076         TestWindowState(WindowManagerService service, Session session, IWindow window,
2077                 WindowManager.LayoutParams attrs, WindowToken token) {
2078             super(service, session, window, token, null, OP_NONE, attrs, 0, 0, 0,
2079                     false /* ownerCanAddInternalSystemWindow */);
2080         }
2081 
2082         @Override
reportResized()2083         void reportResized() {
2084             super.reportResized();
2085             mResizeReported = true;
2086         }
2087 
2088         @Override
isGoneForLayout()2089         public boolean isGoneForLayout() {
2090             return false;
2091         }
2092 
2093         @Override
updateResizingWindowIfNeeded()2094         void updateResizingWindowIfNeeded() {
2095             // Used in AppWindowTokenTests#testLandscapeSeascapeRotationRelayout to deceive
2096             // the system that it can actually update the window.
2097             boolean hadSurface = mHasSurface;
2098             mHasSurface = true;
2099 
2100             super.updateResizingWindowIfNeeded();
2101 
2102             mHasSurface = hadSurface;
2103         }
2104     }
2105 
2106     static class TestTransitionController extends TransitionController {
TestTransitionController(ActivityTaskManagerService atms)2107         TestTransitionController(ActivityTaskManagerService atms) {
2108             super(atms);
2109             doReturn(this).when(atms).getTransitionController();
2110             mSnapshotController = mock(SnapshotController.class);
2111             mTransitionTracer = mock(TransitionTracer.class);
2112         }
2113     }
2114 
2115     static class TestTransitionPlayer extends ITransitionPlayer.Stub {
2116         final TransitionController mController;
2117         final WindowOrganizerController mOrganizer;
2118         Transition mLastTransit = null;
2119         TransitionRequestInfo mLastRequest = null;
2120         TransitionInfo mLastReady = null;
2121 
TestTransitionPlayer(@onNull TransitionController controller, @NonNull WindowOrganizerController organizer)2122         TestTransitionPlayer(@NonNull TransitionController controller,
2123                 @NonNull WindowOrganizerController organizer) {
2124             mController = controller;
2125             mOrganizer = organizer;
2126         }
2127 
clear()2128         void clear() {
2129             mLastTransit = null;
2130             mLastReady = null;
2131             mLastRequest = null;
2132         }
2133 
2134         @Override
onTransitionReady(IBinder transitToken, TransitionInfo transitionInfo, SurfaceControl.Transaction transaction, SurfaceControl.Transaction finishT)2135         public void onTransitionReady(IBinder transitToken, TransitionInfo transitionInfo,
2136                 SurfaceControl.Transaction transaction, SurfaceControl.Transaction finishT)
2137                 throws RemoteException {
2138             mLastTransit = Transition.fromBinder(transitToken);
2139             mLastReady = transitionInfo;
2140         }
2141 
2142         @Override
requestStartTransition(IBinder transitToken, TransitionRequestInfo request)2143         public void requestStartTransition(IBinder transitToken,
2144                 TransitionRequestInfo request) throws RemoteException {
2145             mLastTransit = Transition.fromBinder(transitToken);
2146             mLastRequest = request;
2147         }
2148 
startTransition()2149         void startTransition() {
2150             mOrganizer.startTransition(mLastTransit.getToken(), null);
2151         }
2152 
onTransactionReady(SurfaceControl.Transaction t)2153         void onTransactionReady(SurfaceControl.Transaction t) {
2154             mLastTransit.onTransactionReady(mLastTransit.getSyncId(), t);
2155         }
2156 
start()2157         void start() {
2158             startTransition();
2159             onTransactionReady(mock(SurfaceControl.Transaction.class));
2160         }
2161 
finish()2162         public void finish() {
2163             mController.finishTransition(ActionChain.testFinish(mLastTransit));
2164         }
2165     }
2166 }
2167