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