diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 9d54255..94c2192 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -396,7 +396,7 @@
 
         mWindowState = WINDOW_STATE_INVALID;
         ActivityStack stack =
-                mSupervisor.mRootActivityContainer.getTopDisplayFocusedStack();
+                mSupervisor.mRootWindowContainer.getTopDisplayFocusedStack();
         if (stack == null) {
             return;
         }
@@ -408,7 +408,7 @@
 
         @WindowingMode int windowingMode = stack.getWindowingMode();
         if (windowingMode == WINDOWING_MODE_PINNED) {
-            stack = mSupervisor.mRootActivityContainer.findStackBehind(stack);
+            stack = mSupervisor.mRootWindowContainer.findStackBehind(stack);
             windowingMode = stack.getWindowingMode();
         }
         switch (windowingMode) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index cffcfef..76d18fa 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -515,7 +515,7 @@
 
     boolean inHistory;  // are we in the history stack?
     final ActivityStackSupervisor mStackSupervisor;
-    final RootActivityContainer mRootActivityContainer;
+    final RootWindowContainer mRootWindowContainer;
 
     static final int STARTING_WINDOW_NOT_SHOWN = 0;
     static final int STARTING_WINDOW_SHOWN = 1;
@@ -1564,7 +1564,7 @@
 
         appToken.attach(this);
 
-        mRootActivityContainer = _service.mRootActivityContainer;
+        mRootWindowContainer = _service.mRootWindowContainer;
         launchedFromPid = _launchedFromPid;
         launchedFromUid = _launchedFromUid;
         launchedFromPackage = _launchedFromPackage;
@@ -2100,7 +2100,7 @@
         // {@link #returningOptions} of the activity under this one can be applied in
         // {@link #handleAlreadyVisible()}.
         if (changed || !occludesParent) {
-            mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+            mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
         }
         return changed;
     }
@@ -2140,7 +2140,7 @@
     }
 
     boolean isFocusable() {
-        return mRootActivityContainer.isFocusable(this, isAlwaysFocusable());
+        return mRootWindowContainer.isFocusable(this, isAlwaysFocusable());
     }
 
     boolean isResizeable() {
@@ -2336,7 +2336,7 @@
             return false;
         }
 
-        if (mRootActivityContainer.getTopResumedActivity() == this
+        if (mRootWindowContainer.getTopResumedActivity() == this
                 && getDisplayContent().mFocusedApp == this) {
             if (DEBUG_FOCUS) {
                 Slog.d(TAG_FOCUS, "moveActivityStackToFront: already on top, activity=" + this);
@@ -2350,7 +2350,7 @@
 
         stack.moveToFront(reason, task);
         // Report top activity change to tracking services and WM
-        if (mRootActivityContainer.getTopResumedActivity() == this) {
+        if (mRootWindowContainer.getTopResumedActivity() == this) {
             mAtmService.setResumedActivityUncheckLocked(this, reason);
         }
         return true;
@@ -2466,7 +2466,7 @@
         final boolean shouldAdjustGlobalFocus = mayAdjustTop
                 // It must be checked before {@link #makeFinishingLocked} is called, because a stack
                 // is not visible if it only contains finishing activities.
-                && mRootActivityContainer.isTopDisplayFocusedStack(stack);
+                && mRootWindowContainer.isTopDisplayFocusedStack(stack);
 
         mAtmService.deferWindowLayout();
         try {
@@ -2694,11 +2694,11 @@
         // If the display does not have running activity, the configuration may need to be
         // updated for restoring original orientation of the display.
         if (next == null) {
-            mRootActivityContainer.ensureVisibilityAndConfig(next, getDisplayId(),
+            mRootWindowContainer.ensureVisibilityAndConfig(next, getDisplayId(),
                     false /* markFrozenIfConfigChanged */, true /* deferResume */);
         }
         if (activityRemoved) {
-            mRootActivityContainer.resumeFocusedStacksTopActivities();
+            mRootWindowContainer.resumeFocusedStacksTopActivities();
         }
 
         if (DEBUG_CONTAINERS) {
@@ -2722,7 +2722,7 @@
             mStackSupervisor.mFinishingActivities.add(this);
         }
         resumeKeyDispatchingLocked();
-        return mRootActivityContainer.resumeFocusedStacksTopActivities();
+        return mRootWindowContainer.resumeFocusedStacksTopActivities();
     }
 
     /**
@@ -2892,7 +2892,7 @@
             removeFromHistory(reason);
         }
 
-        mRootActivityContainer.resumeFocusedStacksTopActivities();
+        mRootWindowContainer.resumeFocusedStacksTopActivities();
     }
 
     /**
@@ -3409,13 +3409,13 @@
 
     void setShowWhenLocked(boolean showWhenLocked) {
         mShowWhenLocked = showWhenLocked;
-        mAtmService.mRootActivityContainer.ensureActivitiesVisible(null /* starting */,
+        mAtmService.mRootWindowContainer.ensureActivitiesVisible(null /* starting */,
                 0 /* configChanges */, false /* preserveWindows */);
     }
 
     void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
         mInheritShownWhenLocked = inheritShowWhenLocked;
-        mAtmService.mRootActivityContainer.ensureActivitiesVisible(null /* starting */,
+        mAtmService.mRootWindowContainer.ensureActivitiesVisible(null /* starting */,
                 0 /* configChanges */, false /* preserveWindows */);
     }
 
@@ -4835,7 +4835,7 @@
             }
         }
 
-        mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+        mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
     }
 
     /**
@@ -4966,9 +4966,9 @@
             } else {
                 if (deferRelaunchUntilPaused) {
                     destroyImmediately(true /* removeFromApp */, "stop-config");
-                    mRootActivityContainer.resumeFocusedStacksTopActivities();
+                    mRootWindowContainer.resumeFocusedStacksTopActivities();
                 } else {
-                    mRootActivityContainer.updatePreviousProcess(this);
+                    mRootWindowContainer.updatePreviousProcess(this);
                 }
             }
         }
@@ -5428,7 +5428,7 @@
         // First find the real culprit...  if this activity has stopped, then the key dispatching
         // timeout should not be caused by this.
         if (stopped) {
-            final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
+            final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
             // Try to use the one which is closest to top.
             ActivityRecord r = stack.getResumedActivity();
             if (r == null) {
@@ -6104,7 +6104,7 @@
         getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
         scheduleAnimation();
 
-        if (mAtmService.mRootActivityContainer.allResumedActivitiesIdle()
+        if (mAtmService.mRootWindowContainer.allResumedActivitiesIdle()
                 || mAtmService.mStackSupervisor.isStoppingNoHistoryActivity()) {
             // If all activities are already idle or there is an activity that must be
             // stopped immediately after visible, then we now need to make sure we perform
@@ -7423,7 +7423,7 @@
     }
 
     boolean isTopRunningActivity() {
-        return mRootActivityContainer.topRunningActivity() == this;
+        return mRootWindowContainer.topRunningActivity() == this;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 37ceb73..16245f0 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -384,7 +384,7 @@
 
     /** Run all ActivityStacks through this */
     protected final ActivityStackSupervisor mStackSupervisor;
-    protected final RootActivityContainer mRootActivityContainer;
+    protected final RootWindowContainer mRootWindowContainer;
 
     private boolean mTopActivityOccludesKeyguard;
     private ActivityRecord mTopDismissingKeyguardActivity;
@@ -443,7 +443,7 @@
             if (mUpdateConfig) {
                 // Ensure the resumed state of the focus activity if we updated the configuration of
                 // any activity.
-                mRootActivityContainer.resumeFocusedStacksTopActivities();
+                mRootWindowContainer.resumeFocusedStacksTopActivities();
             }
         }
 
@@ -646,7 +646,7 @@
         EventLogTags.writeWmStackCreated(stackId);
         mStackSupervisor = supervisor;
         mAtmService = supervisor.mService;
-        mRootActivityContainer = mAtmService.mRootActivityContainer;
+        mRootWindowContainer = mAtmService.mRootWindowContainer;
         mHandler = new ActivityStackHandler(supervisor.mLooper);
         mRemoteToken = new RemoteToken(this);
         mCurrentUser = mAtmService.mAmInternal.getCurrentUserId();
@@ -673,7 +673,7 @@
             if (DEBUG_STACK) Slog.v(TAG_STACK, "set resumed activity to:" + record + " reason:"
                     + reason);
             setResumedActivity(record, reason + " - onActivityStateChanged");
-            if (record == mRootActivityContainer.getTopResumedActivity()) {
+            if (record == mRootWindowContainer.getTopResumedActivity()) {
                 mAtmService.setResumedActivityUncheckLocked(record, reason);
             }
             mStackSupervisor.mRecentTasks.add(record.getTask());
@@ -983,8 +983,8 @@
         }
 
         if (!deferEnsuringVisibility) {
-            mRootActivityContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
-            mRootActivityContainer.resumeFocusedStacksTopActivities();
+            mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
+            mRootWindowContainer.resumeFocusedStacksTopActivities();
         }
     }
 
@@ -1002,10 +1002,10 @@
     /** Resume next focusable stack after reparenting to another display. */
     void postReparent() {
         adjustFocusToNextFocusableStack("reparent", true /* allowFocusSelf */);
-        mRootActivityContainer.resumeFocusedStacksTopActivities();
+        mRootWindowContainer.resumeFocusedStacksTopActivities();
         // Update visibility of activities before notifying WM. This way it won't try to resize
         // windows that are no longer visible.
-        mRootActivityContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
+        mRootWindowContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
                 !PRESERVE_WINDOWS);
     }
 
@@ -1230,7 +1230,7 @@
 
     boolean isFocusable() {
         final ActivityRecord r = topRunningActivity();
-        return mRootActivityContainer.isFocusable(this, r != null && r.isFocusable());
+        return mRootWindowContainer.isFocusable(this, r != null && r.isFocusable());
     }
 
     boolean isFocusableAndVisible() {
@@ -1395,7 +1395,7 @@
         if (prev == null) {
             if (resuming == null) {
                 Slog.wtf(TAG, "Trying to pause when nothing is resumed");
-                mRootActivityContainer.resumeFocusedStacksTopActivities();
+                mRootWindowContainer.resumeFocusedStacksTopActivities();
             }
             return false;
         }
@@ -1485,7 +1485,7 @@
             // pause, so just treat it as being paused now.
             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
             if (resuming == null) {
-                mRootActivityContainer.resumeFocusedStacksTopActivities();
+                mRootWindowContainer.resumeFocusedStacksTopActivities();
             }
             return false;
         }
@@ -1538,9 +1538,9 @@
         }
 
         if (resumeNext) {
-            final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
+            final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
             if (!topStack.shouldSleepOrShutDownActivities()) {
-                mRootActivityContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
+                mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
             } else {
                 checkReadyForSleep();
                 ActivityRecord top = topStack.topRunningActivity();
@@ -1549,7 +1549,7 @@
                     // something. Also if the top activity on the stack is not the just paused
                     // activity, we need to go ahead and resume it to ensure we complete an
                     // in-flight app switch.
-                    mRootActivityContainer.resumeFocusedStacksTopActivities();
+                    mRootWindowContainer.resumeFocusedStacksTopActivities();
                 }
             }
         }
@@ -1580,7 +1580,7 @@
             mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
         }
 
-        mRootActivityContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
+        mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
     }
 
     /**
@@ -1786,7 +1786,7 @@
     /**
      * Ensure visibility with an option to also update the configuration of visible activities.
      * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
-     * @see RootActivityContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
+     * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
      */
     // TODO: Should be re-worked based on the fact that each task as a stack in most cases.
     void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
@@ -1988,7 +1988,7 @@
      *
      * NOTE: It is not safe to call this method directly as it can cause an activity in a
      *       non-focused stack to be resumed.
-     *       Use {@link RootActivityContainer#resumeFocusedStacksTopActivities} to resume the
+     *       Use {@link RootWindowContainer#resumeFocusedStacksTopActivities} to resume the
      *       right activity for the current system state.
      */
     @GuardedBy("mService")
@@ -2059,7 +2059,7 @@
             return false;
         }
 
-        mRootActivityContainer.cancelInitializingActivities();
+        mRootWindowContainer.cancelInitializingActivities();
 
         // Remember how we'll process this pause/resume situation, and ensure
         // that the state is reset however we wind up proceeding.
@@ -2093,7 +2093,7 @@
         // activity is paused, well that is the state we want.
         if (shouldSleepOrShutDownActivities()
                 && mLastPausedActivity == next
-                && mRootActivityContainer.allPausedActivitiesComplete()) {
+                && mRootWindowContainer.allPausedActivitiesComplete()) {
             // If the current top activity may be able to occlude keyguard but the occluded state
             // has not been set, update visibility and check again if we should continue to resume.
             boolean nothingToResume = true;
@@ -2137,7 +2137,7 @@
         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
 
         // If we are currently pausing an activity, then don't do anything until that is done.
-        if (!mRootActivityContainer.allPausedActivitiesComplete()) {
+        if (!mRootWindowContainer.allPausedActivitiesComplete()) {
             if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                     "resumeTopActivityLocked: Skip resume: some activity pausing.");
 
@@ -2350,7 +2350,7 @@
                 // result of invisible window resize.
                 // TODO: Remove this once visibilities are set correctly immediately when
                 // starting an activity.
-                notUpdated = !mRootActivityContainer.ensureVisibilityAndConfig(next, mDisplayId,
+                notUpdated = !mRootWindowContainer.ensureVisibilityAndConfig(next, mDisplayId,
                         true /* markFrozenIfConfigChanged */, false /* deferResume */);
             }
 
@@ -2481,7 +2481,7 @@
                 // Try to move focus to the next visible stack with a running activity if this
                 // stack is not covering the entire screen or is on a secondary display with no home
                 // stack.
-                return mRootActivityContainer.resumeFocusedStacksTopActivities(nextFocusedStack,
+                return mRootWindowContainer.resumeFocusedStacksTopActivities(nextFocusedStack,
                         prev, null /* targetOptions */);
             }
         }
@@ -2491,7 +2491,7 @@
         ActivityOptions.abort(options);
         if (DEBUG_STATES) Slog.d(TAG_STATES,
                 "resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home");
-        return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
+        return mRootWindowContainer.resumeHomeActivity(prev, reason, mDisplayId);
     }
 
     void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
@@ -2698,7 +2698,7 @@
      */
     private ActivityStack adjustFocusToNextFocusableStack(String reason, boolean allowFocusSelf) {
         final ActivityStack stack =
-                mRootActivityContainer.getNextFocusableStack(this, !allowFocusSelf);
+                mRootWindowContainer.getNextFocusableStack(this, !allowFocusSelf);
         final String myReason = reason + " adjustFocusToNextFocusableStack";
         if (stack == null) {
             return null;
@@ -3070,7 +3070,7 @@
                 topActivity.supportsEnterPipOnTaskSwitch = true;
             }
 
-            mRootActivityContainer.resumeFocusedStacksTopActivities();
+            mRootWindowContainer.resumeFocusedStacksTopActivities();
             EventLogTags.writeWmTaskToFront(tr.mUserId, tr.mTaskId);
             mAtmService.getTaskChangeNotificationController().notifyTaskMovedToFront(tr.getTaskInfo());
         } finally {
@@ -3138,12 +3138,12 @@
             // The new top activity is already resumed, so there's a good chance that nothing will
             // get resumed below. So, update visibility now in case the transition is closed
             // prematurely.
-            mRootActivityContainer.ensureVisibilityAndConfig(null /* starting */,
+            mRootWindowContainer.ensureVisibilityAndConfig(null /* starting */,
                     getDisplay().mDisplayId, false /* markFrozenIfConfigChanged */,
                     false /* deferResume */);
         }
 
-        mRootActivityContainer.resumeFocusedStacksTopActivities();
+        mRootWindowContainer.resumeFocusedStacksTopActivities();
         return true;
     }
 
@@ -3505,7 +3505,7 @@
         // The task might have already been running and its visibility needs to be synchronized with
         // the visibility of the stack / windows.
         ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
-        mRootActivityContainer.resumeFocusedStacksTopActivities();
+        mRootWindowContainer.resumeFocusedStacksTopActivities();
     }
 
     public void setAlwaysOnTop(boolean alwaysOnTop) {
@@ -3545,7 +3545,7 @@
         moveToFront(reason);
         // If the original state is resumed, there is no state change to update focused app.
         // So here makes sure the activity focus is set if it is the top.
-        if (origState == RESUMED && r == mRootActivityContainer.getTopResumedActivity()) {
+        if (origState == RESUMED && r == mRootWindowContainer.getTopResumedActivity()) {
             mAtmService.setResumedActivityUncheckLocked(r, reason);
         }
     }
@@ -4090,7 +4090,7 @@
             mStackSupervisor.resizeDockedStackLocked(getRequestedOverrideBounds(), mTmpRect,
                     mTmpRect2, null, null, PRESERVE_WINDOWS);
         }
-        mRootActivityContainer.updateUIDsPresentOnDisplay();
+        mRootWindowContainer.updateUIDsPresentOnDisplay();
 
         // Resume next focusable stack after reparenting to another display if we aren't removing
         // the prevous display.
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 9203fcb..a380efc4 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -73,10 +73,10 @@
 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
 import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_SUPERVISOR_STACK_MSG;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
-import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_ONLY;
-import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
-import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
-import static com.android.server.wm.RootActivityContainer.TAG_STATES;
+import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_ONLY;
+import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
+import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
+import static com.android.server.wm.RootWindowContainer.TAG_STATES;
 import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE;
 import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
 import static com.android.server.wm.Task.LOCK_TASK_AUTH_WHITELISTED;
@@ -244,7 +244,7 @@
     private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE;
 
     final ActivityTaskManagerService mService;
-    RootActivityContainer mRootActivityContainer;
+    RootWindowContainer mRootWindowContainer;
 
     /** The historial list of recent tasks including inactive tasks */
     RecentTasks mRecentTasks;
@@ -564,7 +564,7 @@
     }
 
     void moveRecentsStackToFront(String reason) {
-        final ActivityStack recentsStack = mRootActivityContainer.getDefaultDisplay().getStack(
+        final ActivityStack recentsStack = mRootWindowContainer.getDefaultDisplay().getStack(
                 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
         if (recentsStack != null) {
             recentsStack.moveToFront(reason);
@@ -594,7 +594,7 @@
         // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on.
         int candidateTaskId = nextTaskIdForUser(currentTaskId, userId);
         while (mRecentTasks.containsTaskId(candidateTaskId, userId)
-                || mRootActivityContainer.anyTaskForId(
+                || mRootWindowContainer.anyTaskForId(
                         candidateTaskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) != null) {
             candidateTaskId = nextTaskIdForUser(candidateTaskId, userId);
             if (candidateTaskId == currentTaskId) {
@@ -776,7 +776,7 @@
     boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
             boolean andResume, boolean checkConfig) throws RemoteException {
 
-        if (!mRootActivityContainer.allPausedActivitiesComplete()) {
+        if (!mRootWindowContainer.allPausedActivitiesComplete()) {
             // While there are activities pausing we skipping starting any new activities until
             // pauses are complete. NOTE: that we also do this for activities that are starting in
             // the paused state because they will first be resumed then paused on the client side.
@@ -814,7 +814,7 @@
                 // Deferring resume here because we're going to launch new activity shortly.
                 // We don't want to perform a redundant launch of the same record while ensuring
                 // configurations and trying to resume top activity of focused stack.
-                mRootActivityContainer.ensureVisibilityAndConfig(r, r.getDisplayId(),
+                mRootWindowContainer.ensureVisibilityAndConfig(r, r.getDisplayId(),
                         false /* markFrozenIfConfigChanged */, true /* deferResume */);
             }
 
@@ -981,7 +981,7 @@
         // launching the initial activity (that is, home), so that it can have
         // a chance to initialize itself while in the background, making the
         // switch back to it faster and look better.
-        if (mRootActivityContainer.isTopDisplayFocusedStack(stack)) {
+        if (mRootWindowContainer.isTopDisplayFocusedStack(stack)) {
             mService.getActivityStartController().startSetupActivity();
         }
 
@@ -1122,7 +1122,7 @@
         }
 
         final DisplayContent displayContent =
-                mRootActivityContainer.getDisplayContentOrCreate(launchDisplayId);
+                mRootWindowContainer.getDisplayContentOrCreate(launchDisplayId);
         if (displayContent == null || displayContent.isRemoved()) {
             Slog.w(TAG, "Launch on display check: display not found");
             return false;
@@ -1338,7 +1338,7 @@
 
             // Check if able to finish booting when device is booting and all resumed activities
             // are idle.
-            if ((mService.isBooting() && mRootActivityContainer.allResumedActivitiesIdle())
+            if ((mService.isBooting() && mRootWindowContainer.allResumedActivitiesIdle())
                     || fromTimeout) {
                 booting = checkFinishBootingLocked();
             }
@@ -1348,7 +1348,7 @@
             r.mRelaunchReason = RELAUNCH_REASON_NONE;
         }
 
-        if (mRootActivityContainer.allResumedActivitiesIdle()) {
+        if (mRootWindowContainer.allResumedActivitiesIdle()) {
             if (r != null) {
                 mService.scheduleAppGcsLocked();
             }
@@ -1361,7 +1361,7 @@
                 }
                 mLaunchingActivityWakeLock.release();
             }
-            mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+            mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
         }
 
         // Atomically retrieve all of the other things to do.
@@ -1417,7 +1417,7 @@
         //mWindowManager.dump();
 
         if (activityRemoved) {
-            mRootActivityContainer.resumeFocusedStacksTopActivities();
+            mRootWindowContainer.resumeFocusedStacksTopActivities();
         }
 
         return r;
@@ -1444,7 +1444,7 @@
             task.setBounds(bounds);
 
             ActivityStack stack =
-                    mRootActivityContainer.getLaunchStack(null, options, task, ON_TOP);
+                    mRootWindowContainer.getLaunchStack(null, options, task, ON_TOP);
 
             if (stack != currentStack) {
                 moveHomeStackToFrontIfNeeded(flags, stack.getDisplay(), reason);
@@ -1509,13 +1509,13 @@
     }
 
     private void deferUpdateRecentsHomeStackBounds() {
-        mRootActivityContainer.deferUpdateBounds(ACTIVITY_TYPE_RECENTS);
-        mRootActivityContainer.deferUpdateBounds(ACTIVITY_TYPE_HOME);
+        mRootWindowContainer.deferUpdateBounds(ACTIVITY_TYPE_RECENTS);
+        mRootWindowContainer.deferUpdateBounds(ACTIVITY_TYPE_HOME);
     }
 
     private void continueUpdateRecentsHomeStackBounds() {
-        mRootActivityContainer.continueUpdateBounds(ACTIVITY_TYPE_RECENTS);
-        mRootActivityContainer.continueUpdateBounds(ACTIVITY_TYPE_HOME);
+        mRootWindowContainer.continueUpdateBounds(ACTIVITY_TYPE_RECENTS);
+        mRootWindowContainer.continueUpdateBounds(ACTIVITY_TYPE_HOME);
     }
 
     void notifyAppTransitionDone() {
@@ -1523,7 +1523,7 @@
         for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
             final int taskId = mResizingTasksDuringAnimation.valueAt(i);
             final Task task =
-                    mRootActivityContainer.anyTaskForId(taskId, MATCH_TASK_IN_STACKS_ONLY);
+                    mRootWindowContainer.anyTaskForId(taskId, MATCH_TASK_IN_STACKS_ONLY);
             if (task != null) {
                 task.setTaskDockedResizing(false);
             }
@@ -1542,7 +1542,7 @@
         try {
             final int windowingMode = fromStack.getWindowingMode();
             final DisplayContent toDisplay =
-                    mRootActivityContainer.getDisplayContent(toDisplayId);
+                    mRootWindowContainer.getDisplayContent(toDisplayId);
 
             if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
                 // We are moving all tasks from the docked stack to the fullscreen stack,
@@ -1574,8 +1574,8 @@
                         fromStack, toDisplay, onTop, schedulePictureInPictureModeChange);
             }
 
-            mRootActivityContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
-            mRootActivityContainer.resumeFocusedStacksTopActivities();
+            mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
+            mRootWindowContainer.resumeFocusedStacksTopActivities();
         } finally {
             mAllowDockedStackResize = true;
             mService.continueWindowLayout();
@@ -1627,7 +1627,7 @@
         }
 
         final ActivityStack stack =
-                mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
+                mRootWindowContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
         if (stack == null) {
             Slog.w(TAG, "resizeDockedStackLocked: docked stack not found");
             return;
@@ -1667,7 +1667,7 @@
                 // static stacks need to be adjusted so they don't overlap with the docked stack.
                 // We get the bounds to use from window manager which has been adjusted for any
                 // screen controls and is also the same for all stacks.
-                final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+                final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
                 final Rect otherTaskRect = new Rect();
                 for (int i = display.getStackCount() - 1; i >= 0; --i) {
                     final ActivityStack current = display.getStackAt(i);
@@ -1715,7 +1715,7 @@
     void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
         // TODO(multi-display): The display containing the stack should be passed in.
         final ActivityStack stack =
-                mRootActivityContainer.getDefaultDisplay().getPinnedStack();
+                mRootWindowContainer.getDefaultDisplay().getPinnedStack();
         if (stack == null) {
             Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found");
             return;
@@ -1798,7 +1798,7 @@
     boolean removeTaskById(int taskId, boolean killProcess, boolean removeFromRecents,
             String reason) {
         final Task task =
-                mRootActivityContainer.anyTaskForId(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+                mRootWindowContainer.anyTaskForId(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
         if (task != null) {
             removeTask(task, killProcess, removeFromRecents, reason);
             return true;
@@ -1893,7 +1893,7 @@
      */
     boolean restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop) {
         final ActivityStack stack =
-                mRootActivityContainer.getLaunchStack(null, aOptions, task, onTop);
+                mRootWindowContainer.getLaunchStack(null, aOptions, task, onTop);
         final ActivityStack currentStack = task.getStack();
 
         if (currentStack == stack) {
@@ -1994,7 +1994,7 @@
             }
         }
 
-        mRootActivityContainer.applySleepTokens(false /* applyToStacks */);
+        mRootWindowContainer.applySleepTokens(false /* applyToStacks */);
 
         checkReadyForSleepLocked(true /* allowDelay */);
     }
@@ -2005,7 +2005,7 @@
         boolean timedout = false;
         final long endTime = System.currentTimeMillis() + timeout;
         while (true) {
-            if (!mRootActivityContainer.putStacksToSleep(
+            if (!mRootWindowContainer.putStacksToSleep(
                     true /* allowDelay */, true /* shuttingDown */)) {
                 long timeRemaining = endTime - System.currentTimeMillis();
                 if (timeRemaining > 0) {
@@ -2052,13 +2052,13 @@
             return;
         }
 
-        if (!mRootActivityContainer.putStacksToSleep(
+        if (!mRootWindowContainer.putStacksToSleep(
                 allowDelay, false /* shuttingDown */)) {
             return;
         }
 
         // Send launch end powerhint before going sleep
-        mRootActivityContainer.sendPowerHintForLaunchEndIfNeeded();
+        mRootWindowContainer.sendPowerHintForLaunchEndIfNeeded();
 
         removeSleepTimeouts();
 
@@ -2076,10 +2076,10 @@
 
         final ActivityStack stack = r.getActivityStack();
         if (stack.getDisplay().allResumedActivitiesComplete()) {
-            mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+            mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
             // Make sure activity & window visibility should be identical
             // for all displays in this stage.
-            mRootActivityContainer.executeAppTransitionForAllDisplay();
+            mRootWindowContainer.executeAppTransitionForAllDisplay();
             return true;
         }
         return false;
@@ -2108,7 +2108,7 @@
 
     /** Checks whether the userid is a profile of the current user. */
     boolean isCurrentProfileLocked(int userId) {
-        if (userId == mRootActivityContainer.mCurrentUser) return true;
+        if (userId == mRootWindowContainer.mCurrentUser) return true;
         return mService.mAmInternal.isCurrentProfile(userId);
     }
 
@@ -2134,7 +2134,7 @@
             boolean remove, boolean processPausingActivities) {
         ArrayList<ActivityRecord> stops = null;
 
-        final boolean nowVisible = mRootActivityContainer.allResumedActivitiesVisible();
+        final boolean nowVisible = mRootWindowContainer.allResumedActivitiesVisible();
         for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
             ActivityRecord s = mStoppingActivities.get(activityNdx);
 
@@ -2206,10 +2206,10 @@
     public void dump(PrintWriter pw, String prefix) {
         pw.println();
         pw.println("ActivityStackSupervisor state:");
-        mRootActivityContainer.dump(pw, prefix);
+        mRootWindowContainer.dump(pw, prefix);
         pw.print(prefix);
         pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
-        pw.println(prefix + "mUserStackInFront=" + mRootActivityContainer.mUserStackInFront);
+        pw.println(prefix + "mUserStackInFront=" + mRootWindowContainer.mUserStackInFront);
         if (!mWaitingForActivityVisible.isEmpty()) {
             pw.println(prefix + "mWaitingForActivityVisible=");
             for (int i = 0; i < mWaitingForActivityVisible.size(); ++i) {
@@ -2217,7 +2217,7 @@
             }
         }
         pw.print(prefix); pw.print("isHomeRecentsComponent=");
-        pw.print(mRecentTasks.isRecentsComponentHomeActivity(mRootActivityContainer.mCurrentUser));
+        pw.print(mRecentTasks.isRecentsComponentHomeActivity(mRootWindowContainer.mCurrentUser));
 
         getKeyguardController().dump(pw, prefix);
         mService.getLockTaskController().dump(pw, prefix);
@@ -2335,7 +2335,7 @@
      */
     void updateTopResumedActivityIfNeeded() {
         final ActivityRecord prevTopActivity = mTopResumedActivity;
-        final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
+        final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
         if (topStack == null || topStack.mResumedActivity == prevTopActivity) {
             return;
         }
@@ -2449,7 +2449,7 @@
             }
 
             final DisplayContent preferredDisplay =
-                    mRootActivityContainer.getDisplayContent(preferredDisplayId);
+                    mRootWindowContainer.getDisplayContent(preferredDisplayId);
 
             final boolean singleTaskInstance = preferredDisplay != null
                     && preferredDisplay.isSingleTaskInstance();
@@ -2662,7 +2662,7 @@
                 } break;
                 case RESUME_TOP_ACTIVITY_MSG: {
                     synchronized (mService.mGlobalLock) {
-                        mRootActivityContainer.resumeFocusedStacksTopActivities();
+                        mRootWindowContainer.resumeFocusedStacksTopActivities();
                     }
                 } break;
                 case SLEEP_TIMEOUT_MSG: {
@@ -2714,7 +2714,7 @@
                         mHandler.removeMessages(REPORT_HOME_CHANGED_MSG);
 
                         // Start home activities on displays with no activities.
-                        mRootActivityContainer.startHomeOnEmptyDisplays("homeChanged");
+                        mRootWindowContainer.startHomeOnEmptyDisplays("homeChanged");
                     }
                 } break;
                 case TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG: {
@@ -2780,7 +2780,7 @@
                 mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
             }
 
-            task = mRootActivityContainer.anyTaskForId(taskId,
+            task = mRootWindowContainer.anyTaskForId(taskId,
                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, activityOptions, ON_TOP);
             if (task == null) {
                 continueUpdateRecentsHomeStackBounds();
@@ -2794,7 +2794,7 @@
                 // from whatever is started from the recents activity, so move the home stack
                 // forward.
                 // TODO (b/115289124): Multi-display supports for recents.
-                mRootActivityContainer.getDefaultDisplay().moveHomeStackToFront(
+                mRootWindowContainer.getDefaultDisplay().moveHomeStackToFront(
                         "startActivityFromRecents");
             }
 
@@ -2804,7 +2804,7 @@
                     && task.getRootActivity() != null) {
                 final ActivityRecord targetActivity = task.getTopNonFinishingActivity();
 
-                mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
+                mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(
                         true /* forceSend */, targetActivity);
                 final LaunchingState launchingState =
                         mActivityMetricsLogger.notifyActivityLaunching(task.intent);
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 4c165df..955e581 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -182,7 +182,7 @@
         options.setLaunchDisplayId(displayId);
 
         final DisplayContent display =
-                mService.mRootActivityContainer.getDisplayContent(displayId);
+                mService.mRootWindowContainer.getDisplayContent(displayId);
         // The home activity will be started later, defer resuming to avoid unneccerary operations
         // (e.g. start home recursively) when creating home stack.
         mSupervisor.beginDeferResume();
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 1355424..df97caa 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -69,7 +69,7 @@
 
     private final ActivityTaskManagerService mService;
     private final ActivityStackSupervisor mSupervisor;
-    private final RootActivityContainer mRootActivityContainer;
+    private final RootWindowContainer mRootWindowContainer;
     private final Context mServiceContext;
 
     // UserManager cannot be final as it's not ready when this class is instantiated during boot
@@ -102,15 +102,15 @@
 
     ActivityStartInterceptor(
             ActivityTaskManagerService service, ActivityStackSupervisor supervisor) {
-        this(service, supervisor, service.mRootActivityContainer, service.mContext);
+        this(service, supervisor, service.mRootWindowContainer, service.mContext);
     }
 
     @VisibleForTesting
     ActivityStartInterceptor(ActivityTaskManagerService service, ActivityStackSupervisor supervisor,
-            RootActivityContainer root, Context context) {
+            RootWindowContainer root, Context context) {
         mService = service;
         mSupervisor = supervisor;
-        mRootActivityContainer = root;
+        mRootWindowContainer = root;
         mServiceContext = context;
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 6ad439e..a2b9d95 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -144,7 +144,7 @@
     private static final int INVALID_LAUNCH_MODE = -1;
 
     private final ActivityTaskManagerService mService;
-    private final RootActivityContainer mRootActivityContainer;
+    private final RootWindowContainer mRootWindowContainer;
     private final ActivityStackSupervisor mSupervisor;
     private final ActivityStartInterceptor mInterceptor;
     private final ActivityStartController mController;
@@ -506,7 +506,7 @@
             ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
         mController = controller;
         mService = service;
-        mRootActivityContainer = service.mRootActivityContainer;
+        mRootWindowContainer = service.mRootWindowContainer;
         mSupervisor = supervisor;
         mInterceptor = interceptor;
         reset(true);
@@ -614,7 +614,7 @@
 
             int res;
             synchronized (mService.mGlobalLock) {
-                final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
+                final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
                 stack.mConfigWillChange = mRequest.globalConfig != null
                         && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
                 if (DEBUG_CONFIGURATION) {
@@ -845,7 +845,7 @@
         ActivityRecord sourceRecord = null;
         ActivityRecord resultRecord = null;
         if (resultTo != null) {
-            sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
+            sourceRecord = mRootWindowContainer.isInAnyStack(resultTo);
             if (DEBUG_RESULTS) {
                 Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
             }
@@ -1070,7 +1070,7 @@
 
                 if (DEBUG_PERMISSIONS_REVIEW) {
                     final ActivityStack focusedStack =
-                            mRootActivityContainer.getTopDisplayFocusedStack();
+                            mRootWindowContainer.getTopDisplayFocusedStack();
                     Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
                             true, false) + "} from uid " + callingUid + " on display "
                             + (focusedStack == null ? DEFAULT_DISPLAY : focusedStack.mDisplayId));
@@ -1104,7 +1104,7 @@
             r.appTimeTracker = sourceRecord.appTimeTracker;
         }
 
-        final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
+        final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
 
         // If we are starting an activity that is not from the same uid as the currently resumed
         // one, check whether app switches are allowed.
@@ -1438,7 +1438,7 @@
                 // update the configuration for changing to different display.
                 final ActivityRecord currentTop = startedActivityStack.topRunningActivity();
                 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
-                    mRootActivityContainer.ensureVisibilityAndConfig(
+                    mRootWindowContainer.ensureVisibilityAndConfig(
                             currentTop, currentTop.getDisplayId(),
                             true /* markFrozenIfConfigChanged */, false /* deferResume */);
                 }
@@ -1525,7 +1525,7 @@
 
         // If the activity being launched is the same as the one currently at the top, then
         // we need to check if it should only be launched once.
-        final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
+        final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
         startResult = deliverToCurrentTopIfNeeded(topStack);
         if (startResult != START_SUCCESS) {
             return startResult;
@@ -1567,7 +1567,7 @@
 
         mTargetStack.mLastPausedActivity = null;
 
-        mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
+        mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(
                 false /* forceSend */, mStartActivity);
 
         mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
@@ -1595,16 +1595,16 @@
                 // task stack to be focusable, then ensure that we now update the focused stack
                 // accordingly.
                 if (mTargetStack.isFocusable()
-                        && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
+                        && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
                     mTargetStack.moveToFront("startActivityInner");
                 }
-                mRootActivityContainer.resumeFocusedStacksTopActivities(
+                mRootWindowContainer.resumeFocusedStacksTopActivities(
                         mTargetStack, mStartActivity, mOptions);
             }
         } else if (mStartActivity != null) {
             mSupervisor.mRecentTasks.add(mStartActivity.getTask());
         }
-        mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
+        mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
 
         mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(),
                 preferredWindowingMode, mPreferredDisplayId, mTargetStack);
@@ -1644,7 +1644,7 @@
         // Do not start home activity if it cannot be launched on preferred display. We are not
         // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
         // fallback to launch on other displays.
-        if (r.isActivityTypeHome() && !mRootActivityContainer.canStartHomeOnDisplay(r.info,
+        if (r.isActivityTypeHome() && !mRootWindowContainer.canStartHomeOnDisplay(r.info,
                 mPreferredDisplayId, true /* allowInstrumenting */)) {
             Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
             return START_CANCELED;
@@ -1710,7 +1710,7 @@
             }
         }
 
-        mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */,
+        mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */,
                 targetTaskTop);
 
         setTargetStackIfNeeded(targetTaskTop);
@@ -1793,7 +1793,7 @@
         // For paranoia, make sure we have correctly resumed the top activity.
         topStack.mLastPausedActivity = null;
         if (mDoResume) {
-            mRootActivityContainer.resumeFocusedStacksTopActivities();
+            mRootWindowContainer.resumeFocusedStacksTopActivities();
         }
         ActivityOptions.abort(mOptions);
         if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
@@ -2046,7 +2046,7 @@
             if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
                 r.mTaskOverlay = true;
                 if (!mOptions.canTaskOverlayResume()) {
-                    final Task task = mRootActivityContainer.anyTaskForId(
+                    final Task task = mRootWindowContainer.anyTaskForId(
                             mOptions.getLaunchTaskId());
                     final ActivityRecord top = task != null
                             ? task.getTopNonFinishingActivity() : null;
@@ -2083,7 +2083,7 @@
         if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
             ActivityRecord checkedCaller = sourceRecord;
             if (checkedCaller == null) {
-                checkedCaller = mRootActivityContainer.getTopDisplayFocusedStack()
+                checkedCaller = mRootWindowContainer.getTopDisplayFocusedStack()
                         .topRunningNonDelayedActivityLocked(mNotTop);
             }
             if (!checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
@@ -2247,7 +2247,7 @@
         putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
         ActivityRecord intentActivity = null;
         if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
-            Task launchTask = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
+            Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
             if (launchTask != null) {
                 return launchTask;
             }
@@ -2255,17 +2255,17 @@
             if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
                 // There can be one and only one instance of single instance activity in the
                 // history, and it is always in its own unique task, so we do a special search.
-               intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
+                intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
                        mStartActivity.isActivityTypeHome());
             } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
                 // For the launch adjacent case we only want to put the activity in an existing
                 // task if the activity already exists in the history.
-                intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
+                intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
                         !(LAUNCH_SINGLE_TASK == mLaunchMode));
             } else {
                 // Otherwise find the best task to put the activity in.
                 intentActivity =
-                        mRootActivityContainer.findTask(mStartActivity, mPreferredDisplayId);
+                        mRootWindowContainer.findTask(mStartActivity, mPreferredDisplayId);
             }
         }
 
@@ -2382,11 +2382,11 @@
 
     private void resumeTargetStackIfNeeded() {
         if (mDoResume) {
-            mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
+            mRootWindowContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
         } else {
             ActivityOptions.abort(mOptions);
         }
-        mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
+        mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
     }
 
     private void setNewTask(Task taskToAffiliate) {
@@ -2478,7 +2478,7 @@
         }
 
         final ActivityStack currentStack = task != null ? task.getStack() : null;
-        final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
+        final ActivityStack focusedStack = mRootWindowContainer.getTopDisplayFocusedStack();
         if (currentStack != null) {
             if (focusedStack != currentStack) {
                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
@@ -2499,18 +2499,18 @@
 
         if (mPreferredDisplayId != DEFAULT_DISPLAY) {
             // Try to put the activity in a stack on a secondary display.
-            stack = mRootActivityContainer.getValidLaunchStackOnDisplay(
+            stack = mRootWindowContainer.getValidLaunchStackOnDisplay(
                     mPreferredDisplayId, r, aOptions, mLaunchParams);
             if (stack == null) {
                 // If source display is not suitable - look for topmost valid stack in the system.
                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
                         "computeStackFocus: Can't launch on mPreferredDisplayId="
                                 + mPreferredDisplayId + ", looking on all displays.");
-                stack = mRootActivityContainer.getNextValidLaunchStack(r, mPreferredDisplayId);
+                stack = mRootWindowContainer.getNextValidLaunchStack(r, mPreferredDisplayId);
             }
         }
         if (stack == null) {
-            stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
+            stack = mRootWindowContainer.getLaunchStack(r, aOptions, task, ON_TOP);
         }
         if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
                 + r + " stackId=" + stack.mStackId);
@@ -2520,7 +2520,7 @@
     /** Check if provided activity record can launch in currently focused stack. */
     // TODO: This method can probably be consolidated into getLaunchStack() below.
     private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
-        final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
+        final ActivityStack focusedStack = mRootWindowContainer.getTopDisplayFocusedStack();
         final boolean canUseFocusedStack;
         if (focusedStack.isActivityTypeAssistant()) {
             canUseFocusedStack = r.isActivityTypeAssistant();
@@ -2565,13 +2565,13 @@
             final boolean onTop =
                     (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
             final ActivityStack stack =
-                    mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams,
+                    mRootWindowContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams,
                             mRequest.realCallingPid, mRequest.realCallingUid);
             return stack;
         }
         // Otherwise handle adjacent launch.
 
-        final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
+        final ActivityStack focusedStack = mRootWindowContainer.getTopDisplayFocusedStack();
         // The parent activity doesn't want to launch the activity on top of itself, but
         // instead tries to put it onto other side in side-by-side mode.
         final ActivityStack parentStack = task != null ? task.getStack(): focusedStack;
@@ -2590,7 +2590,7 @@
                 // If parent was in docked stack, the natural place to launch another activity
                 // will be fullscreen, so it can appear alongside the docked window.
                 final int activityType =
-                        mRootActivityContainer.resolveActivityType(r, mOptions, task);
+                        mRootWindowContainer.resolveActivityType(r, mOptions, task);
                 return parentStack.getDisplay().getOrCreateStack(
                         WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
             } else {
@@ -2598,10 +2598,10 @@
                 // and if yes, we will launch into that stack. If not, we just put the new
                 // activity into parent's stack, because we can't find a better place.
                 final ActivityStack dockedStack =
-                        mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
+                        mRootWindowContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
                 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
                     // There is a docked stack, but it isn't visible, so we can't launch into that.
-                    return mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
+                    return mRootWindowContainer.getLaunchStack(r, aOptions, task, ON_TOP);
                 } else {
                     return dockedStack;
                 }
@@ -2808,7 +2808,7 @@
         prefix = prefix + "  ";
         pw.print(prefix);
         pw.print("mCurrentUser=");
-        pw.println(mRootActivityContainer.mCurrentUser);
+        pw.println(mRootWindowContainer.mCurrentUser);
         pw.print(prefix);
         pw.print("mLastStartReason=");
         pw.println(mLastStartReason);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 6f80feb..ac1dbc4 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -117,8 +117,8 @@
 import static com.android.server.wm.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
 import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
-import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_ONLY;
-import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
+import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_ONLY;
+import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
 import static com.android.server.wm.Task.LOCK_TASK_AUTH_DONT_LOCK;
 import static com.android.server.wm.Task.REPARENT_KEEP_STACK_AT_FRONT;
 import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE;
@@ -376,7 +376,7 @@
      */
     final Object mGlobalLockWithoutBoost = mGlobalLock;
     ActivityStackSupervisor mStackSupervisor;
-    RootActivityContainer mRootActivityContainer;
+    RootWindowContainer mRootWindowContainer;
     WindowManagerService mWindowManager;
     private UserManagerService mUserManager;
     private AppOpsService mAppOpsService;
@@ -862,15 +862,14 @@
     public void setWindowManager(WindowManagerService wm) {
         synchronized (mGlobalLock) {
             mWindowManager = wm;
-            // TODO(merge-root): Remove cast
-            mRootActivityContainer = (RootActivityContainer) wm.mRoot;
+            mRootWindowContainer = wm.mRoot;
             mTempConfig.setToDefaults();
             mTempConfig.setLocales(LocaleList.getDefault());
             mConfigurationSeq = mTempConfig.seq = 1;
-            mRootActivityContainer.onConfigurationChanged(mTempConfig);
+            mRootWindowContainer.onConfigurationChanged(mTempConfig);
             mLockTaskController.setWindowManager(wm);
             mStackSupervisor.setWindowManager(wm);
-            mRootActivityContainer.setWindowManager(wm);
+            mRootWindowContainer.setWindowManager(wm);
         }
     }
 
@@ -1341,7 +1340,7 @@
                 sourceToken = resultTo;
             }
 
-            sourceRecord = mRootActivityContainer.isInAnyStack(sourceToken);
+            sourceRecord = mRootWindowContainer.isInAnyStack(sourceToken);
             if (sourceRecord == null) {
                 throw new SecurityException("Called with bad activity token: " + sourceToken);
             }
@@ -2021,7 +2020,7 @@
     public void notifyActivityDrawn(IBinder token) {
         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
         synchronized (mGlobalLock) {
-            ActivityRecord r = mRootActivityContainer.isInAnyStack(token);
+            ActivityRecord r = mRootWindowContainer.isInAnyStack(token);
             if (r != null) {
                 r.getActivityStack().notifyActivityDrawnLocked(r);
             }
@@ -2058,7 +2057,7 @@
             synchronized (mGlobalLock) {
                 ActivityStack focusedStack = getTopDisplayFocusedStack();
                 if (focusedStack != null) {
-                    return mRootActivityContainer.getStackInfo(focusedStack.mStackId);
+                    return mRootWindowContainer.getStackInfo(focusedStack.mStackId);
                 }
                 return null;
             }
@@ -2074,14 +2073,14 @@
         final long callingId = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                final ActivityStack stack = mRootActivityContainer.getStack(stackId);
+                final ActivityStack stack = mRootWindowContainer.getStack(stackId);
                 if (stack == null) {
                     Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
                     return;
                 }
                 final ActivityRecord r = stack.topRunningActivity();
                 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
-                    mRootActivityContainer.resumeFocusedStacksTopActivities();
+                    mRootWindowContainer.resumeFocusedStacksTopActivities();
                 }
             }
         } finally {
@@ -2096,14 +2095,14 @@
         final long callingId = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                final Task task = mRootActivityContainer.anyTaskForId(taskId,
+                final Task task = mRootWindowContainer.anyTaskForId(taskId,
                         MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
                     return;
                 }
                 final ActivityRecord r = task.topRunningActivityLocked();
                 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
-                    mRootActivityContainer.resumeFocusedStacksTopActivities();
+                    mRootWindowContainer.resumeFocusedStacksTopActivities();
                 }
             }
         } finally {
@@ -2206,7 +2205,7 @@
             final long origId = Binder.clearCallingIdentity();
             try {
                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
-                final Task task = mRootActivityContainer.anyTaskForId(taskId);
+                final Task task = mRootWindowContainer.anyTaskForId(taskId);
                 if (task != null) {
                     return ActivityRecord.getStackLocked(token).moveTaskToBack(task);
                 }
@@ -2224,7 +2223,7 @@
         Rect rect = new Rect();
         try {
             synchronized (mGlobalLock) {
-                final Task task = mRootActivityContainer.anyTaskForId(taskId,
+                final Task task = mRootWindowContainer.anyTaskForId(taskId,
                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
                 if (task == null) {
                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
@@ -2247,7 +2246,7 @@
         synchronized (mGlobalLock) {
             enforceCallerIsRecentsOrHasPermission(
                     MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
-            final Task tr = mRootActivityContainer.anyTaskForId(id,
+            final Task tr = mRootWindowContainer.anyTaskForId(id,
                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
             if (tr != null) {
                 return tr.getTaskDescription();
@@ -2267,7 +2266,7 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                final Task task = mRootActivityContainer.anyTaskForId(taskId,
+                final Task task = mRootWindowContainer.anyTaskForId(taskId,
                         MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
                     Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
@@ -2403,7 +2402,7 @@
             }
         }
         try {
-            final Task task = mRootActivityContainer.anyTaskForId(taskId);
+            final Task task = mRootWindowContainer.anyTaskForId(taskId);
             if (task == null) {
                 Slog.d(TAG, "Could not find task for id: "+ taskId);
                 SafeActivityOptions.abort(options);
@@ -2547,7 +2546,7 @@
             if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
 
             final boolean allowed = isGetTasksAllowed("getTasks", callingPid, callingUid);
-            mRootActivityContainer.getRunningTasks(maxNum, list, ignoreActivityType,
+            mRootWindowContainer.getRunningTasks(maxNum, list, ignoreActivityType,
                     ignoreWindowingMode, callingUid, allowed, crossUser, callingProfileIds);
         }
 
@@ -2594,7 +2593,7 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                final Task task = mRootActivityContainer.anyTaskForId(taskId);
+                final Task task = mRootWindowContainer.anyTaskForId(taskId);
                 if (task == null) {
                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
                     return;
@@ -2603,7 +2602,7 @@
                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
                         + " to stackId=" + stackId + " toTop=" + toTop);
 
-                final ActivityStack stack = mRootActivityContainer.getStack(stackId);
+                final ActivityStack stack = mRootWindowContainer.getStack(stackId);
                 if (stack == null) {
                     throw new IllegalStateException(
                             "moveTaskToStack: No stack for stackId=" + stackId);
@@ -2631,7 +2630,7 @@
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                final ActivityStack stack = mRootActivityContainer.getStack(stackId);
+                final ActivityStack stack = mRootWindowContainer.getStack(stackId);
                 if (stack == null) {
                     Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
                     return;
@@ -2659,7 +2658,7 @@
                 if (xOffset == 0 && yOffset == 0) {
                     return;
                 }
-                final ActivityStack stack = mRootActivityContainer.getStack(stackId);
+                final ActivityStack stack = mRootWindowContainer.getStack(stackId);
                 if (stack == null) {
                     Slog.w(TAG, "offsetPinnedStackBounds: stackId " + stackId + " not found.");
                     return;
@@ -2706,7 +2705,7 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                final Task task = mRootActivityContainer.anyTaskForId(taskId,
+                final Task task = mRootWindowContainer.anyTaskForId(taskId,
                         MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
                     Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
@@ -2748,7 +2747,7 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                mRootActivityContainer.removeStacksInWindowingModes(windowingModes);
+                mRootWindowContainer.removeStacksInWindowingModes(windowingModes);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -2763,7 +2762,7 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                mRootActivityContainer.removeStacksWithActivityTypes(activityTypes);
+                mRootWindowContainer.removeStacksWithActivityTypes(activityTypes);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -2794,7 +2793,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                return mRootActivityContainer.getAllStackInfos(INVALID_DISPLAY);
+                return mRootWindowContainer.getAllStackInfos(INVALID_DISPLAY);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -2807,7 +2806,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                return mRootActivityContainer.getStackInfo(windowingMode, activityType);
+                return mRootWindowContainer.getStackInfo(windowingMode, activityType);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -2820,7 +2819,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                return mRootActivityContainer.getAllStackInfos(displayId);
+                return mRootWindowContainer.getAllStackInfos(displayId);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -2834,7 +2833,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                return mRootActivityContainer.getStackInfo(windowingMode, activityType, displayId);
+                return mRootWindowContainer.getStackInfo(windowingMode, activityType, displayId);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -2876,7 +2875,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                final Task task = mRootActivityContainer.anyTaskForId(taskId,
+                final Task task = mRootWindowContainer.anyTaskForId(taskId,
                         MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
                     return;
@@ -2918,7 +2917,7 @@
             return;
         }
 
-        final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
+        final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
         if (stack == null || task != stack.getTopMostTask()) {
             throw new IllegalArgumentException("Invalid task, not in foreground");
         }
@@ -2933,7 +2932,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             // When a task is locked, dismiss the pinned stack if it exists
-            mRootActivityContainer.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
+            mRootWindowContainer.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
 
             getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
         } finally {
@@ -3035,7 +3034,7 @@
             try {
                 // TODO: VI Consider treating local voice interactions and voice tasks
                 // differently here
-                mRootActivityContainer.finishVoiceTask(session);
+                mRootWindowContainer.finishVoiceTask(session);
             } finally {
                 Binder.restoreCallingIdentity(origId);
             }
@@ -3230,7 +3229,7 @@
     @Override
     public void setTaskResizeable(int taskId, int resizeableMode) {
         synchronized (mGlobalLock) {
-            final Task task = mRootActivityContainer.anyTaskForId(
+            final Task task = mRootWindowContainer.anyTaskForId(
                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
             if (task == null) {
                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
@@ -3246,7 +3245,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                final Task task = mRootActivityContainer.anyTaskForId(taskId,
+                final Task task = mRootWindowContainer.anyTaskForId(taskId,
                         MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
@@ -3438,7 +3437,7 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                final ActivityStack stack = mRootActivityContainer.getStack(stackId);
+                final ActivityStack stack = mRootWindowContainer.getStack(stackId);
                 if (stack == null) {
                     Slog.w(TAG, "removeStack: No stack with id=" + stackId);
                     return;
@@ -3463,7 +3462,7 @@
             try {
                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
                         + " to displayId=" + displayId);
-                mRootActivityContainer.moveStackToDisplay(stackId, displayId, ON_TOP);
+                mRootWindowContainer.moveStackToDisplay(stackId, displayId, ON_TOP);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -3949,13 +3948,13 @@
             try {
                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
                         + taskId + " in stackId=" + stackId + " at position=" + position);
-                final Task task = mRootActivityContainer.anyTaskForId(taskId);
+                final Task task = mRootWindowContainer.anyTaskForId(taskId);
                 if (task == null) {
                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
                             + taskId);
                 }
 
-                final ActivityStack stack = mRootActivityContainer.getStack(stackId);
+                final ActivityStack stack = mRootWindowContainer.getStack(stackId);
 
                 if (stack == null) {
                     throw new IllegalArgumentException("positionTaskInStack: no stack for id="
@@ -4011,7 +4010,7 @@
         try {
             synchronized (mGlobalLock) {
                 final ActivityStack stack =
-                        mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
+                        mRootWindowContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
                 if (stack == null) {
                     Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
                     return;
@@ -4052,7 +4051,7 @@
         try {
             synchronized (mGlobalLock) {
                 final ActivityStack stack =
-                        mRootActivityContainer.getDefaultDisplay().getPinnedStack();
+                        mRootWindowContainer.getDefaultDisplay().getPinnedStack();
                 if (stack == null) {
                     Slog.w(TAG, "dismissPip: pinned stack not found.");
                     return;
@@ -4090,7 +4089,7 @@
         synchronized (mGlobalLock) {
             final long origId = Binder.clearCallingIdentity();
             try {
-                final ActivityStack stack = mRootActivityContainer.getStack(fromStackId);
+                final ActivityStack stack = mRootWindowContainer.getStack(fromStackId);
                 if (stack != null){
                     if (!stack.isActivityTypeStandardOrUndefined()) {
                         throw new IllegalArgumentException(
@@ -4125,7 +4124,7 @@
 
             long ident = Binder.clearCallingIdentity();
             try {
-                return mRootActivityContainer.moveTopStackActivityToPinnedStack(stackId);
+                return mRootWindowContainer.moveTopStackActivityToPinnedStack(stackId);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -4206,7 +4205,7 @@
                         // Adjust the source bounds by the insets for the transition down
                         final Rect sourceBounds = new Rect(
                                 r.pictureInPictureArgs.getSourceRectHint());
-                        mRootActivityContainer.moveActivityToPinnedStack(
+                        mRootWindowContainer.moveActivityToPinnedStack(
                                 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
                         final ActivityStack stack = r.getActivityStack();
                         stack.setPictureInPictureAspectRatio(aspectRatio);
@@ -4538,7 +4537,7 @@
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                final Task task = mRootActivityContainer.anyTaskForId(taskId,
+                final Task task = mRootWindowContainer.anyTaskForId(taskId,
                         MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
@@ -4566,7 +4565,7 @@
             boolean restoreFromDisk) {
         final Task task;
         synchronized (mGlobalLock) {
-            task = mRootActivityContainer.anyTaskForId(taskId,
+            task = mRootWindowContainer.anyTaskForId(taskId,
                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
             if (task == null) {
                 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
@@ -4743,7 +4742,7 @@
                 "registerRemoteAnimations");
         definition.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid());
         synchronized (mGlobalLock) {
-            final DisplayContent display = mRootActivityContainer.getDisplayContent(displayId);
+            final DisplayContent display = mRootWindowContainer.getDisplayContent(displayId);
             if (display == null) {
                 Slog.e(TAG, "Couldn't find display with id: " + displayId);
                 return;
@@ -4849,7 +4848,7 @@
         if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
             Slog.i(TAG, "Moving " + r.shortComponentName + " from display " + r.getDisplayId()
                     + " to main display for VR");
-            mRootActivityContainer.moveStackToDisplay(
+            mRootWindowContainer.moveStackToDisplay(
                     r.getStackId(), DEFAULT_DISPLAY, true /* toTop */);
         }
         mH.post(() -> {
@@ -4862,7 +4861,7 @@
                 if (disableNonVrUi) {
                     // If we are in a VR mode where Picture-in-Picture mode is unsupported,
                     // then remove the pinned stack.
-                    mRootActivityContainer.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
+                    mRootWindowContainer.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
                 }
             }
         });
@@ -4914,7 +4913,7 @@
     }
 
     ActivityStack getTopDisplayFocusedStack() {
-        return mRootActivityContainer.getTopDisplayFocusedStack();
+        return mRootWindowContainer.getTopDisplayFocusedStack();
     }
 
     /** Pokes the task persister. */
@@ -4952,7 +4951,7 @@
         final long origId = Binder.clearCallingIdentity();
         try {
             final DisplayContent display =
-                    mRootActivityContainer.getDisplayContentOrCreate(displayId);
+                    mRootWindowContainer.getDisplayContentOrCreate(displayId);
             if (display != null) {
                 display.setDisplayToSingleTaskInstance();
             }
@@ -5048,12 +5047,12 @@
             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
         pw.println(header);
 
-        boolean printedAnything = mRootActivityContainer.dumpActivities(fd, pw, dumpAll, dumpClient,
+        boolean printedAnything = mRootWindowContainer.dumpActivities(fd, pw, dumpAll, dumpClient,
                 dumpPackage);
         boolean needSep = printedAnything;
 
         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
-                mRootActivityContainer.getTopResumedActivity(),  dumpPackage, needSep,
+                mRootWindowContainer.getTopResumedActivity(),  dumpPackage, needSep,
                 "  ResumedActivity: ");
         if (printed) {
             printedAnything = true;
@@ -5075,7 +5074,7 @@
 
     void dumpActivityContainersLocked(PrintWriter pw) {
         pw.println("ACTIVITY MANAGER CONTAINERS (dumpsys activity containers)");
-        mRootActivityContainer.dumpChildrenNames(pw, " ");
+        mRootWindowContainer.dumpChildrenNames(pw, " ");
         pw.println(" ");
     }
 
@@ -5102,7 +5101,7 @@
         ArrayList<ActivityRecord> activities;
 
         synchronized (mGlobalLock) {
-            activities = mRootActivityContainer.getDumpActivities(name, dumpVisibleStacksOnly,
+            activities = mRootWindowContainer.getDumpActivities(name, dumpVisibleStacksOnly,
                     dumpFocusedStackOnly);
         }
 
@@ -5180,7 +5179,7 @@
         final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
         proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
                 PowerManagerInternal.wakefulnessToProtoEnum(wakeFullness));
-        for (ActivityTaskManagerInternal.SleepToken st : mRootActivityContainer.mSleepTokens) {
+        for (ActivityTaskManagerInternal.SleepToken st : mRootWindowContainer.mSleepTokens) {
             proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
                     st.toString());
         }
@@ -5216,10 +5215,10 @@
      * also corresponds to the merged configuration of the default display.
      */
     Configuration getGlobalConfiguration() {
-        // Return default configuration before mRootActivityContainer initialized, which happens
+        // Return default configuration before mRootWindowContainer initialized, which happens
         // while initializing process record for system, see {@link
         // ActivityManagerService#setSystemProcess}.
-        return mRootActivityContainer != null ? mRootActivityContainer.getConfiguration()
+        return mRootWindowContainer != null ? mRootWindowContainer.getConfiguration()
                 : new Configuration();
     }
 
@@ -5293,7 +5292,7 @@
             boolean persistent, int userId, boolean deferResume) {
 
         final DisplayContent defaultDisplay =
-                mRootActivityContainer.getDisplayContent(DEFAULT_DISPLAY);
+                mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY);
 
         mTempConfig.setTo(getGlobalConfiguration());
         final int changes = mTempConfig.updateFrom(values);
@@ -5351,7 +5350,7 @@
         mTempConfig.seq = increaseConfigurationSeqLocked();
 
         // Update stored global config and notify everyone about the change.
-        mRootActivityContainer.onConfigurationChanged(mTempConfig);
+        mRootWindowContainer.onConfigurationChanged(mTempConfig);
 
         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
         // TODO(multi-display): Update UsageEvents#Event to include displayId.
@@ -5399,7 +5398,7 @@
 
         // Override configuration of the default display duplicates global config, so we need to
         // update it also. This will also notify WindowManager about changes.
-        defaultDisplay.performDisplayOverrideConfigUpdate(mRootActivityContainer.getConfiguration(),
+        defaultDisplay.performDisplayOverrideConfigUpdate(mRootWindowContainer.getConfiguration(),
                 deferResume);
 
         return changes;
@@ -5549,7 +5548,7 @@
                     mCurAppTimeTracker.stop();
                     mH.obtainMessage(
                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
-                    mRootActivityContainer.clearOtherAppTimeTrackers(r.appTimeTracker);
+                    mRootWindowContainer.clearOtherAppTimeTrackers(r.appTimeTracker);
                     mCurAppTimeTracker = null;
                 }
                 if (r.appTimeTracker != null) {
@@ -5611,14 +5610,14 @@
     ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
         synchronized (mGlobalLock) {
             final ActivityTaskManagerInternal.SleepToken token =
-                    mRootActivityContainer.createSleepToken(tag, displayId);
+                    mRootWindowContainer.createSleepToken(tag, displayId);
             updateSleepIfNeededLocked();
             return token;
         }
     }
 
     void updateSleepIfNeededLocked() {
-        final boolean shouldSleep = !mRootActivityContainer.hasAwakeDisplay();
+        final boolean shouldSleep = !mRootWindowContainer.hasAwakeDisplay();
         final boolean wasSleeping = mSleeping;
         boolean updateOomAdj = false;
 
@@ -5635,7 +5634,7 @@
                 Slog.d(TAG, "Top Process State changed to PROCESS_STATE_TOP");
                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
             }
-            mRootActivityContainer.applySleepTokens(true /* applyToStacks */);
+            mRootWindowContainer.applySleepTokens(true /* applyToStacks */);
             if (wasSleeping) {
                 updateOomAdj = true;
             }
@@ -5848,7 +5847,7 @@
 
     // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
     private void startTimeTrackingFocusedActivityLocked() {
-        final ActivityRecord resumedActivity = mRootActivityContainer.getTopResumedActivity();
+        final ActivityRecord resumedActivity = mRootWindowContainer.getTopResumedActivity();
         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
             mCurAppTimeTracker.start(resumedActivity.packageName);
         }
@@ -5873,7 +5872,7 @@
     /** Applies latest configuration and/or visibility updates if needed. */
     boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
         boolean kept = true;
-        final ActivityStack mainStack = mRootActivityContainer.getTopDisplayFocusedStack();
+        final ActivityStack mainStack = mRootWindowContainer.getTopDisplayFocusedStack();
         // mainStack is null during startup.
         if (mainStack != null) {
             if (changes != 0 && starting == null) {
@@ -5888,7 +5887,7 @@
                         false /* preserveWindow */);
                 // And we need to make sure at this point that all other activities
                 // are made visible with the correct configuration.
-                mRootActivityContainer.ensureActivitiesVisible(starting, changes,
+                mRootWindowContainer.ensureActivitiesVisible(starting, changes,
                         !PRESERVE_WINDOWS);
             }
         }
@@ -6173,7 +6172,7 @@
         public ComponentName getHomeActivityForUser(int userId) {
             synchronized (mGlobalLock) {
                 final ActivityRecord homeActivity =
-                        mRootActivityContainer.getDefaultDisplayHomeActivityForUser(userId);
+                        mRootWindowContainer.getDefaultDisplayHomeActivityForUser(userId);
                 return homeActivity == null ? null : homeActivity.mActivityComponent;
             }
         }
@@ -6208,14 +6207,14 @@
         @Override
         public List<IBinder> getTopVisibleActivities() {
             synchronized (mGlobalLock) {
-                return mRootActivityContainer.getTopVisibleActivities();
+                return mRootWindowContainer.getTopVisibleActivities();
             }
         }
 
         @Override
         public void notifyDockedStackMinimizedChanged(boolean minimized) {
             synchronized (mGlobalLock) {
-                mRootActivityContainer.setDockedStackMinimized(minimized);
+                mRootWindowContainer.setDockedStackMinimized(minimized);
             }
         }
 
@@ -6300,7 +6299,7 @@
                 // We might change the visibilities here, so prepare an empty app transition which
                 // might be overridden later if we actually change visibilities.
                 final DisplayContent displayContent =
-                        mRootActivityContainer.getDisplayContent(displayId);
+                        mRootWindowContainer.getDisplayContent(displayId);
                 if (displayContent == null) {
                     return;
                 }
@@ -6310,7 +6309,7 @@
                 if (!wasTransitionSet) {
                     dc.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
                 }
-                mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+                mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
 
                 // If there was a transition set already we don't want to interfere with it as we
                 // might be starting it too early.
@@ -6327,7 +6326,7 @@
         public void notifyKeyguardTrustedChanged() {
             synchronized (mGlobalLock) {
                 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
-                    mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+                    mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
                 }
             }
         }
@@ -6354,7 +6353,7 @@
                             "setFocusedActivity: No activity record matching token=" + token);
                 }
                 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
-                    mRootActivityContainer.resumeFocusedStacksTopActivities();
+                    mRootWindowContainer.resumeFocusedStacksTopActivities();
                 }
             }
         }
@@ -6512,7 +6511,7 @@
         public boolean shuttingDown(boolean booted, int timeout) {
             synchronized (mGlobalLock) {
                 mShuttingDown = true;
-                mRootActivityContainer.prepareForShutdown();
+                mRootWindowContainer.prepareForShutdown();
                 updateEventDispatchingLocked(booted);
                 notifyTaskPersisterLocked(null, true);
                 return mStackSupervisor.shutdownLocked(timeout);
@@ -6618,7 +6617,7 @@
         @Override
         public void onPackageReplaced(ApplicationInfo aInfo) {
             synchronized (mGlobalLock) {
-                mRootActivityContainer.updateActivityApplicationInfo(aInfo);
+                mRootWindowContainer.updateActivityApplicationInfo(aInfo);
             }
         }
 
@@ -6652,7 +6651,7 @@
             }
             synchronized (mGlobalLock) {
                 final DisplayContent displayContent =
-                        mRootActivityContainer.getDisplayContent(displayId);
+                        mRootWindowContainer.getDisplayContent(displayId);
                 if (displayContent == null) {
                     // Call might come when display is not yet added or has been removed.
                     if (DEBUG_CONFIGURATION) {
@@ -6699,7 +6698,7 @@
         @Override
         public ActivityTokens getTopActivityForTask(int taskId) {
             synchronized (mGlobalLock) {
-                final Task task = mRootActivityContainer.anyTaskForId(taskId);
+                final Task task = mRootWindowContainer.anyTaskForId(taskId);
                 if (task == null) {
                     Slog.w(TAG, "getApplicationThreadForTopActivity failed:"
                             + " Requested task not found");
@@ -6758,7 +6757,7 @@
         @Override
         public boolean startHomeActivity(int userId, String reason) {
             synchronized (mGlobalLock) {
-                return mRootActivityContainer.startHomeOnDisplay(userId, reason, DEFAULT_DISPLAY);
+                return mRootWindowContainer.startHomeOnDisplay(userId, reason, DEFAULT_DISPLAY);
             }
         }
 
@@ -6766,7 +6765,7 @@
         public boolean startHomeOnDisplay(int userId, String reason, int displayId,
                 boolean allowInstrumenting, boolean fromHomeKey) {
             synchronized (mGlobalLock) {
-                return mRootActivityContainer.startHomeOnDisplay(userId, reason, displayId,
+                return mRootWindowContainer.startHomeOnDisplay(userId, reason, displayId,
                         allowInstrumenting, fromHomeKey);
             }
         }
@@ -6774,7 +6773,7 @@
         @Override
         public boolean startHomeOnAllDisplays(int userId, String reason) {
             synchronized (mGlobalLock) {
-                return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
+                return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
             }
         }
 
@@ -6840,7 +6839,7 @@
                 Runnable finishInstrumentationCallback) {
             synchronized (mGlobalLockWithoutBoost) {
                 // Remove this application's activities from active lists.
-                boolean hasVisibleActivities = mRootActivityContainer.handleAppDied(wpc);
+                boolean hasVisibleActivities = mRootWindowContainer.handleAppDied(wpc);
 
                 wpc.clearRecentTasks();
                 wpc.clearActivities();
@@ -6852,12 +6851,12 @@
                 if (!restarting && hasVisibleActivities) {
                     deferWindowLayout();
                     try {
-                        if (!mRootActivityContainer.resumeFocusedStacksTopActivities()) {
+                        if (!mRootWindowContainer.resumeFocusedStacksTopActivities()) {
                             // If there was nothing to resume, and we are not already restarting
                             // this process, but there is a visible activity that is hosted by the
                             // process...then make sure all visible activities are running, taking
                             // care of restarting this process.
-                            mRootActivityContainer.ensureActivitiesVisible(null, 0,
+                            mRootWindowContainer.ensureActivitiesVisible(null, 0,
                                     !PRESERVE_WINDOWS);
                         }
                     } finally {
@@ -6888,7 +6887,7 @@
                     }
                     mWindowManager.closeSystemDialogs(reason);
 
-                    mRootActivityContainer.closeSystemDialogs();
+                    mRootWindowContainer.closeSystemDialogs();
                 }
                 // Call into AM outside the synchronized block.
                 mAmInternal.broadcastCloseSystemDialogs(reason);
@@ -6902,9 +6901,9 @@
                 String packageName, Set<String> disabledClasses, int userId, boolean booted) {
             synchronized (mGlobalLock) {
                 // Clean-up disabled activities.
-                if (mRootActivityContainer.finishDisabledPackageActivities(
+                if (mRootWindowContainer.finishDisabledPackageActivities(
                         packageName, disabledClasses, true, false, userId) && booted) {
-                    mRootActivityContainer.resumeFocusedStacksTopActivities();
+                    mRootWindowContainer.resumeFocusedStacksTopActivities();
                     mStackSupervisor.scheduleIdleLocked();
                 }
 
@@ -6921,7 +6920,7 @@
 
                 boolean didSomething =
                         getActivityStartController().clearPendingActivityLaunches(packageName);
-                didSomething |= mRootActivityContainer.finishDisabledPackageActivities(packageName,
+                didSomething |= mRootWindowContainer.finishDisabledPackageActivities(packageName,
                         null, doit, evenPersistent, userId);
                 return didSomething;
             }
@@ -6930,7 +6929,7 @@
         @Override
         public void resumeTopActivities(boolean scheduleIdle) {
             synchronized (mGlobalLock) {
-                mRootActivityContainer.resumeFocusedStacksTopActivities();
+                mRootWindowContainer.resumeFocusedStacksTopActivities();
                 if (scheduleIdle) {
                     mStackSupervisor.scheduleIdleLocked();
                 }
@@ -6953,7 +6952,7 @@
                     Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
                 }
                 try {
-                    return mRootActivityContainer.attachApplication(wpc);
+                    return mRootWindowContainer.attachApplication(wpc);
                 } finally {
                     Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                 }
@@ -6978,7 +6977,7 @@
                             // Showing launcher to avoid user entering credential twice.
                             startHomeActivity(currentUserId, "notifyLockedProfile");
                         }
-                        mRootActivityContainer.lockAllProfileTasks(userId);
+                        mRootWindowContainer.lockAllProfileTasks(userId);
                     }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
@@ -7010,7 +7009,7 @@
             synchronized (mGlobalLock) {
                 // The output proto of "activity --proto activities"
                 // is ActivityManagerServiceDumpActivitiesProto
-                mRootActivityContainer.dumpDebug(proto,
+                mRootWindowContainer.dumpDebug(proto,
                         ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR,
                         WindowTraceLogLevel.ALL);
             }
@@ -7106,7 +7105,7 @@
                 }
                 if (dumpPackage == null) {
                     pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
-                    mRootActivityContainer.dumpDisplayConfigs(pw, "  ");
+                    mRootWindowContainer.dumpDisplayConfigs(pw, "  ");
                 }
                 if (dumpAll) {
                     if (dumpPackage == null) {
@@ -7134,7 +7133,7 @@
                 if (dumpPackage == null) {
                     pw.println("  mWakefulness="
                             + PowerManagerInternal.wakefulnessToString(wakefulness));
-                    pw.println("  mSleepTokens=" + mRootActivityContainer.mSleepTokens);
+                    pw.println("  mSleepTokens=" + mRootWindowContainer.mSleepTokens);
                     if (mRunningVoice != null) {
                         pw.println("  mRunningVoice=" + mRunningVoice);
                         pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
@@ -7273,7 +7272,7 @@
         @Override
         public boolean canGcNow() {
             synchronized (mGlobalLock) {
-                return isSleeping() || mRootActivityContainer.allResumedActivitiesIdle();
+                return isSleeping() || mRootWindowContainer.allResumedActivitiesIdle();
             }
         }
 
@@ -7281,12 +7280,12 @@
         @Override
         public WindowProcessController getTopApp() {
             synchronized (mGlobalLockWithoutBoost) {
-                if (mRootActivityContainer == null) {
-                    // Return null if mRootActivityContainer not yet initialize, while update
+                if (mRootWindowContainer == null) {
+                    // Return null if mRootWindowContainer not yet initialize, while update
                     // oomadj after AMS created.
                     return null;
                 }
-                final ActivityRecord top = mRootActivityContainer.getTopResumedActivity();
+                final ActivityRecord top = mRootWindowContainer.getTopResumedActivity();
                 return top != null ? top.app : null;
             }
         }
@@ -7295,8 +7294,8 @@
         @Override
         public void rankTaskLayersIfNeeded() {
             synchronized (mGlobalLockWithoutBoost) {
-                if (mRootActivityContainer != null) {
-                    mRootActivityContainer.rankTaskLayersIfNeeded();
+                if (mRootWindowContainer != null) {
+                    mRootWindowContainer.rankTaskLayersIfNeeded();
                 }
             }
         }
@@ -7304,35 +7303,35 @@
         @Override
         public void scheduleDestroyAllActivities(String reason) {
             synchronized (mGlobalLock) {
-                mRootActivityContainer.scheduleDestroyAllActivities(reason);
+                mRootWindowContainer.scheduleDestroyAllActivities(reason);
             }
         }
 
         @Override
         public void removeUser(int userId) {
             synchronized (mGlobalLock) {
-                mRootActivityContainer.removeUser(userId);
+                mRootWindowContainer.removeUser(userId);
             }
         }
 
         @Override
         public boolean switchUser(int userId, UserState userState) {
             synchronized (mGlobalLock) {
-                return mRootActivityContainer.switchUser(userId, userState);
+                return mRootWindowContainer.switchUser(userId, userState);
             }
         }
 
         @Override
         public void onHandleAppCrash(WindowProcessController wpc) {
             synchronized (mGlobalLock) {
-                mRootActivityContainer.handleAppCrash(wpc);
+                mRootWindowContainer.handleAppCrash(wpc);
             }
         }
 
         @Override
         public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
             synchronized (mGlobalLock) {
-                return mRootActivityContainer.finishTopCrashedActivities(crashedApp, reason);
+                return mRootWindowContainer.finishTopCrashedActivities(crashedApp, reason);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 6d9584c..357f9e5 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -17,7 +17,7 @@
 package com.android.server.wm;
 
 import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
-import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
+import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
 
 import android.app.ActivityManager;
 import android.app.IAppTask;
@@ -79,7 +79,7 @@
         synchronized (mService.mGlobalLock) {
             long origId = Binder.clearCallingIdentity();
             try {
-                Task task = mService.mRootActivityContainer.anyTaskForId(mTaskId,
+                Task task = mService.mRootWindowContainer.anyTaskForId(mTaskId,
                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
                 if (task == null) {
                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
@@ -139,7 +139,7 @@
         Task task;
         IApplicationThread appThread;
         synchronized (mService.mGlobalLock) {
-            task = mService.mRootActivityContainer.anyTaskForId(mTaskId,
+            task = mService.mRootWindowContainer.anyTaskForId(mTaskId,
                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
             if (task == null) {
                 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
@@ -167,7 +167,7 @@
         synchronized (mService.mGlobalLock) {
             long origId = Binder.clearCallingIdentity();
             try {
-                Task task = mService.mRootActivityContainer.anyTaskForId(mTaskId,
+                Task task = mService.mRootWindowContainer.anyTaskForId(mTaskId,
                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
                 if (task == null) {
                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index f696bb2..51742b9 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -125,7 +125,7 @@
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
 import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
-import static com.android.server.wm.RootActivityContainer.TAG_STATES;
+import static com.android.server.wm.RootWindowContainer.TAG_STATES;
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
@@ -605,7 +605,7 @@
      */
     private static int sNextFreeStackId = 0;
 
-    private RootActivityContainer mRootActivityContainer;
+    private RootWindowContainer mRootWindowContainer;
 
     /**
      * All of the stacks on this display. Order matters, topmost stack is in front of all other
@@ -663,8 +663,8 @@
     // Used in updating override configurations
     private final Configuration mTempConfig = new Configuration();
 
-    private final RootActivityContainer.FindTaskResult
-            mTmpFindTaskResult = new RootActivityContainer.FindTaskResult();
+    private final RootWindowContainer.FindTaskResult
+            mTmpFindTaskResult = new RootWindowContainer.FindTaskResult();
 
     private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
         WindowStateAnimator winAnimator = w.mWinAnimator;
@@ -950,9 +950,9 @@
      * Create new {@link DisplayContent} instance, add itself to the root window container and
      * initialize direct children.
      * @param display May not be null.
-     * @param root {@link RootActivityContainer}
+     * @param root {@link RootWindowContainer}
      */
-    DisplayContent(Display display, RootActivityContainer root) {
+    DisplayContent(Display display, RootWindowContainer root) {
         super(root.mWindowManager);
         if (mWmService.mRoot.getDisplayContent(display.getDisplayId()) != null) {
             throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
@@ -961,7 +961,7 @@
                     + " new=" + display);
         }
 
-        mRootActivityContainer = root;
+        mRootWindowContainer = root;
         mAtmService = mWmService.mAtmService;
         mDisplay = display;
         mDisplayId = display.getDisplayId();
@@ -1348,7 +1348,7 @@
                     false /* deferResume */, null /* result */);
             activityRecord.frozenBeforeDestroy = true;
             if (!kept) {
-                mWmService.mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
+                mRootWindowContainer.resumeFocusedStacksTopActivities();
             }
         } else {
             // We have a new configuration to push so we need to update ATMS for now.
@@ -5628,7 +5628,7 @@
             final ActivityStack currentFocusedStack = getFocusedStack();
             if (currentFocusedStack != prevFocusedStack) {
                 mLastFocusedStack = prevFocusedStack;
-                EventLogTags.writeWmFocusedStack(mRootActivityContainer.mCurrentUser, mDisplayId,
+                EventLogTags.writeWmFocusedStack(mRootWindowContainer.mCurrentUser, mDisplayId,
                         currentFocusedStack == null ? -1 : currentFocusedStack.getStackId(),
                         mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(),
                         updateLastFocusedStackReason);
@@ -5713,7 +5713,7 @@
             // Create stack on default display instead since this display can only contain 1 stack.
             // TODO: Kinda a hack, but better that having the decision at each call point. Hoping
             // this goes away once ActivityView is no longer using virtual displays.
-            return mRootActivityContainer.getDefaultDisplay().createStack(
+            return mRootWindowContainer.getDefaultDisplay().createStack(
                     windowingMode, activityType, onTop);
         }
 
@@ -5753,7 +5753,7 @@
                     + "activity type.");
         }
         final ActivityStack stack = new ActivityStack(this, stackId,
-                mRootActivityContainer.mStackSupervisor, activityType);
+                mRootWindowContainer.mStackSupervisor, activityType);
         addStack(stack, onTop ? POSITION_TOP : POSITION_BOTTOM);
         stack.setWindowingMode(windowingMode, false /* animate */, false /* showRecents */,
                 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */,
@@ -5888,7 +5888,7 @@
      * Find task for putting the Activity in.
      */
     void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplay,
-            RootActivityContainer.FindTaskResult result) {
+            RootWindowContainer.FindTaskResult result) {
         mTmpFindTaskResult.clear();
         for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
             final ActivityStack stack = getStackAt(stackNdx);
@@ -5947,7 +5947,7 @@
         }
 
         for (int i = stacks.size() - 1; i >= 0; --i) {
-            mRootActivityContainer.mStackSupervisor.removeStack(stacks.get(i));
+            mRootWindowContainer.mStackSupervisor.removeStack(stacks.get(i));
         }
     }
 
@@ -5971,7 +5971,7 @@
         }
 
         for (int i = stacks.size() - 1; i >= 0; --i) {
-            mRootActivityContainer.mStackSupervisor.removeStack(stacks.get(i));
+            mRootWindowContainer.mStackSupervisor.removeStack(stacks.get(i));
         }
     }
 
@@ -6210,7 +6210,7 @@
         // This activity can be considered the top running activity if we are not considering
         // the locked state, the keyguard isn't locked, or we can show when locked.
         if (topRunning != null && considerKeyguardState
-                && mRootActivityContainer.mStackSupervisor.getKeyguardController()
+                && mRootWindowContainer.mStackSupervisor.getKeyguardController()
                         .isKeyguardLocked()
                 && !topRunning.canShowWhenLocked()) {
             return null;
@@ -6370,8 +6370,8 @@
         // released (no more ActivityStack). But, we cannot release it at that moment or the
         // related WindowContainer will also be removed. So, we set display as removed after
         // reparenting stack finished.
-        final DisplayContent toDisplay = mRootActivityContainer.getDefaultDisplay();
-        mRootActivityContainer.mStackSupervisor.beginDeferResume();
+        final DisplayContent toDisplay = mRootWindowContainer.getDefaultDisplay();
+        mRootWindowContainer.mStackSupervisor.beginDeferResume();
         try {
             int numStacks = getStackCount();
             // Keep the order from bottom to top.
@@ -6397,7 +6397,7 @@
                 numStacks = getStackCount();
             }
         } finally {
-            mRootActivityContainer.mStackSupervisor.endDeferResume();
+            mRootWindowContainer.mStackSupervisor.endDeferResume();
         }
         mRemoved = true;
 
@@ -6409,7 +6409,7 @@
         releaseSelfIfNeeded();
 
         if (!mAllSleepTokens.isEmpty()) {
-            mRootActivityContainer.mSleepTokens.removeAll(mAllSleepTokens);
+            mRootWindowContainer.mSleepTokens.removeAll(mAllSleepTokens);
             mAllSleepTokens.clear();
             mAtmService.updateSleepIfNeededLocked();
         }
@@ -6428,7 +6428,7 @@
             stack.removeIfPossible();
         } else if (getTopStack() == null) {
             removeIfPossible();
-            mRootActivityContainer.mStackSupervisor
+            mRootWindowContainer.mStackSupervisor
                     .getKeyguardController().onDisplayRemoved(mDisplayId);
         }
     }
@@ -6574,7 +6574,7 @@
 
     @Nullable
     ActivityRecord getHomeActivity() {
-        return getHomeActivityForUser(mRootActivityContainer.mCurrentUser);
+        return getHomeActivityForUser(mRootWindowContainer.mCurrentUser);
     }
 
     @Nullable
diff --git a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
index bb31d45..af13e3a 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
@@ -39,9 +39,9 @@
         synchronized (mService.mGlobalLock) {
             mDisplayListeners.register(listener);
             try {
-                for (int i = 0; i < mService.mAtmService.mRootActivityContainer.getChildCount();
+                for (int i = 0; i < mService.mAtmService.mRootWindowContainer.getChildCount();
                         ++i) {
-                    DisplayContent d = mService.mAtmService.mRootActivityContainer.getChildAt(i);
+                    DisplayContent d = mService.mAtmService.mRootWindowContainer.getChildAt(i);
                     listener.onDisplayAdded(d.mDisplayId);
                 }
             } catch (RemoteException e) { }
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index 949ff19..e74f61d 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -59,7 +59,7 @@
     /**
      * Ensure visibility with an option to also update the configuration of visible activities.
      * @see ActivityStack#ensureActivitiesVisible(ActivityRecord, int, boolean)
-     * @see RootActivityContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
+     * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
      */
     void process(ActivityRecord starting, int configChanges, boolean preserveWindows,
             boolean notifyClients) {
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 6f81957..7db30f6 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -73,7 +73,7 @@
     private int mVisibilityTransactionDepth;
     private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>();
     private final ActivityTaskManagerService mService;
-    private RootActivityContainer mRootActivityContainer;
+    private RootWindowContainer mRootWindowContainer;
 
     KeyguardController(ActivityTaskManagerService service,
             ActivityStackSupervisor stackSupervisor) {
@@ -83,7 +83,7 @@
 
     void setWindowManager(WindowManagerService windowManager) {
         mWindowManager = windowManager;
-        mRootActivityContainer = mService.mRootActivityContainer;
+        mRootWindowContainer = mService.mRootWindowContainer;
     }
 
     /**
@@ -165,7 +165,7 @@
         // Update the sleep token first such that ensureActivitiesVisible has correct sleep token
         // state when evaluating visibilities.
         updateKeyguardSleepToken();
-        mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+        mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
     }
 
     /**
@@ -187,16 +187,16 @@
                     mAodShowing ? 1 : 0,
                     1 /* keyguardGoingAway */,
                     "keyguardGoingAway");
-            mRootActivityContainer.getDefaultDisplay().mDisplayContent
+            mRootWindowContainer.getDefaultDisplay().mDisplayContent
                     .prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
                             false /* alwaysKeepCurrent */, convertTransitFlags(flags),
                             false /* forceOverride */);
             updateKeyguardSleepToken();
 
             // Some stack visibility might change (e.g. docked stack)
-            mRootActivityContainer.resumeFocusedStacksTopActivities();
-            mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
-            mRootActivityContainer.addStartingWindowsForVisibleActivities();
+            mRootWindowContainer.resumeFocusedStacksTopActivities();
+            mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+            mRootWindowContainer.addStartingWindowsForVisibleActivities();
             mWindowManager.executeAppTransition();
         } finally {
             mService.continueWindowLayout();
@@ -294,9 +294,9 @@
 
     private void visibilitiesUpdated() {
         boolean requestDismissKeyguard = false;
-        for (int displayNdx = mRootActivityContainer.getChildCount() - 1;
+        for (int displayNdx = mRootWindowContainer.getChildCount() - 1;
              displayNdx >= 0; displayNdx--) {
-            final DisplayContent display = mRootActivityContainer.getChildAt(displayNdx);
+            final DisplayContent display = mRootWindowContainer.getChildAt(displayNdx);
             final KeyguardDisplayState state = getDisplay(display.mDisplayId);
             state.visibilitiesUpdated(this, display);
             requestDismissKeyguard |= state.mRequestDismissKeyguard;
@@ -325,12 +325,12 @@
         if (isKeyguardLocked()) {
             mService.deferWindowLayout();
             try {
-                mRootActivityContainer.getDefaultDisplay().mDisplayContent
+                mRootWindowContainer.getDefaultDisplay().mDisplayContent
                         .prepareAppTransition(resolveOccludeTransit(),
                                 false /* alwaysKeepCurrent */, 0 /* flags */,
                                 true /* forceOverride */);
                 updateKeyguardSleepToken(DEFAULT_DISPLAY);
-                mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+                mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
                 mWindowManager.executeAppTransition();
             } finally {
                 mService.continueWindowLayout();
@@ -356,12 +356,12 @@
         // If we are about to unocclude the Keyguard, but we can dismiss it without security,
         // we immediately dismiss the Keyguard so the activity gets shown without a flicker.
         final DisplayContent dc =
-                mRootActivityContainer.getDefaultDisplay().mDisplayContent;
+                mRootWindowContainer.getDefaultDisplay().mDisplayContent;
         if (mKeyguardShowing && canDismissKeyguard()
                 && dc.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE) {
             dc.prepareAppTransition(mBeforeUnoccludeTransit, false /* alwaysKeepCurrent */,
                     0 /* flags */, true /* forceOverride */);
-            mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+            mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
             mWindowManager.executeAppTransition();
         }
     }
@@ -379,8 +379,7 @@
     }
 
     private int resolveOccludeTransit() {
-        final DisplayContent dc =
-                mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent;
+        final DisplayContent dc = mRootWindowContainer.getDefaultDisplay().mDisplayContent;
         if (mBeforeUnoccludeTransit != TRANSIT_UNSET
                 && dc.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE
                 // TODO(b/113840485): Handle app transition for individual display.
@@ -408,7 +407,7 @@
             // stack since it will be complicated/risky to try to put the activity on top
             // of the lock screen in the right fullscreen configuration.
             final ActivityStack stack =
-                    mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
+                    mRootWindowContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
             if (stack == null) {
                 return;
             }
@@ -418,9 +417,9 @@
     }
 
     private void updateKeyguardSleepToken() {
-        for (int displayNdx = mRootActivityContainer.getChildCount() - 1;
+        for (int displayNdx = mRootWindowContainer.getChildCount() - 1;
              displayNdx >= 0; displayNdx--) {
-            final DisplayContent display = mRootActivityContainer.getChildAt(displayNdx);
+            final DisplayContent display = mRootWindowContainer.getChildAt(displayNdx);
             updateKeyguardSleepToken(display.mDisplayId);
         }
     }
@@ -509,7 +508,7 @@
             }
             // TODO(b/123372519): isShowingDream can only works on default display.
             if (mDisplayId == DEFAULT_DISPLAY) {
-                mOccluded |= mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent
+                mOccluded |= mService.mRootWindowContainer.getDefaultDisplay().mDisplayContent
                         .getDisplayPolicy().isShowingDreamLw();
             }
 
diff --git a/services/core/java/com/android/server/wm/LaunchParamsPersister.java b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
index 8cf3dc8..0beae7e 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsPersister.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
@@ -224,7 +224,7 @@
         final ActivityStack stack = task.getStack();
         final int displayId = stack.mDisplayId;
         final DisplayContent display =
-                mSupervisor.mRootActivityContainer.getDisplayContent(displayId);
+                mSupervisor.mRootWindowContainer.getDisplayContent(displayId);
         final DisplayInfo info = new DisplayInfo();
         display.mDisplay.getDisplayInfo(info);
 
@@ -260,7 +260,7 @@
             return;
         }
 
-        final DisplayContent display = mSupervisor.mRootActivityContainer.getDisplayContent(
+        final DisplayContent display = mSupervisor.mRootWindowContainer.getDisplayContent(
                 persistableParams.mDisplayUniqueId);
         if (display != null) {
             outParams.mPreferredDisplayId =  display.mDisplayId;
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 0443c40..02413bb 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -459,7 +459,7 @@
             return;
         }
         task.performClearTaskLocked();
-        mSupervisor.mRootActivityContainer.resumeFocusedStacksTopActivities();
+        mSupervisor.mRootWindowContainer.resumeFocusedStacksTopActivities();
     }
 
     /**
@@ -591,7 +591,7 @@
         if (andResume) {
             mSupervisor.findTaskToMoveToFront(task, 0, null, reason,
                     lockTaskModeState != LOCK_TASK_MODE_NONE);
-            mSupervisor.mRootActivityContainer.resumeFocusedStacksTopActivities();
+            mSupervisor.mRootWindowContainer.resumeFocusedStacksTopActivities();
             final ActivityStack stack = task.getStack();
             if (stack != null) {
                 stack.getDisplay().mDisplayContent.executeAppTransition();
@@ -653,9 +653,9 @@
             taskChanged = true;
         }
 
-        mSupervisor.mRootActivityContainer.forAllTasks(Task::setLockTaskAuth);
+        mSupervisor.mRootWindowContainer.forAllTasks(Task::setLockTaskAuth);
 
-        final ActivityRecord r = mSupervisor.mRootActivityContainer.topRunningActivity();
+        final ActivityRecord r = mSupervisor.mRootWindowContainer.topRunningActivity();
         final Task task = (r != null) ? r.getTask() : null;
         if (mLockTaskModeTasks.isEmpty() && task!= null
                 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
@@ -667,7 +667,7 @@
         }
 
         if (taskChanged) {
-            mSupervisor.mRootActivityContainer.resumeFocusedStacksTopActivities();
+            mSupervisor.mRootWindowContainer.resumeFocusedStacksTopActivities();
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 71bbb70..a18d541 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -207,7 +207,7 @@
             mService.mH.post(PooledLambda.obtainRunnable((nonArg) -> {
                 synchronized (mService.mGlobalLock) {
                     // Unfreeze the task list once we touch down in a task
-                    final RootActivityContainer rac = mService.mRootActivityContainer;
+                    final RootWindowContainer rac = mService.mRootWindowContainer;
                     final DisplayContent dc = rac.getDisplayContent(displayId).mDisplayContent;
                     if (dc.pointWithinAppWindow(x, y)) {
                         final ActivityStack stack = mService.getTopDisplayFocusedStack();
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 0a8e747..647be0f 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -84,7 +84,7 @@
             @Nullable WindowProcessController caller) {
         mService = atm;
         mStackSupervisor = stackSupervisor;
-        mDefaultDisplay = mService.mRootActivityContainer.getDefaultDisplay();
+        mDefaultDisplay = mService.mRootWindowContainer.getDefaultDisplay();
         mActivityStartController = activityStartController;
         mWindowManager = wm;
         mTargetIntent = targetIntent;
@@ -165,7 +165,7 @@
 
         // TODO(multi-display) currently only support recents animation in default display.
         final DisplayContent dc =
-                mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent;
+                mService.mRootWindowContainer.getDefaultDisplay().mDisplayContent;
         if (!mWindowManager.canStartRecentsAnimation()) {
             notifyAnimationCancelBeforeStart(recentsAnimationRunner);
             ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
@@ -193,7 +193,7 @@
         // Send launch hint if we are actually launching the target. If it's already visible
         // (shouldn't happen in general) we don't need to send it.
         if (targetActivity == null || !targetActivity.mVisibleRequested) {
-            mService.mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
+            mService.mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(
                     true /* forceSend */, targetActivity);
         }
 
@@ -255,7 +255,7 @@
 
             // If we updated the launch-behind state, update the visibility of the activities after
             // we fetch the visible tasks to be controlled by the animation
-            mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
+            mService.mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
 
             mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState,
                     START_TASK_TO_FRONT, targetActivity);
@@ -288,7 +288,7 @@
             // Just to be sure end the launch hint in case the target activity was never launched.
             // However, if we're keeping the activity and making it visible, we can leave it on.
             if (reorderMode != REORDER_KEEP_IN_PLACE) {
-                mService.mRootActivityContainer.sendPowerHintForLaunchEndIfNeeded();
+                mService.mRootWindowContainer.sendPowerHintForLaunchEndIfNeeded();
             }
 
             // Once the target is shown, prevent spurious background app switches
@@ -381,8 +381,8 @@
                     }
 
                     mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
-                    mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, false);
-                    mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
+                    mService.mRootWindowContainer.ensureActivitiesVisible(null, 0, false);
+                    mService.mRootWindowContainer.resumeFocusedStacksTopActivities();
 
                     // No reason to wait for the pausing activity in this case, as the hiding of
                     // surfaces needs to be done immediately.
@@ -424,7 +424,7 @@
         }
 
         final DisplayContent dc =
-                mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent;
+                mService.mRootWindowContainer.getDefaultDisplay().mDisplayContent;
         dc.mBoundsAnimationController.setAnimationType(
                 controller.shouldDeferCancelUntilNextTransition() ? FADE_IN : BOUNDS);
 
diff --git a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
index d787cbc..f78c82b 100644
--- a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
+++ b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
@@ -261,7 +261,7 @@
         DisplayContent display = mParent.getDisplay();
         final boolean singleTaskInstanceDisplay = display.isSingleTaskInstance();
         if (singleTaskInstanceDisplay) {
-            display = mParent.mRootActivityContainer.getDefaultDisplay();
+            display = mParent.mRootWindowContainer.getDefaultDisplay();
         }
 
         final int windowingMode = mParent.getWindowingMode();
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
deleted file mode 100644
index c0077e4..0000000
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ /dev/null
@@ -1,2647 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.wm;
-
-import static android.app.ActivityTaskManager.INVALID_STACK_ID;
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
-import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Display.INVALID_DISPLAY;
-import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
-import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
-
-import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS;
-import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID;
-import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT;
-import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
-import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES;
-import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
-import static com.android.server.am.ActivityStackSupervisorProto.ROOT_WINDOW_CONTAINER;
-import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
-import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
-import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
-import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
-import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
-import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
-import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
-import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
-import static com.android.server.wm.ActivityTaskManagerService.TAG_SWITCH;
-import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE;
-import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
-
-import static java.lang.Integer.MAX_VALUE;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UserIdInt;
-import android.app.ActivityManager;
-import android.app.ActivityOptions;
-import android.app.AppGlobals;
-import android.app.WindowConfiguration;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ResolveInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManagerInternal;
-import android.hardware.power.V1_0.PowerHint;
-import android.net.Uri;
-import android.os.FactoryTest;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.service.voice.IVoiceInteractionSession;
-import android.util.ArraySet;
-import android.util.DisplayMetrics;
-import android.util.IntArray;
-import android.util.Pair;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-import android.util.TimeUtils;
-import android.util.proto.ProtoOutputStream;
-import android.view.Display;
-import android.view.DisplayInfo;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.ResolverActivity;
-import com.android.internal.util.function.pooled.PooledConsumer;
-import com.android.internal.util.function.pooled.PooledFunction;
-import com.android.internal.util.function.pooled.PooledLambda;
-import com.android.internal.util.function.pooled.PooledPredicate;
-import com.android.server.LocalServices;
-import com.android.server.am.ActivityManagerService;
-import com.android.server.am.AppTimeTracker;
-import com.android.server.am.UserState;
-import com.android.server.policy.WindowManagerPolicy;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.Function;
-
-/**
- * Root node for activity containers.
- * TODO: This class is mostly temporary to separate things out of ActivityStackSupervisor.java. The
- * intention is to have this merged with RootWindowContainer.java as part of unifying the hierarchy.
- */
-class RootActivityContainer extends RootWindowContainer
-        implements DisplayManager.DisplayListener {
-
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "RootActivityContainer" : TAG_ATM;
-    static final String TAG_TASKS = TAG + POSTFIX_TASKS;
-    private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
-    static final String TAG_STATES = TAG + POSTFIX_STATES;
-    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
-
-    /**
-     * The modes which affect which tasks are returned when calling
-     * {@link RootActivityContainer#anyTaskForId(int)}.
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-            MATCH_TASK_IN_STACKS_ONLY,
-            MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
-            MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
-    })
-    public @interface AnyTaskForIdMatchTaskMode {}
-    // Match only tasks in the current stacks
-    static final int MATCH_TASK_IN_STACKS_ONLY = 0;
-    // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
-    static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
-    // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
-    // provided stack id
-    static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
-
-    ActivityTaskManagerService mService;
-    ActivityStackSupervisor mStackSupervisor;
-    WindowManagerService mWindowManager;
-    DisplayManager mDisplayManager;
-    private DisplayManagerInternal mDisplayManagerInternal;
-
-    /** Reference to default display so we can quickly look it up. */
-    private DisplayContent mDefaultDisplay;
-    private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
-
-    /** The current user */
-    int mCurrentUser;
-    /** Stack id of the front stack when user switched, indexed by userId. */
-    SparseIntArray mUserStackInFront = new SparseIntArray(2);
-
-    /**
-     * A list of tokens that cause the top activity to be put to sleep.
-     * They are used by components that may hide and block interaction with underlying
-     * activities.
-     */
-    final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>();
-
-    /** Is dock currently minimized. */
-    boolean mIsDockMinimized;
-
-    /** Set when a power hint has started, but not ended. */
-    private boolean mPowerHintSent;
-
-    /** Used to keep ensureActivitiesVisible() from being entered recursively. */
-    private boolean mInEnsureActivitiesVisible = false;
-
-    // The default minimal size that will be used if the activity doesn't specify its minimal size.
-    // It will be calculated when the default display gets added.
-    int mDefaultMinSizeOfResizeableTaskDp = -1;
-
-    // Whether tasks have moved and we need to rank the tasks before next OOM scoring
-    private boolean mTaskLayersChanged = true;
-    private int mTmpTaskLayerRank;
-
-    private boolean mTmpBoolean;
-    private RemoteException mTmpRemoteException;
-
-    private String mDestroyAllActivitiesReason;
-    private final Runnable mDestroyAllActivitiesRunnable = new Runnable() {
-        @Override
-        public void run() {
-            synchronized (mService.mGlobalLock) {
-                try {
-                    mStackSupervisor.beginDeferResume();
-
-                    final PooledConsumer c = PooledLambda.obtainConsumer(
-                            RootActivityContainer::destroyActivity, RootActivityContainer.this,
-                            PooledLambda.__(ActivityRecord.class));
-                    forAllActivities(c);
-                    c.recycle();
-                } finally {
-                    mStackSupervisor.endDeferResume();
-                    resumeFocusedStacksTopActivities();
-                }
-            }
-        }
-
-    };
-
-    private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
-    static class FindTaskResult implements Function<Task, Boolean> {
-        ActivityRecord mRecord;
-        boolean mIdealMatch;
-
-        private ActivityRecord mTarget;
-        private Intent intent;
-        private ActivityInfo info;
-        private ComponentName cls;
-        private int userId;
-        private boolean isDocument;
-        private Uri documentData;
-
-        /**
-         * Returns the top activity in any existing task matching the given Intent in the input
-         * result. Returns null if no such task is found.
-         */
-        void process(ActivityRecord target, ActivityStack parent) {
-            mTarget = target;
-
-            intent = target.intent;
-            info = target.info;
-            cls = intent.getComponent();
-            if (info.targetActivity != null) {
-                cls = new ComponentName(info.packageName, info.targetActivity);
-            }
-            userId = UserHandle.getUserId(info.applicationInfo.uid);
-            isDocument = intent != null & intent.isDocument();
-            // If documentData is non-null then it must match the existing task data.
-            documentData = isDocument ? intent.getData() : null;
-
-            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + parent);
-            parent.forAllTasks(this);
-        }
-
-        void clear() {
-            mRecord = null;
-            mIdealMatch = false;
-        }
-
-        void setTo(FindTaskResult result) {
-            mRecord = result.mRecord;
-            mIdealMatch = result.mIdealMatch;
-        }
-
-        @Override
-        public Boolean apply(Task task) {
-            if (task.voiceSession != null) {
-                // We never match voice sessions; those always run independently.
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
-                return false;
-            }
-            if (task.mUserId != userId) {
-                // Looking for a different task.
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
-                return false;
-            }
-
-            // Overlays should not be considered as the task's logical top activity.
-            final ActivityRecord r = task.getTopNonFinishingActivity(false /* includeOverlays */);
-            if (r == null || r.finishing || r.mUserId != userId ||
-                    r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
-                return false;
-            }
-            if (!r.hasCompatibleActivityType(mTarget)) {
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
-                return false;
-            }
-
-            final Intent taskIntent = task.intent;
-            final Intent affinityIntent = task.affinityIntent;
-            final boolean taskIsDocument;
-            final Uri taskDocumentData;
-            if (taskIntent != null && taskIntent.isDocument()) {
-                taskIsDocument = true;
-                taskDocumentData = taskIntent.getData();
-            } else if (affinityIntent != null && affinityIntent.isDocument()) {
-                taskIsDocument = true;
-                taskDocumentData = affinityIntent.getData();
-            } else {
-                taskIsDocument = false;
-                taskDocumentData = null;
-            }
-
-            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
-                    + (task.realActivity != null ? task.realActivity.flattenToShortString() : "")
-                    + "/aff=" + r.getTask().rootAffinity + " to new cls="
-                    + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
-            // TODO Refactor to remove duplications. Check if logic can be simplified.
-            if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
-                    && Objects.equals(documentData, taskDocumentData)) {
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
-                //dump();
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS,
-                        "For Intent " + intent + " bringing to top: " + r.intent);
-                mRecord = r;
-                mIdealMatch = true;
-                return true;
-            } else if (affinityIntent != null && affinityIntent.getComponent() != null &&
-                    affinityIntent.getComponent().compareTo(cls) == 0 &&
-                    Objects.equals(documentData, taskDocumentData)) {
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS,
-                        "For Intent " + intent + " bringing to top: " + r.intent);
-                mRecord = r;
-                mIdealMatch = true;
-                return true;
-            } else if (!isDocument && !taskIsDocument
-                    && mRecord == null && task.rootAffinity != null) {
-                if (task.rootAffinity.equals(mTarget.taskAffinity)) {
-                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!");
-                    // It is possible for multiple tasks to have the same root affinity especially
-                    // if they are in separate stacks. We save off this candidate, but keep looking
-                    // to see if there is a better candidate.
-                    mRecord = r;
-                    mIdealMatch = false;
-                }
-            } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
-
-            return false;
-        }
-    }
-
-    RootActivityContainer(ActivityTaskManagerService service, WindowManagerService wmService) {
-        super(wmService);
-        mService = service;
-        mStackSupervisor = service.mStackSupervisor;
-        mStackSupervisor.mRootActivityContainer = this;
-    }
-
-    void setWindowManager(WindowManagerService wm) {
-        mWindowManager = wm;
-        mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
-        mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
-        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
-
-        final Display[] displays = mDisplayManager.getDisplays();
-        for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
-            final Display display = displays[displayNdx];
-            final DisplayContent displayContent = new DisplayContent(display, this);
-            if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
-                mDefaultDisplay = displayContent;
-            }
-        }
-        calculateDefaultMinimalSizeOfResizeableTasks();
-
-        final DisplayContent defaultDisplay = getDefaultDisplay();
-
-        defaultDisplay.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
-        positionChildAt(POSITION_TOP, defaultDisplay, false /* includingParents */);
-    }
-
-    // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
-    DisplayContent getDefaultDisplay() {
-        return mDefaultDisplay;
-    }
-
-    /**
-     * Get an existing instance of {@link DisplayContent} that has the given uniqueId. Unique ID is
-     * defined in {@link DisplayInfo#uniqueId}.
-     *
-     * @param uniqueId the unique ID of the display
-     * @return the {@link DisplayContent} or {@code null} if nothing is found.
-     */
-    DisplayContent getDisplayContent(String uniqueId) {
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final DisplayContent display = getChildAt(i);
-            final boolean isValid = display.mDisplay.isValid();
-            if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
-                return display;
-            }
-        }
-
-        return null;
-    }
-
-    // TODO: Look into consolidating with getDisplayContentOrCreate()
-    DisplayContent getDisplayContent(int displayId) {
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final DisplayContent displayContent = getChildAt(i);
-            if (displayContent.mDisplayId == displayId) {
-                return displayContent;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get an existing instance of {@link DisplayContent} or create new if there is a
-     * corresponding record in display manager.
-     */
-    // TODO: Look into consolidating with getDisplayContent()
-    @Nullable DisplayContent getDisplayContentOrCreate(int displayId) {
-        DisplayContent displayContent = getDisplayContent(displayId);
-        if (displayContent != null) {
-            return displayContent;
-        }
-        if (mDisplayManager == null) {
-            // The system isn't fully initialized yet.
-            return null;
-        }
-        final Display display = mDisplayManager.getDisplay(displayId);
-        if (display == null) {
-            // The display is not registered in DisplayManager.
-            return null;
-        }
-        // The display hasn't been added to ActivityManager yet, create a new record now.
-        displayContent = new DisplayContent(display, this);
-        return displayContent;
-    }
-
-    ActivityRecord getDefaultDisplayHomeActivity() {
-        return getDefaultDisplayHomeActivityForUser(mCurrentUser);
-    }
-
-    ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
-        return getDisplayContent(DEFAULT_DISPLAY).getHomeActivityForUser(userId);
-    }
-
-    boolean startHomeOnAllDisplays(int userId, String reason) {
-        boolean homeStarted = false;
-        for (int i = getChildCount() - 1; i >= 0; i--) {
-            final int displayId = getChildAt(i).mDisplayId;
-            homeStarted |= startHomeOnDisplay(userId, reason, displayId);
-        }
-        return homeStarted;
-    }
-
-    void startHomeOnEmptyDisplays(String reason) {
-        for (int i = getChildCount() - 1; i >= 0; i--) {
-            final DisplayContent display = getChildAt(i);
-            if (display.topRunningActivity() == null) {
-                startHomeOnDisplay(mCurrentUser, reason, display.mDisplayId);
-            }
-        }
-    }
-
-    boolean startHomeOnDisplay(int userId, String reason, int displayId) {
-        return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
-                false /* fromHomeKey */);
-    }
-
-    /**
-     * This starts home activity on displays that can have system decorations based on displayId -
-     * Default display always use primary home component.
-     * For Secondary displays, the home activity must have category SECONDARY_HOME and then resolves
-     * according to the priorities listed below.
-     *  - If default home is not set, always use the secondary home defined in the config.
-     *  - Use currently selected primary home activity.
-     *  - Use the activity in the same package as currently selected primary home activity.
-     *    If there are multiple activities matched, use first one.
-     *  - Use the secondary home defined in the config.
-     */
-    boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
-            boolean fromHomeKey) {
-        // Fallback to top focused display if the displayId is invalid.
-        if (displayId == INVALID_DISPLAY) {
-            final ActivityStack stack = getTopDisplayFocusedStack();
-            displayId = stack != null ? stack.mDisplayId : DEFAULT_DISPLAY;
-        }
-
-        Intent homeIntent = null;
-        ActivityInfo aInfo = null;
-        if (displayId == DEFAULT_DISPLAY) {
-            homeIntent = mService.getHomeIntent();
-            aInfo = resolveHomeActivity(userId, homeIntent);
-        } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
-            Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
-            aInfo = info.first;
-            homeIntent = info.second;
-        }
-        if (aInfo == null || homeIntent == null) {
-            return false;
-        }
-
-        if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
-            return false;
-        }
-
-        // Updates the home component of the intent.
-        homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
-        homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
-        // Updates the extra information of the intent.
-        if (fromHomeKey) {
-            homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
-        }
-        // Update the reason for ANR debugging to verify if the user activity is the one that
-        // actually launched.
-        final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
-                aInfo.applicationInfo.uid) + ":" + displayId;
-        mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
-                displayId);
-        return true;
-    }
-
-    /**
-     * This resolves the home activity info.
-     * @return the home activity info if any.
-     */
-    @VisibleForTesting
-    ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
-        final int flags = ActivityManagerService.STOCK_PM_FLAGS;
-        final ComponentName comp = homeIntent.getComponent();
-        ActivityInfo aInfo = null;
-        try {
-            if (comp != null) {
-                // Factory test.
-                aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
-            } else {
-                final String resolvedType =
-                        homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
-                final ResolveInfo info = AppGlobals.getPackageManager()
-                        .resolveIntent(homeIntent, resolvedType, flags, userId);
-                if (info != null) {
-                    aInfo = info.activityInfo;
-                }
-            }
-        } catch (RemoteException e) {
-            // ignore
-        }
-
-        if (aInfo == null) {
-            Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
-            return null;
-        }
-
-        aInfo = new ActivityInfo(aInfo);
-        aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
-        return aInfo;
-    }
-
-    @VisibleForTesting
-    Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId, int displayId) {
-        if (displayId == DEFAULT_DISPLAY) {
-            throw new IllegalArgumentException(
-                    "resolveSecondaryHomeActivity: Should not be DEFAULT_DISPLAY");
-        }
-        // Resolve activities in the same package as currently selected primary home activity.
-        Intent homeIntent = mService.getHomeIntent();
-        ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent);
-        if (aInfo != null) {
-            if (ResolverActivity.class.getName().equals(aInfo.name)) {
-                // Always fallback to secondary home component if default home is not set.
-                aInfo = null;
-            } else {
-                // Look for secondary home activities in the currently selected default home
-                // package.
-                homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName);
-                final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent);
-                final int size = resolutions.size();
-                final String targetName = aInfo.name;
-                aInfo = null;
-                for (int i = 0; i < size; i++) {
-                    ResolveInfo resolveInfo = resolutions.get(i);
-                    // We need to traverse all resolutions to check if the currently selected
-                    // default home activity is present.
-                    if (resolveInfo.activityInfo.name.equals(targetName)) {
-                        aInfo = resolveInfo.activityInfo;
-                        break;
-                    }
-                }
-                if (aInfo == null && size > 0) {
-                    // First one is the best.
-                    aInfo = resolutions.get(0).activityInfo;
-                }
-            }
-        }
-
-        if (aInfo != null) {
-            if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
-                aInfo = null;
-            }
-        }
-
-        // Fallback to secondary home component.
-        if (aInfo == null) {
-            homeIntent = mService.getSecondaryHomeIntent(null);
-            aInfo = resolveHomeActivity(userId, homeIntent);
-        }
-        return Pair.create(aInfo, homeIntent);
-    }
-
-    /**
-     * Retrieve all activities that match the given intent.
-     * The list should already ordered from best to worst matched.
-     * {@link android.content.pm.PackageManager#queryIntentActivities}
-     */
-    @VisibleForTesting
-    List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) {
-        List<ResolveInfo> resolutions;
-        try {
-            final String resolvedType =
-                    homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
-            resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent,
-                    resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList();
-
-        } catch (RemoteException e) {
-            resolutions = new ArrayList<>();
-        }
-        return resolutions;
-    }
-
-    boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {
-        if (!mService.isBooting() && !mService.isBooted()) {
-            // Not ready yet!
-            return false;
-        }
-
-        if (displayId == INVALID_DISPLAY) {
-            displayId = DEFAULT_DISPLAY;
-        }
-
-        final ActivityRecord r = getDisplayContent(displayId).getHomeActivity();
-        final String myReason = reason + " resumeHomeActivity";
-
-        // Only resume home activity if isn't finishing.
-        if (r != null && !r.finishing) {
-            r.moveFocusableActivityToTop(myReason);
-            return resumeFocusedStacksTopActivities(r.getActivityStack(), prev, null);
-        }
-        return startHomeOnDisplay(mCurrentUser, myReason, displayId);
-    }
-
-    /**
-     * Check if the display is valid for secondary home activity.
-     * @param displayId The id of the target display.
-     * @return {@code true} if allow to launch, {@code false} otherwise.
-     */
-    boolean shouldPlaceSecondaryHomeOnDisplay(int displayId) {
-        if (displayId == DEFAULT_DISPLAY) {
-            throw new IllegalArgumentException(
-                    "shouldPlaceSecondaryHomeOnDisplay: Should not be DEFAULT_DISPLAY");
-        } else if (displayId == INVALID_DISPLAY) {
-            return false;
-        }
-
-        if (!mService.mSupportsMultiDisplay) {
-            // Can't launch home on secondary display if device does not support multi-display.
-            return false;
-        }
-
-        final boolean deviceProvisioned = Settings.Global.getInt(
-                mService.mContext.getContentResolver(),
-                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
-        if (!deviceProvisioned) {
-            // Can't launch home on secondary display before device is provisioned.
-            return false;
-        }
-
-        if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) {
-            // Can't launch home on secondary displays if device is still locked.
-            return false;
-        }
-
-        final DisplayContent display = getDisplayContent(displayId);
-        if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) {
-            // Can't launch home on display that doesn't support system decorations.
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check if home activity start should be allowed on a display.
-     * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched.
-     * @param displayId The id of the target display.
-     * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
-     * @return {@code true} if allow to launch, {@code false} otherwise.
-     */
-    boolean canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId,
-            boolean allowInstrumenting) {
-        if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
-                && mService.mTopAction == null) {
-            // We are running in factory test mode, but unable to find the factory test app, so
-            // just sit around displaying the error message and don't try to start anything.
-            return false;
-        }
-
-        final WindowProcessController app =
-                mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
-        if (!allowInstrumenting && app != null && app.isInstrumenting()) {
-            // Don't do this if the home app is currently being instrumented.
-            return false;
-        }
-
-        if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
-                && displayId == mService.mVr2dDisplayId)) {
-            // No restrictions to default display or vr 2d display.
-            return true;
-        }
-
-        if (!shouldPlaceSecondaryHomeOnDisplay(displayId)) {
-            return false;
-        }
-
-        final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK
-                && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE;
-        if (!supportMultipleInstance) {
-            // Can't launch home on secondary displays if it requested to be single instance.
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Ensure all activities visibility, update orientation and configuration.
-     *
-     * @param starting The currently starting activity or {@code null} if there is none.
-     * @param displayId The id of the display where operation is executed.
-     * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
-     *                                  {@code true} if config changed.
-     * @param deferResume Whether to defer resume while updating config.
-     * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched
-     *         because of configuration update.
-     */
-    boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
-            boolean markFrozenIfConfigChanged, boolean deferResume) {
-        // First ensure visibility without updating the config just yet. We need this to know what
-        // activities are affecting configuration now.
-        // Passing null here for 'starting' param value, so that visibility of actual starting
-        // activity will be properly updated.
-        ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
-                false /* preserveWindows */, false /* notifyClients */);
-
-        if (displayId == INVALID_DISPLAY) {
-            // The caller didn't provide a valid display id, skip updating config.
-            return true;
-        }
-
-        // Force-update the orientation from the WindowManager, since we need the true configuration
-        // to send to the client now.
-        final DisplayContent displayContent = getDisplayContent(displayId);
-        Configuration config = null;
-        if (displayContent != null) {
-            config = displayContent.updateOrientation(
-                    getDisplayOverrideConfiguration(displayId),
-                    starting != null && starting.mayFreezeScreenLocked()
-                            ? starting.appToken : null,
-                    true /* forceUpdate */);
-        }
-        // Visibilities may change so let the starting activity have a chance to report. Can't do it
-        // when visibility is changed in each AppWindowToken because it may trigger wrong
-        // configuration push because the visibility of some activities may not be updated yet.
-        if (starting != null) {
-            starting.reportDescendantOrientationChangeIfNeeded();
-        }
-        if (starting != null && markFrozenIfConfigChanged && config != null) {
-            starting.frozenBeforeDestroy = true;
-        }
-
-        if (displayContent != null) {
-            // Update the configuration of the activities on the display.
-            return displayContent.updateDisplayOverrideConfigurationLocked(config, starting,
-                    deferResume, null /* result */);
-        } else {
-            return true;
-        }
-    }
-
-    /**
-     * @return a list of activities which are the top ones in each visible stack. The first
-     * entry will be the focused activity.
-     */
-    List<IBinder> getTopVisibleActivities() {
-        final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
-        final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
-        // Traverse all displays.
-        for (int i = getChildCount() - 1; i >= 0; i--) {
-            final DisplayContent display = getChildAt(i);
-            // Traverse all stacks on a display.
-            for (int j = display.getStackCount() - 1; j >= 0; --j) {
-                final ActivityStack stack = display.getStackAt(j);
-                // Get top activity from a visible stack and add it to the list.
-                if (stack.shouldBeVisible(null /* starting */)) {
-                    final ActivityRecord top = stack.getTopNonFinishingActivity();
-                    if (top != null) {
-                        if (stack == topFocusedStack) {
-                            topActivityTokens.add(0, top.appToken);
-                        } else {
-                            topActivityTokens.add(top.appToken);
-                        }
-                    }
-                }
-            }
-        }
-        return topActivityTokens;
-    }
-
-    ActivityStack getTopDisplayFocusedStack() {
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final ActivityStack focusedStack = getChildAt(i).getFocusedStack();
-            if (focusedStack != null) {
-                return focusedStack;
-            }
-        }
-        return null;
-    }
-
-    ActivityRecord getTopResumedActivity() {
-        final ActivityStack focusedStack = getTopDisplayFocusedStack();
-        if (focusedStack == null) {
-            return null;
-        }
-        final ActivityRecord resumedActivity = focusedStack.getResumedActivity();
-        if (resumedActivity != null && resumedActivity.app != null) {
-            return resumedActivity;
-        }
-        // The top focused stack might not have a resumed activity yet - look on all displays in
-        // focus order.
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final DisplayContent display = getChildAt(i);
-            final ActivityRecord resumedActivityOnDisplay = display.getResumedActivity();
-            if (resumedActivityOnDisplay != null) {
-                return resumedActivityOnDisplay;
-            }
-        }
-        return null;
-    }
-
-    boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) {
-        if (container.inSplitScreenPrimaryWindowingMode() && mIsDockMinimized) {
-            return false;
-        }
-
-        return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable;
-    }
-
-    boolean isTopDisplayFocusedStack(ActivityStack stack) {
-        return stack != null && stack == getTopDisplayFocusedStack();
-    }
-
-    void updatePreviousProcess(ActivityRecord r) {
-        // Now that this process has stopped, we may want to consider it to be the previous app to
-        // try to keep around in case the user wants to return to it.
-
-        // First, found out what is currently the foreground app, so that we don't blow away the
-        // previous app if this activity is being hosted by the process that is actually still the
-        // foreground.
-        WindowProcessController fgApp = null;
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                if (isTopDisplayFocusedStack(stack)) {
-                    final ActivityRecord resumedActivity = stack.getResumedActivity();
-                    if (resumedActivity != null) {
-                        fgApp = resumedActivity.app;
-                    } else if (stack.mPausingActivity != null) {
-                        fgApp = stack.mPausingActivity.app;
-                    }
-                    break;
-                }
-            }
-        }
-
-        // Now set this one as the previous process, only if that really makes sense to.
-        if (r.hasProcess() && fgApp != null && r.app != fgApp
-                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
-                && r.app != mService.mHomeProcess) {
-            mService.mPreviousProcess = r.app;
-            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
-        }
-    }
-
-    boolean attachApplication(WindowProcessController app) throws RemoteException {
-        final String processName = app.mName;
-        boolean didSomething = false;
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            final ActivityStack stack = display.getFocusedStack();
-            if (stack == null) {
-                continue;
-            }
-
-            mTmpRemoteException = null;
-            mTmpBoolean = false; // Set to true if an activity was started.
-            final PooledFunction c = PooledLambda.obtainFunction(
-                    RootActivityContainer::startActivityForAttachedApplicationIfNeeded, this,
-                    PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
-            stack.forAllActivities(c);
-            c.recycle();
-            if (mTmpRemoteException != null) {
-                throw mTmpRemoteException;
-            }
-            didSomething |= mTmpBoolean;
-        }
-        if (!didSomething) {
-            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
-        }
-        return didSomething;
-    }
-
-    private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
-            WindowProcessController app, ActivityRecord top) {
-        if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
-                || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
-            return false;
-        }
-
-        try {
-            if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
-                    true /*checkConfig*/)) {
-                mTmpBoolean = true;
-            }
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Exception in new application when starting activity "
-                    + top.intent.getComponent().flattenToShortString(), e);
-            mTmpRemoteException = e;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Make sure that all activities that need to be visible in the system actually are and update
-     * their configuration.
-     */
-    void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
-            boolean preserveWindows) {
-        ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
-    }
-
-    /**
-     * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
-     */
-    void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
-            boolean preserveWindows, boolean notifyClients) {
-        if (mInEnsureActivitiesVisible) {
-            // Don't do recursive work.
-            return;
-        }
-        mInEnsureActivitiesVisible = true;
-
-        try {
-            mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
-            // First the front stacks. In case any are not fullscreen and are in front of home.
-            for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-                final DisplayContent display = getChildAt(displayNdx);
-                display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
-                        notifyClients);
-            }
-        } finally {
-            mStackSupervisor.getKeyguardController().endActivityVisibilityUpdate();
-            mInEnsureActivitiesVisible = false;
-        }
-    }
-
-    boolean switchUser(int userId, UserState uss) {
-        final int focusStackId = getTopDisplayFocusedStack().getStackId();
-        // We dismiss the docked stack whenever we switch users.
-        final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenPrimaryStack();
-        if (dockedStack != null) {
-            mStackSupervisor.moveTasksToFullscreenStackLocked(
-                    dockedStack, dockedStack.isFocusedStackOnDisplay());
-        }
-        // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
-        // also cause all tasks to be moved to the fullscreen stack at a position that is
-        // appropriate.
-        removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
-
-        mUserStackInFront.put(mCurrentUser, focusStackId);
-        final int restoreStackId =
-                mUserStackInFront.get(userId, getDefaultDisplay().getHomeStack().mStackId);
-        mCurrentUser = userId;
-
-        mStackSupervisor.mStartingUsers.add(uss);
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                stack.switchUser(userId);
-                Task task = stack.getTopMostTask();
-                if (task != null) {
-                    stack.positionChildAtTop(task);
-                }
-            }
-        }
-
-        ActivityStack stack = getStack(restoreStackId);
-        if (stack == null) {
-            stack = getDefaultDisplay().getHomeStack();
-        }
-        final boolean homeInFront = stack.isActivityTypeHome();
-        if (stack.isOnHomeDisplay()) {
-            stack.moveToFront("switchUserOnHomeDisplay");
-        } else {
-            // Stack was moved to another display while user was swapped out.
-            resumeHomeActivity(null, "switchUserOnOtherDisplay", DEFAULT_DISPLAY);
-        }
-        return homeInFront;
-    }
-
-    void removeUser(int userId) {
-        mUserStackInFront.delete(userId);
-    }
-
-    /**
-     * Update the last used stack id for non-current user (current user's last
-     * used stack is the focused stack)
-     */
-    void updateUserStack(int userId, ActivityStack stack) {
-        if (userId != mCurrentUser) {
-            mUserStackInFront.put(userId, stack != null ? stack.getStackId()
-                    : getDefaultDisplay().getHomeStack().mStackId);
-        }
-    }
-
-    /**
-     * Move stack with all its existing content to specified display.
-     * @param stackId Id of stack to move.
-     * @param displayId Id of display to move stack to.
-     * @param onTop Indicates whether container should be place on top or on bottom.
-     */
-    void moveStackToDisplay(int stackId, int displayId, boolean onTop) {
-        final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
-        if (displayContent == null) {
-            throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId="
-                    + displayId);
-        }
-        final ActivityStack stack = getStack(stackId);
-        if (stack == null) {
-            throw new IllegalArgumentException("moveStackToDisplay: Unknown stackId="
-                    + stackId);
-        }
-
-        final DisplayContent currentDisplay = stack.getDisplay();
-        if (currentDisplay == null) {
-            throw new IllegalStateException("moveStackToDisplay: Stack with stack=" + stack
-                    + " is not attached to any display.");
-        }
-
-        if (currentDisplay.mDisplayId == displayId) {
-            throw new IllegalArgumentException("Trying to move stack=" + stack
-                    + " to its current displayId=" + displayId);
-        }
-
-        if (displayContent.isSingleTaskInstance() && displayContent.getStackCount() > 0) {
-            // We don't allow moving stacks to single instance display that already has a child.
-            Slog.e(TAG, "Can not move stack=" + stack
-                    + " to single task instance display=" + displayContent);
-            return;
-        }
-
-        stack.reparent(displayContent.mDisplayContent, onTop);
-        // TODO(multi-display): resize stacks properly if moved from split-screen.
-    }
-
-    boolean moveTopStackActivityToPinnedStack(int stackId) {
-        final ActivityStack stack = getStack(stackId);
-        if (stack == null) {
-            throw new IllegalArgumentException(
-                    "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId);
-        }
-
-        final ActivityRecord r = stack.topRunningActivity();
-        if (r == null) {
-            Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity"
-                    + " in stack=" + stack);
-            return false;
-        }
-
-        if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
-            Slog.w(TAG, "moveTopStackActivityToPinnedStack: Picture-In-Picture not supported for "
-                    + " r=" + r);
-            return false;
-        }
-
-        moveActivityToPinnedStack(r, null /* sourceBounds */, 0f /* aspectRatio */,
-                "moveTopActivityToPinnedStack");
-        return true;
-    }
-
-    void moveActivityToPinnedStack(ActivityRecord r, Rect sourceHintBounds, float aspectRatio,
-            String reason) {
-        mService.deferWindowLayout();
-
-        final DisplayContent display = r.getActivityStack().getDisplay();
-
-        try {
-            final Task task = r.getTask();
-
-            final ActivityStack pinnedStack = display.getPinnedStack();
-            // This will change the pinned stack's windowing mode to its original mode, ensuring
-            // we only have one stack that is in pinned mode.
-            if (pinnedStack != null) {
-                pinnedStack.dismissPip();
-            }
-
-            final boolean singleActivity = task.getChildCount() == 1;
-
-            final ActivityStack stack;
-            if (singleActivity) {
-                stack = r.getActivityStack();
-            } else {
-                // In the case of multiple activities, we will create a new stack for it and then
-                // move the PIP activity into the stack.
-                // We will then perform a windowing mode change for both scenarios.
-                stack = display.createStack(
-                        r.getActivityStack().getRequestedOverrideWindowingMode(),
-                        r.getActivityType(), ON_TOP);
-                // There are multiple activities in the task and moving the top activity should
-                // reveal/leave the other activities in their original task.
-
-                // Currently, we don't support reparenting activities across tasks in two different
-                // stacks, so instead, just create a new task in the same stack, reparent the
-                // activity into that task, and then reparent the whole task to the new stack. This
-                // ensures that all the necessary work to migrate states in the old and new stacks
-                // is also done.
-                final Task newTask = task.getStack().createTask(
-                        mStackSupervisor.getNextTaskIdForUserLocked(r.mUserId), r.info,
-                        r.intent, null, null, true);
-                r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
-
-                // Defer resume until below, and do not schedule PiP changes until we animate below
-                newTask.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
-                        DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
-            }
-
-            stack.setWindowingMode(WINDOWING_MODE_PINNED);
-
-            // Reset the state that indicates it can enter PiP while pausing after we've moved it
-            // to the pinned stack
-            r.supportsEnterPipOnTaskSwitch = false;
-        } finally {
-            mService.continueWindowLayout();
-        }
-
-        // Notify the pinned stack controller to prepare the PiP animation, expect callback
-        // delivered from SystemUI to WM to start the animation.
-        final PinnedStackController pinnedStackController =
-                display.mDisplayContent.getPinnedStackController();
-        pinnedStackController.prepareAnimation(sourceHintBounds, aspectRatio,
-                null /* stackBounds */);
-
-        // TODO: revisit the following statement after the animation is moved from WM to SysUI.
-        // Update the visibility of all activities after the they have been reparented to the new
-        // stack.  This MUST run after the animation above is scheduled to ensure that the windows
-        // drawn signal is scheduled after the bounds animation start call on the bounds animator
-        // thread.
-        ensureActivitiesVisible(null, 0, false /* preserveWindows */);
-        resumeFocusedStacksTopActivities();
-
-        mService.getTaskChangeNotificationController().notifyActivityPinned(r);
-    }
-
-    void executeAppTransitionForAllDisplay() {
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            display.mDisplayContent.executeAppTransition();
-        }
-    }
-
-    void setDockedStackMinimized(boolean minimized) {
-        // Get currently focused stack before setting mIsDockMinimized. We do this because if
-        // split-screen is active, primary stack will not be focusable (see #isFocusable) while
-        // still occluding other stacks. This will cause getTopDisplayFocusedStack() to return null.
-        final ActivityStack current = getTopDisplayFocusedStack();
-        mIsDockMinimized = minimized;
-        if (mIsDockMinimized) {
-            if (current.inSplitScreenPrimaryWindowingMode()) {
-                // The primary split-screen stack can't be focused while it is minimize, so move
-                // focus to something else.
-                current.adjustFocusToNextFocusableStack("setDockedStackMinimized");
-            }
-        }
-    }
-
-    ActivityRecord findTask(ActivityRecord r, int preferredDisplayId) {
-        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
-        mTmpFindTaskResult.clear();
-
-        // Looking up task on preferred display first
-        final DisplayContent preferredDisplay = getDisplayContent(preferredDisplayId);
-        if (preferredDisplay != null) {
-            preferredDisplay.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult);
-            if (mTmpFindTaskResult.mIdealMatch) {
-                return mTmpFindTaskResult.mRecord;
-            }
-        }
-
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            if (display.mDisplayId == preferredDisplayId) {
-                continue;
-            }
-
-            display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult);
-            if (mTmpFindTaskResult.mIdealMatch) {
-                return mTmpFindTaskResult.mRecord;
-            }
-        }
-
-        if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found");
-        return mTmpFindTaskResult.mRecord;
-    }
-
-    /**
-     * Finish the topmost activities in all stacks that belong to the crashed app.
-     * @param app The app that crashed.
-     * @param reason Reason to perform this action.
-     * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
-     */
-    int finishTopCrashedActivities(WindowProcessController app, String reason) {
-        Task finishedTask = null;
-        ActivityStack focusedStack = getTopDisplayFocusedStack();
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            // It is possible that request to finish activity might also remove its task and stack,
-            // so we need to be careful with indexes in the loop and check child count every time.
-            for (int stackNdx = 0; stackNdx < display.getStackCount(); ++stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                final Task t = stack.finishTopCrashedActivityLocked(app, reason);
-                if (stack == focusedStack || finishedTask == null) {
-                    finishedTask = t;
-                }
-            }
-        }
-        return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID;
-    }
-
-    boolean resumeFocusedStacksTopActivities() {
-        return resumeFocusedStacksTopActivities(null, null, null);
-    }
-
-    boolean resumeFocusedStacksTopActivities(
-            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
-
-        if (!mStackSupervisor.readyToResume()) {
-            return false;
-        }
-
-        boolean result = false;
-        if (targetStack != null && (targetStack.isTopStackOnDisplay()
-                || getTopDisplayFocusedStack() == targetStack)) {
-            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
-        }
-
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            boolean resumedOnDisplay = false;
-            final DisplayContent display = getChildAt(displayNdx);
-            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                final ActivityRecord topRunningActivity = stack.topRunningActivity();
-                if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
-                    continue;
-                }
-                if (stack == targetStack) {
-                    // Simply update the result for targetStack because the targetStack had
-                    // already resumed in above. We don't want to resume it again, especially in
-                    // some cases, it would cause a second launch failure if app process was dead.
-                    resumedOnDisplay |= result;
-                    continue;
-                }
-                if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
-                    // Kick off any lingering app transitions form the MoveTaskToFront operation,
-                    // but only consider the top task and stack on that display.
-                    stack.executeAppTransition(targetOptions);
-                } else {
-                    resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
-                }
-            }
-            if (!resumedOnDisplay) {
-                // In cases when there are no valid activities (e.g. device just booted or launcher
-                // crashed) it's possible that nothing was resumed on a display. Requesting resume
-                // of top activity in focused stack explicitly will make sure that at least home
-                // activity is started and resumed, and no recursion occurs.
-                final ActivityStack focusedStack = display.getFocusedStack();
-                if (focusedStack != null) {
-                    result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
-                } else if (targetStack == null && display.getStackCount() == 0) {
-                    result |= resumeHomeActivity(null /* prev */, "empty-display",
-                            display.mDisplayId);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    void applySleepTokens(boolean applyToStacks) {
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            // Set the sleeping state of the display.
-            final DisplayContent display = getChildAt(displayNdx);
-            final boolean displayShouldSleep = display.shouldSleep();
-            if (displayShouldSleep == display.isSleeping()) {
-                continue;
-            }
-            display.setIsSleeping(displayShouldSleep);
-
-            if (!applyToStacks) {
-                continue;
-            }
-
-            // Set the sleeping state of the stacks on the display.
-            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                if (displayShouldSleep) {
-                    stack.goToSleepIfPossible(false /* shuttingDown */);
-                } else {
-                    // When the display which can only contain one task turns on, start a special
-                    // transition. {@link AppTransitionController#handleAppTransitionReady} later
-                    // picks up the transition, and schedules
-                    // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is
-                    // triggered after contents are drawn on the display.
-                    if (display.isSingleTaskInstance()) {
-                        display.mDisplayContent.prepareAppTransition(
-                                TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false);
-                    }
-                    stack.awakeFromSleepingLocked();
-                    if (stack.isFocusedStackOnDisplay()
-                            && !mStackSupervisor.getKeyguardController()
-                            .isKeyguardOrAodShowing(display.mDisplayId)) {
-                        // If the keyguard is unlocked - resume immediately.
-                        // It is possible that the display will not be awake at the time we
-                        // process the keyguard going away, which can happen before the sleep token
-                        // is released. As a result, it is important we resume the activity here.
-                        resumeFocusedStacksTopActivities();
-                    }
-                }
-            }
-
-            if (displayShouldSleep || mStackSupervisor.mGoingToSleepActivities.isEmpty()) {
-                continue;
-            }
-            // The display is awake now, so clean up the going to sleep list.
-            for (Iterator<ActivityRecord> it =
-                 mStackSupervisor.mGoingToSleepActivities.iterator(); it.hasNext(); ) {
-                final ActivityRecord r = it.next();
-                if (r.getDisplayId() == display.mDisplayId) {
-                    it.remove();
-                }
-            }
-        }
-    }
-
-    protected ActivityStack getStack(int stackId) {
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final ActivityStack stack = getChildAt(i).getStack(stackId);
-            if (stack != null) {
-                return stack;
-            }
-        }
-        return null;
-    }
-
-    /** @see DisplayContent#getStack(int, int) */
-    ActivityStack getStack(int windowingMode, int activityType) {
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final ActivityStack stack = getChildAt(i).getStack(windowingMode, activityType);
-            if (stack != null) {
-                return stack;
-            }
-        }
-        return null;
-    }
-
-    private ActivityStack getStack(int windowingMode, int activityType,
-            int displayId) {
-        DisplayContent display = getDisplayContent(displayId);
-        if (display == null) {
-            return null;
-        }
-        return display.getStack(windowingMode, activityType);
-    }
-
-    private ActivityManager.StackInfo getStackInfo(ActivityStack stack) {
-        final int displayId = stack.mDisplayId;
-        final DisplayContent display = getDisplayContent(displayId);
-        ActivityManager.StackInfo info = new ActivityManager.StackInfo();
-        stack.getBounds(info.bounds);
-        info.displayId = displayId;
-        info.stackId = stack.mStackId;
-        info.stackToken = stack.mRemoteToken;
-        info.userId = stack.mCurrentUser;
-        info.visible = stack.shouldBeVisible(null);
-        // A stack might be not attached to a display.
-        info.position = display != null ? display.getIndexOf(stack) : 0;
-        info.configuration.setTo(stack.getConfiguration());
-
-        final int numTasks = stack.getChildCount();
-        info.taskIds = new int[numTasks];
-        info.taskNames = new String[numTasks];
-        info.taskBounds = new Rect[numTasks];
-        info.taskUserIds = new int[numTasks];
-        final int[] currenIndex = {0};
-
-        final PooledConsumer c = PooledLambda.obtainConsumer(
-                RootActivityContainer::processTaskForStackInfo, PooledLambda.__(Task.class), info,
-                currenIndex);
-        stack.forAllTasks(c, false);
-        c.recycle();
-
-        final ActivityRecord top = stack.topRunningActivity();
-        info.topActivity = top != null ? top.intent.getComponent() : null;
-        return info;
-    }
-
-    private static void processTaskForStackInfo(
-            Task task, ActivityManager.StackInfo info, int[] currentIndex) {
-        int i = currentIndex[0];
-        info.taskIds[i] = task.mTaskId;
-        info.taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
-                : task.realActivity != null ? task.realActivity.flattenToString()
-                        : task.getTopNonFinishingActivity() != null
-                                ? task.getTopNonFinishingActivity().packageName : "unknown";
-        info.taskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId);
-        info.taskUserIds[i] = task.mUserId;
-        currentIndex[0] = ++i;
-    }
-
-    ActivityManager.StackInfo getStackInfo(int stackId) {
-        ActivityStack stack = getStack(stackId);
-        if (stack != null) {
-            return getStackInfo(stack);
-        }
-        return null;
-    }
-
-    ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
-        final ActivityStack stack = getStack(windowingMode, activityType);
-        return (stack != null) ? getStackInfo(stack) : null;
-    }
-
-    ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType, int displayId) {
-        final ActivityStack stack = getStack(windowingMode, activityType, displayId);
-        return (stack != null) ? getStackInfo(stack) : null;
-    }
-
-    /** If displayId == INVALID_DISPLAY, this will get stack infos on all displays */
-    ArrayList<ActivityManager.StackInfo> getAllStackInfos(int displayId) {
-        ArrayList<ActivityManager.StackInfo> list = new ArrayList<>();
-        if (displayId == INVALID_DISPLAY) {
-            for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
-                final DisplayContent display = getChildAt(displayNdx);
-                for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                    final ActivityStack stack = display.getStackAt(stackNdx);
-                    list.add(getStackInfo(stack));
-                }
-            }
-            return list;
-        }
-        final DisplayContent display = getDisplayContent(displayId);
-        if (display == null) {
-            return list;
-        }
-        for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-            final ActivityStack stack = display.getStackAt(stackNdx);
-            list.add(getStackInfo(stack));
-        }
-        return list;
-    }
-
-    void deferUpdateBounds(int activityType) {
-        final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
-        if (stack != null) {
-            stack.deferUpdateBounds();
-        }
-    }
-
-    void continueUpdateBounds(int activityType) {
-        final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
-        if (stack != null) {
-            stack.continueUpdateBounds();
-        }
-    }
-
-    @Override
-    public void onDisplayAdded(int displayId) {
-        if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
-        synchronized (mService.mGlobalLock) {
-            final DisplayContent display = getDisplayContentOrCreate(displayId);
-            if (display == null) {
-                return;
-            }
-            // Do not start home before booting, or it may accidentally finish booting before it
-            // starts. Instead, we expect home activities to be launched when the system is ready
-            // (ActivityManagerService#systemReady).
-            if (mService.isBooted() || mService.isBooting()) {
-                startSystemDecorations(display.mDisplayContent);
-            }
-        }
-    }
-
-    private void startSystemDecorations(final DisplayContent displayContent) {
-        startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
-        displayContent.getDisplayPolicy().notifyDisplayReady();
-    }
-
-    @Override
-    public void onDisplayRemoved(int displayId) {
-        if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
-        if (displayId == DEFAULT_DISPLAY) {
-            throw new IllegalArgumentException("Can't remove the primary display.");
-        }
-
-        synchronized (mService.mGlobalLock) {
-            final DisplayContent displayContent = getDisplayContent(displayId);
-            if (displayContent == null) {
-                return;
-            }
-
-            displayContent.remove();
-        }
-    }
-
-    @Override
-    public void onDisplayChanged(int displayId) {
-        if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
-        synchronized (mService.mGlobalLock) {
-            final DisplayContent displayContent = getDisplayContent(displayId);
-            if (displayContent != null) {
-                displayContent.onDisplayChanged();
-            }
-        }
-    }
-
-    /** Update lists of UIDs that are present on displays and have access to them. */
-    void updateUIDsPresentOnDisplay() {
-        mDisplayAccessUIDs.clear();
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent displayContent = getChildAt(displayNdx);
-            // Only bother calculating the whitelist for private displays
-            if (displayContent.isPrivate()) {
-                mDisplayAccessUIDs.append(
-                        displayContent.mDisplayId, displayContent.getPresentUIDs());
-            }
-        }
-        // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
-        mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
-    }
-
-    ActivityStack findStackBehind(ActivityStack stack) {
-        final DisplayContent display = getDisplayContent(stack.mDisplayId);
-        if (display != null) {
-            for (int i = display.getStackCount() - 1; i >= 0; i--) {
-                if (display.getStackAt(i) == stack && i > 0) {
-                    return display.getStackAt(i - 1);
-                }
-            }
-        }
-        throw new IllegalStateException("Failed to find a stack behind stack=" + stack
-                + " in=" + display);
-    }
-
-    @Override
-    void positionChildAt(int position, DisplayContent child, boolean includingParents) {
-        super.positionChildAt(position, child, includingParents);
-        mStackSupervisor.updateTopResumedActivityIfNeeded();
-    }
-
-    Configuration getDisplayOverrideConfiguration(int displayId) {
-        final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
-        if (displayContent == null) {
-            throw new IllegalArgumentException("No display found with id: " + displayId);
-        }
-
-        return displayContent.getRequestedOverrideConfiguration();
-    }
-
-    void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) {
-        final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
-        if (displayContent == null) {
-            throw new IllegalArgumentException("No display found with id: " + displayId);
-        }
-
-        displayContent.onRequestedOverrideConfigurationChanged(overrideConfiguration);
-    }
-
-    void prepareForShutdown() {
-        for (int i = 0; i < getChildCount(); i++) {
-            createSleepToken("shutdown", getChildAt(i).mDisplayId);
-        }
-    }
-
-    ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) {
-        final DisplayContent display = getDisplayContent(displayId);
-        if (display == null) {
-            throw new IllegalArgumentException("Invalid display: " + displayId);
-        }
-
-        final SleepTokenImpl token = new SleepTokenImpl(tag, displayId);
-        mSleepTokens.add(token);
-        display.mAllSleepTokens.add(token);
-        return token;
-    }
-
-    private void removeSleepToken(SleepTokenImpl token) {
-        mSleepTokens.remove(token);
-
-        final DisplayContent display = getDisplayContent(token.mDisplayId);
-        if (display != null) {
-            display.mAllSleepTokens.remove(token);
-            if (display.mAllSleepTokens.isEmpty()) {
-                mService.updateSleepIfNeededLocked();
-            }
-        }
-    }
-
-    void addStartingWindowsForVisibleActivities() {
-        forAllActivities((r) -> {
-            if (r.mVisibleRequested) {
-                r.showStartingWindow(null /* prev */, false /* newTask */, true /*taskSwitch*/);
-            }
-        });
-    }
-
-    void invalidateTaskLayers() {
-        mTaskLayersChanged = true;
-    }
-
-    void rankTaskLayersIfNeeded() {
-        if (!mTaskLayersChanged) {
-            return;
-        }
-        mTaskLayersChanged = false;
-        mTmpTaskLayerRank = 0;
-        final PooledConsumer c = PooledLambda.obtainConsumer(
-                RootActivityContainer::rankTaskLayerForActivity, this,
-                PooledLambda.__(ActivityRecord.class));
-        forAllActivities(c);
-        c.recycle();
-    }
-
-    private void rankTaskLayerForActivity(ActivityRecord r) {
-        if (r.canBeTopRunning() && r.mVisibleRequested) {
-            r.getTask().mLayerRank = ++mTmpTaskLayerRank;
-        } else {
-            r.getTask().mLayerRank = -1;
-        }
-    }
-
-    void clearOtherAppTimeTrackers(AppTimeTracker except) {
-        final PooledConsumer c = PooledLambda.obtainConsumer(
-                RootActivityContainer::clearOtherAppTimeTrackers,
-                PooledLambda.__(ActivityRecord.class), except);
-        forAllActivities(c);
-        c.recycle();
-    }
-
-    private static void clearOtherAppTimeTrackers(ActivityRecord r, AppTimeTracker except) {
-        if ( r.appTimeTracker != except) {
-            r.appTimeTracker = null;
-        }
-    }
-
-    void scheduleDestroyAllActivities(String reason) {
-        mDestroyAllActivitiesReason = reason;
-        mService.mH.post(mDestroyAllActivitiesRunnable);
-    }
-
-    private void destroyActivity(ActivityRecord r) {
-        if (r.finishing || !r.isDestroyable()) return;
-
-        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.getState()
-                + " resumed=" + r.getStack().mResumedActivity + " pausing="
-                + r.getStack().mPausingActivity + " for reason " + mDestroyAllActivitiesReason);
-
-        r.destroyImmediately(true /* removeFromTask */, mDestroyAllActivitiesReason);
-    }
-
-    // Tries to put all activity stacks to sleep. Returns true if all stacks were
-    // successfully put to sleep.
-    boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) {
-        boolean allSleep = true;
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                // Stacks and activities could be removed while putting activities to sleep if
-                // the app process was gone. This prevents us getting exception by accessing an
-                // invalid stack index.
-                if (stackNdx >= display.getStackCount()) {
-                    continue;
-                }
-
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                if (allowDelay) {
-                    allSleep &= stack.goToSleepIfPossible(shuttingDown);
-                } else {
-                    stack.goToSleep();
-                }
-            }
-        }
-        return allSleep;
-    }
-
-    void handleAppCrash(WindowProcessController app) {
-        final PooledConsumer c = PooledLambda.obtainConsumer(
-                RootActivityContainer::handleAppCrash, PooledLambda.__(ActivityRecord.class), app);
-        forAllActivities(c);
-        c.recycle();
-    }
-
-    private static void handleAppCrash(ActivityRecord r, WindowProcessController app) {
-        if (r.app != app) return;
-        Slog.w(TAG, "  Force finishing activity "
-                + r.intent.getComponent().flattenToShortString());
-        // Force the destroy to skip right to removal.
-        r.app = null;
-        r.getDisplay().mDisplayContent.prepareAppTransition(
-                TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
-        r.destroyIfPossible("handleAppCrashed");
-    }
-
-    ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
-        ComponentName cls = intent.getComponent();
-        if (info.targetActivity != null) {
-            cls = new ComponentName(info.packageName, info.targetActivity);
-        }
-        final int userId = UserHandle.getUserId(info.applicationInfo.uid);
-
-        final PooledPredicate p = PooledLambda.obtainPredicate(
-                RootActivityContainer::matchesActivity, PooledLambda.__(ActivityRecord.class),
-                userId, compareIntentFilters, intent, cls);
-        final ActivityRecord r = getActivity(p);
-        p.recycle();
-        return r;
-    }
-
-    private static boolean matchesActivity(ActivityRecord r, int userId,
-            boolean compareIntentFilters, Intent intent, ComponentName cls) {
-        if (!r.canBeTopRunning() || r.mUserId != userId)  return false;
-
-        if (compareIntentFilters) {
-            if (r.intent.filterEquals(intent)) {
-                return true;
-            }
-        } else {
-            if (r.intent.getComponent().equals(cls)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    boolean hasAwakeDisplay() {
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            if (!display.shouldSleep()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    ActivityStack getLaunchStack(@Nullable ActivityRecord r,
-            @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) {
-        return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
-                -1 /* no realCallingPid */, -1 /* no realCallingUid */);
-    }
-
-    /**
-     * Returns the right stack to use for launching factoring in all the input parameters.
-     *
-     * @param r The activity we are trying to launch. Can be null.
-     * @param options The activity options used to the launch. Can be null.
-     * @param candidateTask The possible task the activity might be launched in. Can be null.
-     * @param launchParams The resolved launch params to use.
-     * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
-     * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
-     *
-     * @return The stack to use for the launch or INVALID_STACK_ID.
-     */
-    ActivityStack getLaunchStack(@Nullable ActivityRecord r,
-            @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop,
-            @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
-            int realCallingUid) {
-        int taskId = INVALID_TASK_ID;
-        int displayId = INVALID_DISPLAY;
-        //Rect bounds = null;
-
-        // We give preference to the launch preference in activity options.
-        if (options != null) {
-            taskId = options.getLaunchTaskId();
-            displayId = options.getLaunchDisplayId();
-        }
-
-        // First preference for stack goes to the task Id set in the activity options. Use the stack
-        // associated with that if possible.
-        if (taskId != INVALID_TASK_ID) {
-            // Temporarily set the task id to invalid in case in re-entry.
-            options.setLaunchTaskId(INVALID_TASK_ID);
-            final Task task = anyTaskForId(taskId,
-                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
-            options.setLaunchTaskId(taskId);
-            if (task != null) {
-                return task.getStack();
-            }
-        }
-
-        final int activityType = resolveActivityType(r, options, candidateTask);
-        ActivityStack stack;
-
-        // Next preference for stack goes to the display Id set the candidate display.
-        if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
-            displayId = launchParams.mPreferredDisplayId;
-        }
-        final boolean canLaunchOnDisplayFromStartRequest =
-                realCallingPid != 0 && realCallingUid > 0 && r != null
-                        && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid,
-                        realCallingUid, r.info);
-        // Checking if the activity's launch caller, or the realCallerId of the activity from
-        // start request (i.e. entity that invokes PendingIntent) is allowed to launch on the
-        // display.
-        if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId)
-                || canLaunchOnDisplayFromStartRequest)) {
-            if (r != null) {
-                stack = getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
-                        launchParams);
-                if (stack != null) {
-                    return stack;
-                }
-            }
-            final DisplayContent display = getDisplayContentOrCreate(displayId);
-            if (display != null) {
-                stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
-                if (stack != null) {
-                    return stack;
-                }
-            }
-        }
-
-        // Give preference to the stack and display of the input task and activity if they match the
-        // mode we want to launch into.
-        stack = null;
-        DisplayContent display = null;
-        if (candidateTask != null) {
-            stack = candidateTask.getStack();
-        }
-        if (stack == null && r != null) {
-            stack = r.getActivityStack();
-        }
-        if (stack != null) {
-            display = stack.getDisplay();
-            if (display != null && canLaunchOnDisplay(r, display.mDisplayId)) {
-                int windowingMode = launchParams != null ? launchParams.mWindowingMode
-                        : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-                if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
-                    windowingMode = display.resolveWindowingMode(r, options, candidateTask,
-                            activityType);
-                }
-                if (stack.isCompatible(windowingMode, activityType)) {
-                    return stack;
-                }
-                if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
-                        && display.getSplitScreenPrimaryStack() == stack
-                        && candidateTask == stack.getTopMostTask()) {
-                    // This is a special case when we try to launch an activity that is currently on
-                    // top of split-screen primary stack, but is targeting split-screen secondary.
-                    // In this case we don't want to move it to another stack.
-                    // TODO(b/78788972): Remove after differentiating between preferred and required
-                    // launch options.
-                    return stack;
-                }
-            }
-        }
-
-        if (display == null || !canLaunchOnDisplay(r, display.mDisplayId)) {
-            display = getDefaultDisplay();
-        }
-
-        return display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
-    }
-
-    /** @return true if activity record is null or can be launched on provided display. */
-    private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) {
-        if (r == null) {
-            return true;
-        }
-        return r.canBeLaunchedOnDisplay(displayId);
-    }
-
-    /**
-     * Get a topmost stack on the display, that is a valid launch stack for specified activity.
-     * If there is no such stack, new dynamic stack can be created.
-     * @param displayId Target display.
-     * @param r Activity that should be launched there.
-     * @param candidateTask The possible task the activity might be put in.
-     * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
-     */
-    private ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
-            @Nullable Task candidateTask, @Nullable ActivityOptions options,
-            @Nullable LaunchParamsController.LaunchParams launchParams) {
-        final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
-        if (displayContent == null) {
-            throw new IllegalArgumentException(
-                    "Display with displayId=" + displayId + " not found.");
-        }
-
-        if (!r.canBeLaunchedOnDisplay(displayId)) {
-            return null;
-        }
-
-        // If {@code r} is already in target display and its task is the same as the candidate task,
-        // the intention should be getting a launch stack for the reusable activity, so we can use
-        // the existing stack.
-        if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) {
-            final int attachedDisplayId = r.getDisplayId();
-            if (attachedDisplayId == INVALID_DISPLAY || attachedDisplayId == displayId) {
-                return candidateTask.getStack();
-            }
-        }
-
-        int windowingMode;
-        if (launchParams != null) {
-            // When launch params is not null, we always defer to its windowing mode. Sometimes
-            // it could be unspecified, which indicates it should inherit windowing mode from
-            // display.
-            windowingMode = launchParams.mWindowingMode;
-        } else {
-            windowingMode = options != null ? options.getLaunchWindowingMode()
-                    : r.getWindowingMode();
-        }
-        windowingMode = displayContent.validateWindowingMode(windowingMode, r, candidateTask,
-                r.getActivityType());
-
-        // Return the topmost valid stack on the display.
-        for (int i = displayContent.getStackCount() - 1; i >= 0; --i) {
-            final ActivityStack stack = displayContent.getStackAt(i);
-            if (isValidLaunchStack(stack, r, windowingMode)) {
-                return stack;
-            }
-        }
-
-        // If there is no valid stack on the external display - check if new dynamic stack will do.
-        if (displayId != DEFAULT_DISPLAY) {
-            final int activityType =
-                    options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
-                            ? options.getLaunchActivityType() : r.getActivityType();
-            return displayContent.createStack(windowingMode, activityType, true /*onTop*/);
-        }
-
-        return null;
-    }
-
-    ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
-            @Nullable ActivityOptions options,
-            @Nullable LaunchParamsController.LaunchParams launchParams) {
-        return getValidLaunchStackOnDisplay(displayId, r, null /* candidateTask */, options,
-                launchParams);
-    }
-
-    // TODO: Can probably be consolidated into getLaunchStack()...
-    private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) {
-        switch (stack.getActivityType()) {
-            case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome();
-            case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
-            case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
-        }
-        // There is a 1-to-1 relationship between stack and task when not in
-        // primary split-windowing mode.
-        if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                && r.supportsSplitScreenWindowingMode()
-                && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                || windowingMode == WINDOWING_MODE_UNDEFINED)) {
-            return true;
-        }
-        return false;
-    }
-
-    int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
-            @Nullable Task task) {
-        // Preference is given to the activity type for the activity then the task since the type
-        // once set shouldn't change.
-        int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
-        if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) {
-            activityType = task.getActivityType();
-        }
-        if (activityType != ACTIVITY_TYPE_UNDEFINED) {
-            return activityType;
-        }
-        if (options != null) {
-            activityType = options.getLaunchActivityType();
-        }
-        return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD;
-    }
-
-    /**
-     * Get next focusable stack in the system. This will search through the stack on the same
-     * display as the current focused stack, looking for a focusable and visible stack, different
-     * from the target stack. If no valid candidates will be found, it will then go through all
-     * displays and stacks in last-focused order.
-     *
-     * @param currentFocus The stack that previously had focus.
-     * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
-     *                     candidate.
-     * @return Next focusable {@link ActivityStack}, {@code null} if not found.
-     */
-    ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus,
-            boolean ignoreCurrent) {
-        // First look for next focusable stack on the same display
-        DisplayContent preferredDisplay = currentFocus.getDisplay();
-        if (preferredDisplay == null) {
-            // Stack is currently detached because it is being removed. Use the previous display it
-            // was on.
-            preferredDisplay = getDisplayContent(currentFocus.mPrevDisplayId);
-        }
-        final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack(
-                currentFocus, ignoreCurrent);
-        if (preferredFocusableStack != null) {
-            return preferredFocusableStack;
-        }
-        if (preferredDisplay.supportsSystemDecorations()) {
-            // Stop looking for focusable stack on other displays because the preferred display
-            // supports system decorations. Home activity would be launched on the same display if
-            // no focusable stack found.
-            return null;
-        }
-
-        // Now look through all displays
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final DisplayContent display = getChildAt(i);
-            if (display == preferredDisplay) {
-                // We've already checked this one
-                continue;
-            }
-            final ActivityStack nextFocusableStack = display.getNextFocusableStack(currentFocus,
-                    ignoreCurrent);
-            if (nextFocusableStack != null) {
-                return nextFocusableStack;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Get next valid stack for launching provided activity in the system. This will search across
-     * displays and stacks in last-focused order for a focusable and visible stack, except those
-     * that are on a currently focused display.
-     *
-     * @param r The activity that is being launched.
-     * @param currentFocus The display that previously had focus and thus needs to be ignored when
-     *                     searching for the next candidate.
-     * @return Next valid {@link ActivityStack}, null if not found.
-     */
-    ActivityStack getNextValidLaunchStack(@NonNull ActivityRecord r, int currentFocus) {
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final DisplayContent display = getChildAt(i);
-            if (display.mDisplayId == currentFocus) {
-                continue;
-            }
-            final ActivityStack stack = getValidLaunchStackOnDisplay(display.mDisplayId, r,
-                    null /* options */, null /* launchParams */);
-            if (stack != null) {
-                return stack;
-            }
-        }
-        return null;
-    }
-
-    boolean handleAppDied(WindowProcessController app) {
-        boolean hasVisibleActivities = false;
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                hasVisibleActivities |= stack.handleAppDied(app);
-            }
-        }
-        return hasVisibleActivities;
-    }
-
-    void closeSystemDialogs() {
-        forAllActivities((r) -> {
-            if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
-                r.finishIfPossible("close-sys", true /* oomAdj */);
-            }
-        });
-    }
-
-    FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper =
-            new FinishDisabledPackageActivitiesHelper();
-    class FinishDisabledPackageActivitiesHelper {
-        private boolean mDidSomething;
-        private String mPackageName;
-        private Set<String> mFilterByClasses;
-        private boolean mDoit;
-        private boolean mEvenPersistent;
-        private int mUserId;
-        private Task mLastTask;
-        private ComponentName mHomeActivity;
-
-        private void reset(String packageName, Set<String> filterByClasses,
-                boolean doit, boolean evenPersistent, int userId) {
-            mDidSomething = false;
-            mPackageName = packageName;
-            mFilterByClasses = filterByClasses;
-            mDoit = doit;
-            mEvenPersistent = evenPersistent;
-            mUserId = userId;
-            mLastTask = null;
-            mHomeActivity = null;
-        }
-
-        boolean process(String packageName, Set<String> filterByClasses,
-                boolean doit, boolean evenPersistent, int userId) {
-            reset(packageName, filterByClasses, doit, evenPersistent, userId);
-
-            final PooledFunction f = PooledLambda.obtainFunction(
-                    FinishDisabledPackageActivitiesHelper::processActivity, this,
-                    PooledLambda.__(ActivityRecord.class));
-            forAllActivities(f);
-            f.recycle();
-            return mDidSomething;
-        }
-
-        private boolean processActivity(ActivityRecord r) {
-            final boolean sameComponent =
-                    (r.packageName.equals(mPackageName) && (mFilterByClasses == null
-                            || mFilterByClasses.contains(r.mActivityComponent.getClassName())))
-                            || (mPackageName == null && r.mUserId == mUserId);
-            if ((mUserId == UserHandle.USER_ALL || r.mUserId == mUserId)
-                    && (sameComponent || r.getTask() == mLastTask)
-                    && (r.app == null || mEvenPersistent || !r.app.isPersistent())) {
-                if (!mDoit) {
-                    if (r.finishing) {
-                        // If this activity is just finishing, then it is not
-                        // interesting as far as something to stop.
-                        return false;
-                    }
-                    return true;
-                }
-                if (r.isActivityTypeHome()) {
-                    if (mHomeActivity != null && mHomeActivity.equals(r.mActivityComponent)) {
-                        Slog.i(TAG, "Skip force-stop again " + r);
-                        return false;
-                    } else {
-                        mHomeActivity = r.mActivityComponent;
-                    }
-                }
-                mDidSomething = true;
-                Slog.i(TAG, "  Force finishing activity " + r);
-                mLastTask = r.getTask();
-                r.finishIfPossible("force-stop", true);
-            }
-
-            return false;
-        }
-    }
-
-    /** @return true if some activity was finished (or would have finished if doit were true). */
-    boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
-            boolean doit, boolean evenPersistent, int userId) {
-        return mFinishDisabledPackageActivitiesHelper.process(packageName, filterByClasses, doit,
-                evenPersistent, userId);
-    }
-
-    void updateActivityApplicationInfo(ApplicationInfo aInfo) {
-        final String packageName = aInfo.packageName;
-        final int userId = UserHandle.getUserId(aInfo.uid);
-        final PooledConsumer c = PooledLambda.obtainConsumer(
-                RootActivityContainer::updateActivityApplicationInfo,
-                PooledLambda.__(ActivityRecord.class), aInfo, userId, packageName);
-        forAllActivities(c);
-        c.recycle();
-    }
-
-    private static void updateActivityApplicationInfo(
-            ActivityRecord r, ApplicationInfo aInfo, int userId, String packageName) {
-        if (r.mUserId == userId && packageName.equals(r.packageName)) {
-            r.updateApplicationInfo(aInfo);
-        }
-    }
-
-    void finishVoiceTask(IVoiceInteractionSession session) {
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            final int numStacks = display.getStackCount();
-            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                stack.finishVoiceTask(session);
-            }
-        }
-    }
-
-    /**
-     * Removes stacks in the input windowing modes from the system if they are of activity type
-     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
-     */
-    void removeStacksInWindowingModes(int... windowingModes) {
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            getChildAt(i).removeStacksInWindowingModes(windowingModes);
-        }
-    }
-
-    void removeStacksWithActivityTypes(int... activityTypes) {
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            getChildAt(i).removeStacksWithActivityTypes(activityTypes);
-        }
-    }
-
-    ActivityRecord topRunningActivity() {
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final ActivityRecord topActivity = getChildAt(i).topRunningActivity();
-            if (topActivity != null) {
-                return topActivity;
-            }
-        }
-        return null;
-    }
-
-    boolean allResumedActivitiesIdle() {
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            // TODO(b/117135575): Check resumed activities on all visible stacks.
-            final DisplayContent display = getChildAt(displayNdx);
-            if (display.isSleeping()) {
-                // No resumed activities while display is sleeping.
-                continue;
-            }
-
-            // If the focused stack is not null or not empty, there should have some activities
-            // resuming or resumed. Make sure these activities are idle.
-            final ActivityStack stack = display.getFocusedStack();
-            if (stack == null || !stack.hasActivity()) {
-                continue;
-            }
-            final ActivityRecord resumedActivity = stack.getResumedActivity();
-            if (resumedActivity == null || !resumedActivity.idle) {
-                if (DEBUG_STATES) {
-                    Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
-                            + stack.mStackId + " " + resumedActivity + " not idle");
-                }
-                return false;
-            }
-        }
-        // Send launch end powerhint when idle
-        sendPowerHintForLaunchEndIfNeeded();
-        return true;
-    }
-
-    boolean allResumedActivitiesVisible() {
-        boolean foundResumed = false;
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                final ActivityRecord r = stack.getResumedActivity();
-                if (r != null) {
-                    if (!r.nowVisible) {
-                        return false;
-                    }
-                    foundResumed = true;
-                }
-            }
-        }
-        return foundResumed;
-    }
-
-    boolean allPausedActivitiesComplete() {
-        boolean pausing = true;
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                final ActivityRecord r = stack.mPausingActivity;
-                if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
-                    if (DEBUG_STATES) {
-                        Slog.d(TAG_STATES,
-                                "allPausedActivitiesComplete: r=" + r + " state=" + r.getState());
-                        pausing = false;
-                    } else {
-                        return false;
-                    }
-                }
-            }
-        }
-        return pausing;
-    }
-
-    /**
-     * Find all visible task stacks containing {@param userId} and intercept them with an activity
-     * to block out the contents and possibly start a credential-confirming intent.
-     *
-     * @param userId user handle for the locked managed profile.
-     */
-    void lockAllProfileTasks(@UserIdInt int userId) {
-        mService.deferWindowLayout();
-        try {
-            final PooledConsumer c = PooledLambda.obtainConsumer(
-                    RootActivityContainer::taskTopActivityIsUser, this, PooledLambda.__(Task.class),
-                    userId);
-            forAllTasks(c);
-            c.recycle();
-        } finally {
-            mService.continueWindowLayout();
-        }
-    }
-
-    /**
-     * Detects whether we should show a lock screen in front of this task for a locked user.
-     * <p>
-     * We'll do this if either of the following holds:
-     * <ul>
-     *   <li>The top activity explicitly belongs to {@param userId}.</li>
-     *   <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
-     * </ul>
-     *
-     * @return {@code true} if the top activity looks like it belongs to {@param userId}.
-     */
-    private void taskTopActivityIsUser(Task task, @UserIdInt int userId) {
-        // To handle the case that work app is in the task but just is not the top one.
-        final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
-        final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
-
-        // Check the task for a top activity belonging to userId, or returning a
-        // result to an activity belonging to userId. Example case: a document
-        // picker for personal files, opened by a work app, should still get locked.
-        if ((activityRecord != null && activityRecord.mUserId == userId)
-                || (resultTo != null && resultTo.mUserId == userId)) {
-            mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
-                    task.mTaskId, userId);
-        }
-    }
-
-    void cancelInitializingActivities() {
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                stack.cancelInitializingActivities();
-            }
-        }
-    }
-
-    Task anyTaskForId(int id) {
-        return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE);
-    }
-
-    Task anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode) {
-        return anyTaskForId(id, matchMode, null, !ON_TOP);
-    }
-
-    /**
-     * Returns a {@link Task} for the input id if available. {@code null} otherwise.
-     * @param id Id of the task we would like returned.
-     * @param matchMode The mode to match the given task id in.
-     * @param aOptions The activity options to use for restoration. Can be null.
-     * @param onTop If the stack for the task should be the topmost on the display.
-     */
-    Task anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode,
-            @Nullable ActivityOptions aOptions, boolean onTop) {
-        // If options are set, ensure that we are attempting to actually restore a task
-        if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
-            throw new IllegalArgumentException("Should not specify activity options for non-restore"
-                    + " lookup");
-        }
-
-        final PooledPredicate p = PooledLambda.obtainPredicate(
-                Task::isTaskId, PooledLambda.__(Task.class), id);
-        Task task = getTask(p);
-        p.recycle();
-
-        if (task != null) {
-            if (aOptions != null) {
-                // Resolve the stack the task should be placed in now based on options
-                // and reparent if needed.
-                final ActivityStack launchStack =
-                        getLaunchStack(null, aOptions, task, onTop);
-                if (launchStack != null && task.getStack() != launchStack) {
-                    final int reparentMode = onTop
-                            ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
-                    task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
-                            "anyTaskForId");
-                }
-            }
-            return task;
-        }
-
-        // If we are matching stack tasks only, return now
-        if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
-            return null;
-        }
-
-        // Otherwise, check the recent tasks and return if we find it there and we are not restoring
-        // the task from recents
-        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
-        task = mStackSupervisor.mRecentTasks.getTask(id);
-
-        if (task == null) {
-            if (DEBUG_RECENTS) {
-                Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
-            }
-
-            return null;
-        }
-
-        if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
-            return task;
-        }
-
-        // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
-        if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
-            if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
-                    "Couldn't restore task id=" + id + " found in recents");
-            return null;
-        }
-        if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
-        return task;
-    }
-
-    ActivityRecord isInAnyStack(IBinder token) {
-        int numDisplays = getChildCount();
-        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final DisplayContent display = getChildAt(displayNdx);
-            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getStackAt(stackNdx);
-                final ActivityRecord r = stack.isInStackLocked(token);
-                if (r != null) {
-                    return r;
-                }
-            }
-        }
-        return null;
-    }
-
-    @VisibleForTesting
-    void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
-            @WindowConfiguration.ActivityType int ignoreActivityType,
-            @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid,
-            boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
-        mStackSupervisor.getRunningTasks().getTasks(maxNum, list, ignoreActivityType,
-                ignoreWindowingMode, this, callingUid, allowed, crossUser, profileIds);
-    }
-
-    void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
-        boolean sendHint = forceSend;
-
-        if (!sendHint) {
-            // Send power hint if we don't know what we're launching yet
-            sendHint = targetActivity == null || targetActivity.app == null;
-        }
-
-        if (!sendHint) { // targetActivity != null
-            // Send power hint when the activity's process is different than the current resumed
-            // activity on all displays, or if there are no resumed activities in the system.
-            boolean noResumedActivities = true;
-            boolean allFocusedProcessesDiffer = true;
-            for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
-                final DisplayContent displayContent = getChildAt(displayNdx);
-                final ActivityRecord resumedActivity = displayContent.getResumedActivity();
-                final WindowProcessController resumedActivityProcess =
-                        resumedActivity == null ? null : resumedActivity.app;
-
-                noResumedActivities &= resumedActivityProcess == null;
-                if (resumedActivityProcess != null) {
-                    allFocusedProcessesDiffer &= !resumedActivityProcess.equals(targetActivity.app);
-                }
-            }
-            sendHint = noResumedActivities || allFocusedProcessesDiffer;
-        }
-
-        if (sendHint && mService.mPowerManagerInternal != null) {
-            mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
-            mPowerHintSent = true;
-        }
-    }
-
-    void sendPowerHintForLaunchEndIfNeeded() {
-        // Trigger launch power hint if activity is launched
-        if (mPowerHintSent && mService.mPowerManagerInternal != null) {
-            mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
-            mPowerHintSent = false;
-        }
-    }
-
-    private void calculateDefaultMinimalSizeOfResizeableTasks() {
-        final Resources res = mService.mContext.getResources();
-        final float minimalSize = res.getDimension(
-                com.android.internal.R.dimen.default_minimal_size_resizable_task);
-        final DisplayMetrics dm = res.getDisplayMetrics();
-
-        mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density);
-    }
-
-    /**
-     * Dumps the activities matching the given {@param name} in the either the focused stack
-     * or all visible stacks if {@param dumpVisibleStacks} is true.
-     */
-    ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly,
-            boolean dumpFocusedStackOnly) {
-        if (dumpFocusedStackOnly) {
-            return getTopDisplayFocusedStack().getDumpActivitiesLocked(name);
-        } else {
-            ArrayList<ActivityRecord> activities = new ArrayList<>();
-            int numDisplays = getChildCount();
-            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-                final DisplayContent display = getChildAt(displayNdx);
-                for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                    final ActivityStack stack = display.getStackAt(stackNdx);
-                    if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
-                        activities.addAll(stack.getDumpActivitiesLocked(name));
-                    }
-                }
-            }
-            return activities;
-        }
-    }
-
-    public void dump(PrintWriter pw, String prefix) {
-        pw.print(prefix);
-        pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final DisplayContent display = getChildAt(i);
-            display.dump(pw, prefix, true /* dumpAll */);
-        }
-    }
-
-    /**
-     * Dump all connected displays' configurations.
-     * @param prefix Prefix to apply to each line of the dump.
-     */
-    void dumpDisplayConfigs(PrintWriter pw, String prefix) {
-        pw.print(prefix); pw.println("Display override configurations:");
-        final int displayCount = getChildCount();
-        for (int i = 0; i < displayCount; i++) {
-            final DisplayContent displayContent = getChildAt(i);
-            pw.print(prefix); pw.print("  "); pw.print(displayContent.mDisplayId); pw.print(": ");
-            pw.println(displayContent.getRequestedOverrideConfiguration());
-        }
-    }
-
-    public void dumpDisplays(PrintWriter pw) {
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            final DisplayContent display = getChildAt(i);
-            pw.print("[id:" + display.mDisplayId + " stacks:");
-            display.dumpStacks(pw);
-            pw.print("]");
-        }
-    }
-
-    boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
-            String dumpPackage) {
-        boolean printed = false;
-        boolean needSep = false;
-        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
-            DisplayContent displayContent = getChildAt(displayNdx);
-            pw.print("Display #"); pw.print(displayContent.mDisplayId);
-            pw.println(" (activities from top to bottom):");
-            for (int stackNdx = displayContent.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = displayContent.getStackAt(stackNdx);
-                pw.println();
-                printed = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, needSep);
-                needSep = printed;
-            }
-            printThisActivity(pw, displayContent.getResumedActivity(), dumpPackage, needSep,
-                    " ResumedActivity:");
-        }
-
-        printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, "  ",
-                "Fin", false, !dumpAll,
-                false, dumpPackage, true, "  Activities waiting to finish:", null);
-        printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, "  ",
-                "Stop", false, !dumpAll,
-                false, dumpPackage, true, "  Activities waiting to stop:", null);
-        printed |= dumpHistoryList(fd, pw, mStackSupervisor.mGoingToSleepActivities,
-                "  ", "Sleep", false, !dumpAll,
-                false, dumpPackage, true, "  Activities waiting to sleep:", null);
-
-        return printed;
-    }
-
-    @Override
-    public void dumpDebug(ProtoOutputStream proto, long fieldId,
-            @WindowTraceLogLevel int logLevel) {
-        final long token = proto.start(fieldId);
-        dumpDebugInner(proto, ROOT_WINDOW_CONTAINER, logLevel);
-        for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
-            final DisplayContent displayContent = getChildAt(displayNdx);
-            displayContent.dumpDebug(proto, DISPLAYS, logLevel);
-        }
-        mStackSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER);
-        // TODO(b/111541062): Update tests to look for resumed activities on all displays
-        final ActivityStack focusedStack = getTopDisplayFocusedStack();
-        if (focusedStack != null) {
-            proto.write(FOCUSED_STACK_ID, focusedStack.mStackId);
-            final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity();
-            if (focusedActivity != null) {
-                focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
-            }
-        } else {
-            proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
-        }
-        proto.write(IS_HOME_RECENTS_COMPONENT,
-                mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
-        mService.getActivityStartController().dumpDebug(proto, PENDING_ACTIVITIES);
-        proto.end(token);
-    }
-
-    private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken {
-        private final String mTag;
-        private final long mAcquireTime;
-        private final int mDisplayId;
-
-        public SleepTokenImpl(String tag, int displayId) {
-            mTag = tag;
-            mDisplayId = displayId;
-            mAcquireTime = SystemClock.uptimeMillis();
-        }
-
-        @Override
-        public void release() {
-            synchronized (mService.mGlobalLock) {
-                removeSleepToken(this);
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "{\"" + mTag + "\", display " + mDisplayId
-                    + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 936d643..5470327 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -16,6 +16,21 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
@@ -24,9 +39,36 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
+import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
 
+import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID;
+import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT;
+import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
+import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES;
+import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
+import static com.android.server.am.ActivityStackSupervisorProto.ROOT_WINDOW_CONTAINER;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
+import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
+import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
+import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
+import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
+import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
+import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
+import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
+import static com.android.server.wm.ActivityTaskManagerService.TAG_SWITCH;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
@@ -35,6 +77,8 @@
 import static com.android.server.wm.RootWindowContainerProto.DISPLAYS;
 import static com.android.server.wm.RootWindowContainerProto.WINDOWS;
 import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER;
+import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE;
+import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
@@ -50,45 +94,95 @@
 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
 
+import static java.lang.Integer.MAX_VALUE;
+
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.AppGlobals;
+import android.app.WindowConfiguration;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManagerInternal;
 import android.hardware.power.V1_0.PowerHint;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Debug;
+import android.os.FactoryTest;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.os.storage.StorageManager;
+import android.provider.Settings;
+import android.service.voice.IVoiceInteractionSession;
 import android.util.ArraySet;
+import android.util.DisplayMetrics;
+import android.util.IntArray;
+import android.util.Pair;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.SparseIntArray;
+import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
+import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.ResolverActivity;
+import com.android.internal.util.function.pooled.PooledConsumer;
+import com.android.internal.util.function.pooled.PooledFunction;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.internal.util.function.pooled.PooledPredicate;
+import com.android.server.LocalServices;
+import com.android.server.am.ActivityManagerService;
+import com.android.server.am.AppTimeTracker;
+import com.android.server.am.UserState;
+import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.protolog.common.ProtoLog;
 
+import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
+import java.util.Set;
 import java.util.function.Consumer;
+import java.util.function.Function;
 
 /** Root {@link WindowContainer} for the device. */
-class RootWindowContainer extends WindowContainer<DisplayContent> {
+class RootWindowContainer extends WindowContainer<DisplayContent>
+        implements DisplayManager.DisplayListener {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
 
     private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
     private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
+    static final String TAG_TASKS = TAG + POSTFIX_TASKS;
+    private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
+    static final String TAG_STATES = TAG + POSTFIX_STATES;
+    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
 
     private Object mLastWindowFreezeSource = null;
     private Session mHoldScreen = null;
@@ -129,6 +223,213 @@
     // transaction from the global transaction.
     private final SurfaceControl.Transaction mDisplayTransaction;
 
+    /**
+     * The modes which affect which tasks are returned when calling
+     * {@link RootWindowContainer#anyTaskForId(int)}.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            MATCH_TASK_IN_STACKS_ONLY,
+            MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
+            MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
+    })
+    public @interface AnyTaskForIdMatchTaskMode {}
+    // Match only tasks in the current stacks
+    static final int MATCH_TASK_IN_STACKS_ONLY = 0;
+    // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
+    static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
+    // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
+    // provided stack id
+    static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
+
+    ActivityTaskManagerService mService;
+    ActivityStackSupervisor mStackSupervisor;
+    WindowManagerService mWindowManager;
+    DisplayManager mDisplayManager;
+    private DisplayManagerInternal mDisplayManagerInternal;
+
+    /** Reference to default display so we can quickly look it up. */
+    private DisplayContent mDefaultDisplay;
+    private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
+
+    /** The current user */
+    int mCurrentUser;
+    /** Stack id of the front stack when user switched, indexed by userId. */
+    SparseIntArray mUserStackInFront = new SparseIntArray(2);
+
+    /**
+     * A list of tokens that cause the top activity to be put to sleep.
+     * They are used by components that may hide and block interaction with underlying
+     * activities.
+     */
+    final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>();
+
+    /** Is dock currently minimized. */
+    boolean mIsDockMinimized;
+
+    /** Set when a power hint has started, but not ended. */
+    private boolean mPowerHintSent;
+
+    /** Used to keep ensureActivitiesVisible() from being entered recursively. */
+    private boolean mInEnsureActivitiesVisible = false;
+
+    // The default minimal size that will be used if the activity doesn't specify its minimal size.
+    // It will be calculated when the default display gets added.
+    int mDefaultMinSizeOfResizeableTaskDp = -1;
+
+    // Whether tasks have moved and we need to rank the tasks before next OOM scoring
+    private boolean mTaskLayersChanged = true;
+    private int mTmpTaskLayerRank;
+
+    private boolean mTmpBoolean;
+    private RemoteException mTmpRemoteException;
+
+    private String mDestroyAllActivitiesReason;
+    private final Runnable mDestroyAllActivitiesRunnable = new Runnable() {
+        @Override
+        public void run() {
+            synchronized (mService.mGlobalLock) {
+                try {
+                    mStackSupervisor.beginDeferResume();
+
+                    final PooledConsumer c = PooledLambda.obtainConsumer(
+                            RootWindowContainer::destroyActivity, RootWindowContainer.this,
+                            PooledLambda.__(ActivityRecord.class));
+                    forAllActivities(c);
+                    c.recycle();
+                } finally {
+                    mStackSupervisor.endDeferResume();
+                    resumeFocusedStacksTopActivities();
+                }
+            }
+        }
+
+    };
+
+    private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
+    static class FindTaskResult implements Function<Task, Boolean> {
+        ActivityRecord mRecord;
+        boolean mIdealMatch;
+
+        private ActivityRecord mTarget;
+        private Intent intent;
+        private ActivityInfo info;
+        private ComponentName cls;
+        private int userId;
+        private boolean isDocument;
+        private Uri documentData;
+
+        /**
+         * Returns the top activity in any existing task matching the given Intent in the input
+         * result. Returns null if no such task is found.
+         */
+        void process(ActivityRecord target, ActivityStack parent) {
+            mTarget = target;
+
+            intent = target.intent;
+            info = target.info;
+            cls = intent.getComponent();
+            if (info.targetActivity != null) {
+                cls = new ComponentName(info.packageName, info.targetActivity);
+            }
+            userId = UserHandle.getUserId(info.applicationInfo.uid);
+            isDocument = intent != null & intent.isDocument();
+            // If documentData is non-null then it must match the existing task data.
+            documentData = isDocument ? intent.getData() : null;
+
+            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + parent);
+            parent.forAllTasks(this);
+        }
+
+        void clear() {
+            mRecord = null;
+            mIdealMatch = false;
+        }
+
+        void setTo(FindTaskResult result) {
+            mRecord = result.mRecord;
+            mIdealMatch = result.mIdealMatch;
+        }
+
+        @Override
+        public Boolean apply(Task task) {
+            if (task.voiceSession != null) {
+                // We never match voice sessions; those always run independently.
+                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
+                return false;
+            }
+            if (task.mUserId != userId) {
+                // Looking for a different task.
+                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
+                return false;
+            }
+
+            // Overlays should not be considered as the task's logical top activity.
+            final ActivityRecord r = task.getTopNonFinishingActivity(false /* includeOverlays */);
+            if (r == null || r.finishing || r.mUserId != userId
+                    || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
+                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
+                return false;
+            }
+            if (!r.hasCompatibleActivityType(mTarget)) {
+                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
+                return false;
+            }
+
+            final Intent taskIntent = task.intent;
+            final Intent affinityIntent = task.affinityIntent;
+            final boolean taskIsDocument;
+            final Uri taskDocumentData;
+            if (taskIntent != null && taskIntent.isDocument()) {
+                taskIsDocument = true;
+                taskDocumentData = taskIntent.getData();
+            } else if (affinityIntent != null && affinityIntent.isDocument()) {
+                taskIsDocument = true;
+                taskDocumentData = affinityIntent.getData();
+            } else {
+                taskIsDocument = false;
+                taskDocumentData = null;
+            }
+
+            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
+                    + (task.realActivity != null ? task.realActivity.flattenToShortString() : "")
+                    + "/aff=" + r.getTask().rootAffinity + " to new cls="
+                    + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
+            // TODO Refactor to remove duplications. Check if logic can be simplified.
+            if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
+                    && Objects.equals(documentData, taskDocumentData)) {
+                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
+                //dump();
+                if (DEBUG_TASKS) Slog.d(TAG_TASKS,
+                        "For Intent " + intent + " bringing to top: " + r.intent);
+                mRecord = r;
+                mIdealMatch = true;
+                return true;
+            } else if (affinityIntent != null && affinityIntent.getComponent() != null
+                    && affinityIntent.getComponent().compareTo(cls) == 0 &&
+                    Objects.equals(documentData, taskDocumentData)) {
+                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
+                if (DEBUG_TASKS) Slog.d(TAG_TASKS,
+                        "For Intent " + intent + " bringing to top: " + r.intent);
+                mRecord = r;
+                mIdealMatch = true;
+                return true;
+            } else if (!isDocument && !taskIsDocument
+                    && mRecord == null && task.rootAffinity != null) {
+                if (task.rootAffinity.equals(mTarget.taskAffinity)) {
+                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!");
+                    // It is possible for multiple tasks to have the same root affinity especially
+                    // if they are in separate stacks. We save off this candidate, but keep looking
+                    // to see if there is a better candidate.
+                    mRecord = r;
+                    mIdealMatch = false;
+                }
+            } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
+
+            return false;
+        }
+    }
+
     private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
         if (w.mHasSurface) {
             try {
@@ -149,6 +450,9 @@
         super(service);
         mDisplayTransaction = service.mTransactionFactory.get();
         mHandler = new MyHandler(service.mH.getLooper());
+        mService = service.mAtmService;
+        mStackSupervisor = mService.mStackSupervisor;
+        mStackSupervisor.mRootWindowContainer = this;
     }
 
     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
@@ -204,16 +508,6 @@
                 !mWmService.mPerDisplayFocusEnabled /* updateInputWindows */);
     }
 
-    DisplayContent getDisplayContent(int displayId) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final DisplayContent current = mChildren.get(i);
-            if (current.getDisplayId() == displayId) {
-                return current;
-            }
-        }
-        return null;
-    }
-
     /**
      * Called when DisplayWindowSettings values may change.
      */
@@ -379,17 +673,6 @@
         }
     }
 
-    ActivityStack getStack(int windowingMode, int activityType) {
-        for (int i = mChildren.size() - 1; i >= 0; i--) {
-            final DisplayContent dc = mChildren.get(i);
-            final ActivityStack stack = dc.getStack(windowingMode, activityType);
-            if (stack != null) {
-                return stack;
-            }
-        }
-        return null;
-    }
-
     void setSecureSurfaceState(int userId, boolean disabled) {
         forAllWindows((w) -> {
             if (w.mHasSurface && userId == UserHandle.getUserId(w.mOwnerUid)) {
@@ -1083,4 +1366,2289 @@
         return getDisplayContent(displayId) != null
                 ? getDisplayContent(displayId).getDisplayUiContext() : null;
     }
+
+    void setWindowManager(WindowManagerService wm) {
+        mWindowManager = wm;
+        mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
+        mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
+        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
+
+        final Display[] displays = mDisplayManager.getDisplays();
+        for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
+            final Display display = displays[displayNdx];
+            final DisplayContent displayContent = new DisplayContent(display, this);
+            if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
+                mDefaultDisplay = displayContent;
+            }
+        }
+        calculateDefaultMinimalSizeOfResizeableTasks();
+
+        final DisplayContent defaultDisplay = getDefaultDisplay();
+
+        defaultDisplay.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+        positionChildAt(POSITION_TOP, defaultDisplay, false /* includingParents */);
+    }
+
+    // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
+    DisplayContent getDefaultDisplay() {
+        return mDefaultDisplay;
+    }
+
+    /**
+     * Get an existing instance of {@link DisplayContent} that has the given uniqueId. Unique ID is
+     * defined in {@link DisplayInfo#uniqueId}.
+     *
+     * @param uniqueId the unique ID of the display
+     * @return the {@link DisplayContent} or {@code null} if nothing is found.
+     */
+    DisplayContent getDisplayContent(String uniqueId) {
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final DisplayContent display = getChildAt(i);
+            final boolean isValid = display.mDisplay.isValid();
+            if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
+                return display;
+            }
+        }
+
+        return null;
+    }
+
+    // TODO: Look into consolidating with getDisplayContentOrCreate()
+    DisplayContent getDisplayContent(int displayId) {
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final DisplayContent displayContent = getChildAt(i);
+            if (displayContent.mDisplayId == displayId) {
+                return displayContent;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get an existing instance of {@link DisplayContent} or create new if there is a
+     * corresponding record in display manager.
+     */
+    // TODO: Look into consolidating with getDisplayContent()
+    @Nullable DisplayContent getDisplayContentOrCreate(int displayId) {
+        DisplayContent displayContent = getDisplayContent(displayId);
+        if (displayContent != null) {
+            return displayContent;
+        }
+        if (mDisplayManager == null) {
+            // The system isn't fully initialized yet.
+            return null;
+        }
+        final Display display = mDisplayManager.getDisplay(displayId);
+        if (display == null) {
+            // The display is not registered in DisplayManager.
+            return null;
+        }
+        // The display hasn't been added to ActivityManager yet, create a new record now.
+        displayContent = new DisplayContent(display, this);
+        return displayContent;
+    }
+
+    ActivityRecord getDefaultDisplayHomeActivity() {
+        return getDefaultDisplayHomeActivityForUser(mCurrentUser);
+    }
+
+    ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
+        return getDisplayContent(DEFAULT_DISPLAY).getHomeActivityForUser(userId);
+    }
+
+    boolean startHomeOnAllDisplays(int userId, String reason) {
+        boolean homeStarted = false;
+        for (int i = getChildCount() - 1; i >= 0; i--) {
+            final int displayId = getChildAt(i).mDisplayId;
+            homeStarted |= startHomeOnDisplay(userId, reason, displayId);
+        }
+        return homeStarted;
+    }
+
+    void startHomeOnEmptyDisplays(String reason) {
+        for (int i = getChildCount() - 1; i >= 0; i--) {
+            final DisplayContent display = getChildAt(i);
+            if (display.topRunningActivity() == null) {
+                startHomeOnDisplay(mCurrentUser, reason, display.mDisplayId);
+            }
+        }
+    }
+
+    boolean startHomeOnDisplay(int userId, String reason, int displayId) {
+        return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
+                false /* fromHomeKey */);
+    }
+
+    /**
+     * This starts home activity on displays that can have system decorations based on displayId -
+     * Default display always use primary home component.
+     * For Secondary displays, the home activity must have category SECONDARY_HOME and then resolves
+     * according to the priorities listed below.
+     *  - If default home is not set, always use the secondary home defined in the config.
+     *  - Use currently selected primary home activity.
+     *  - Use the activity in the same package as currently selected primary home activity.
+     *    If there are multiple activities matched, use first one.
+     *  - Use the secondary home defined in the config.
+     */
+    boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
+            boolean fromHomeKey) {
+        // Fallback to top focused display if the displayId is invalid.
+        if (displayId == INVALID_DISPLAY) {
+            final ActivityStack stack = getTopDisplayFocusedStack();
+            displayId = stack != null ? stack.mDisplayId : DEFAULT_DISPLAY;
+        }
+
+        Intent homeIntent = null;
+        ActivityInfo aInfo = null;
+        if (displayId == DEFAULT_DISPLAY) {
+            homeIntent = mService.getHomeIntent();
+            aInfo = resolveHomeActivity(userId, homeIntent);
+        } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
+            Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
+            aInfo = info.first;
+            homeIntent = info.second;
+        }
+        if (aInfo == null || homeIntent == null) {
+            return false;
+        }
+
+        if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
+            return false;
+        }
+
+        // Updates the home component of the intent.
+        homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
+        homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
+        // Updates the extra information of the intent.
+        if (fromHomeKey) {
+            homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
+        }
+        // Update the reason for ANR debugging to verify if the user activity is the one that
+        // actually launched.
+        final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
+                aInfo.applicationInfo.uid) + ":" + displayId;
+        mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
+                displayId);
+        return true;
+    }
+
+    /**
+     * This resolves the home activity info.
+     * @return the home activity info if any.
+     */
+    @VisibleForTesting
+    ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
+        final int flags = ActivityManagerService.STOCK_PM_FLAGS;
+        final ComponentName comp = homeIntent.getComponent();
+        ActivityInfo aInfo = null;
+        try {
+            if (comp != null) {
+                // Factory test.
+                aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
+            } else {
+                final String resolvedType =
+                        homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
+                final ResolveInfo info = AppGlobals.getPackageManager()
+                        .resolveIntent(homeIntent, resolvedType, flags, userId);
+                if (info != null) {
+                    aInfo = info.activityInfo;
+                }
+            }
+        } catch (RemoteException e) {
+            // ignore
+        }
+
+        if (aInfo == null) {
+            Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
+            return null;
+        }
+
+        aInfo = new ActivityInfo(aInfo);
+        aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
+        return aInfo;
+    }
+
+    @VisibleForTesting
+    Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId, int displayId) {
+        if (displayId == DEFAULT_DISPLAY) {
+            throw new IllegalArgumentException(
+                    "resolveSecondaryHomeActivity: Should not be DEFAULT_DISPLAY");
+        }
+        // Resolve activities in the same package as currently selected primary home activity.
+        Intent homeIntent = mService.getHomeIntent();
+        ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent);
+        if (aInfo != null) {
+            if (ResolverActivity.class.getName().equals(aInfo.name)) {
+                // Always fallback to secondary home component if default home is not set.
+                aInfo = null;
+            } else {
+                // Look for secondary home activities in the currently selected default home
+                // package.
+                homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName);
+                final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent);
+                final int size = resolutions.size();
+                final String targetName = aInfo.name;
+                aInfo = null;
+                for (int i = 0; i < size; i++) {
+                    ResolveInfo resolveInfo = resolutions.get(i);
+                    // We need to traverse all resolutions to check if the currently selected
+                    // default home activity is present.
+                    if (resolveInfo.activityInfo.name.equals(targetName)) {
+                        aInfo = resolveInfo.activityInfo;
+                        break;
+                    }
+                }
+                if (aInfo == null && size > 0) {
+                    // First one is the best.
+                    aInfo = resolutions.get(0).activityInfo;
+                }
+            }
+        }
+
+        if (aInfo != null) {
+            if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
+                aInfo = null;
+            }
+        }
+
+        // Fallback to secondary home component.
+        if (aInfo == null) {
+            homeIntent = mService.getSecondaryHomeIntent(null);
+            aInfo = resolveHomeActivity(userId, homeIntent);
+        }
+        return Pair.create(aInfo, homeIntent);
+    }
+
+    /**
+     * Retrieve all activities that match the given intent.
+     * The list should already ordered from best to worst matched.
+     * {@link android.content.pm.PackageManager#queryIntentActivities}
+     */
+    @VisibleForTesting
+    List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) {
+        List<ResolveInfo> resolutions;
+        try {
+            final String resolvedType =
+                    homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
+            resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent,
+                    resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList();
+
+        } catch (RemoteException e) {
+            resolutions = new ArrayList<>();
+        }
+        return resolutions;
+    }
+
+    boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {
+        if (!mService.isBooting() && !mService.isBooted()) {
+            // Not ready yet!
+            return false;
+        }
+
+        if (displayId == INVALID_DISPLAY) {
+            displayId = DEFAULT_DISPLAY;
+        }
+
+        final ActivityRecord r = getDisplayContent(displayId).getHomeActivity();
+        final String myReason = reason + " resumeHomeActivity";
+
+        // Only resume home activity if isn't finishing.
+        if (r != null && !r.finishing) {
+            r.moveFocusableActivityToTop(myReason);
+            return resumeFocusedStacksTopActivities(r.getActivityStack(), prev, null);
+        }
+        return startHomeOnDisplay(mCurrentUser, myReason, displayId);
+    }
+
+    /**
+     * Check if the display is valid for secondary home activity.
+     * @param displayId The id of the target display.
+     * @return {@code true} if allow to launch, {@code false} otherwise.
+     */
+    boolean shouldPlaceSecondaryHomeOnDisplay(int displayId) {
+        if (displayId == DEFAULT_DISPLAY) {
+            throw new IllegalArgumentException(
+                    "shouldPlaceSecondaryHomeOnDisplay: Should not be DEFAULT_DISPLAY");
+        } else if (displayId == INVALID_DISPLAY) {
+            return false;
+        }
+
+        if (!mService.mSupportsMultiDisplay) {
+            // Can't launch home on secondary display if device does not support multi-display.
+            return false;
+        }
+
+        final boolean deviceProvisioned = Settings.Global.getInt(
+                mService.mContext.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        if (!deviceProvisioned) {
+            // Can't launch home on secondary display before device is provisioned.
+            return false;
+        }
+
+        if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) {
+            // Can't launch home on secondary displays if device is still locked.
+            return false;
+        }
+
+        final DisplayContent display = getDisplayContent(displayId);
+        if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) {
+            // Can't launch home on display that doesn't support system decorations.
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Check if home activity start should be allowed on a display.
+     * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched.
+     * @param displayId The id of the target display.
+     * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
+     * @return {@code true} if allow to launch, {@code false} otherwise.
+     */
+    boolean canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId,
+            boolean allowInstrumenting) {
+        if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
+                && mService.mTopAction == null) {
+            // We are running in factory test mode, but unable to find the factory test app, so
+            // just sit around displaying the error message and don't try to start anything.
+            return false;
+        }
+
+        final WindowProcessController app =
+                mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid);
+        if (!allowInstrumenting && app != null && app.isInstrumenting()) {
+            // Don't do this if the home app is currently being instrumented.
+            return false;
+        }
+
+        if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
+                && displayId == mService.mVr2dDisplayId)) {
+            // No restrictions to default display or vr 2d display.
+            return true;
+        }
+
+        if (!shouldPlaceSecondaryHomeOnDisplay(displayId)) {
+            return false;
+        }
+
+        final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK
+                && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE;
+        if (!supportMultipleInstance) {
+            // Can't launch home on secondary displays if it requested to be single instance.
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Ensure all activities visibility, update orientation and configuration.
+     *
+     * @param starting The currently starting activity or {@code null} if there is none.
+     * @param displayId The id of the display where operation is executed.
+     * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
+     *                                  {@code true} if config changed.
+     * @param deferResume Whether to defer resume while updating config.
+     * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched
+     *         because of configuration update.
+     */
+    boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
+            boolean markFrozenIfConfigChanged, boolean deferResume) {
+        // First ensure visibility without updating the config just yet. We need this to know what
+        // activities are affecting configuration now.
+        // Passing null here for 'starting' param value, so that visibility of actual starting
+        // activity will be properly updated.
+        ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
+                false /* preserveWindows */, false /* notifyClients */);
+
+        if (displayId == INVALID_DISPLAY) {
+            // The caller didn't provide a valid display id, skip updating config.
+            return true;
+        }
+
+        // Force-update the orientation from the WindowManager, since we need the true configuration
+        // to send to the client now.
+        final DisplayContent displayContent = getDisplayContent(displayId);
+        Configuration config = null;
+        if (displayContent != null) {
+            config = displayContent.updateOrientation(
+                    getDisplayOverrideConfiguration(displayId),
+                    starting != null && starting.mayFreezeScreenLocked()
+                            ? starting.appToken : null,
+                    true /* forceUpdate */);
+        }
+        // Visibilities may change so let the starting activity have a chance to report. Can't do it
+        // when visibility is changed in each AppWindowToken because it may trigger wrong
+        // configuration push because the visibility of some activities may not be updated yet.
+        if (starting != null) {
+            starting.reportDescendantOrientationChangeIfNeeded();
+        }
+        if (starting != null && markFrozenIfConfigChanged && config != null) {
+            starting.frozenBeforeDestroy = true;
+        }
+
+        if (displayContent != null) {
+            // Update the configuration of the activities on the display.
+            return displayContent.updateDisplayOverrideConfigurationLocked(config, starting,
+                    deferResume, null /* result */);
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * @return a list of activities which are the top ones in each visible stack. The first
+     * entry will be the focused activity.
+     */
+    List<IBinder> getTopVisibleActivities() {
+        final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
+        final ActivityStack topFocusedStack = getTopDisplayFocusedStack();
+        // Traverse all displays.
+        for (int i = getChildCount() - 1; i >= 0; i--) {
+            final DisplayContent display = getChildAt(i);
+            // Traverse all stacks on a display.
+            for (int j = display.getStackCount() - 1; j >= 0; --j) {
+                final ActivityStack stack = display.getStackAt(j);
+                // Get top activity from a visible stack and add it to the list.
+                if (stack.shouldBeVisible(null /* starting */)) {
+                    final ActivityRecord top = stack.getTopNonFinishingActivity();
+                    if (top != null) {
+                        if (stack == topFocusedStack) {
+                            topActivityTokens.add(0, top.appToken);
+                        } else {
+                            topActivityTokens.add(top.appToken);
+                        }
+                    }
+                }
+            }
+        }
+        return topActivityTokens;
+    }
+
+    ActivityStack getTopDisplayFocusedStack() {
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final ActivityStack focusedStack = getChildAt(i).getFocusedStack();
+            if (focusedStack != null) {
+                return focusedStack;
+            }
+        }
+        return null;
+    }
+
+    ActivityRecord getTopResumedActivity() {
+        final ActivityStack focusedStack = getTopDisplayFocusedStack();
+        if (focusedStack == null) {
+            return null;
+        }
+        final ActivityRecord resumedActivity = focusedStack.getResumedActivity();
+        if (resumedActivity != null && resumedActivity.app != null) {
+            return resumedActivity;
+        }
+        // The top focused stack might not have a resumed activity yet - look on all displays in
+        // focus order.
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final DisplayContent display = getChildAt(i);
+            final ActivityRecord resumedActivityOnDisplay = display.getResumedActivity();
+            if (resumedActivityOnDisplay != null) {
+                return resumedActivityOnDisplay;
+            }
+        }
+        return null;
+    }
+
+    boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) {
+        if (container.inSplitScreenPrimaryWindowingMode() && mIsDockMinimized) {
+            return false;
+        }
+
+        return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable;
+    }
+
+    boolean isTopDisplayFocusedStack(ActivityStack stack) {
+        return stack != null && stack == getTopDisplayFocusedStack();
+    }
+
+    void updatePreviousProcess(ActivityRecord r) {
+        // Now that this process has stopped, we may want to consider it to be the previous app to
+        // try to keep around in case the user wants to return to it.
+
+        // First, found out what is currently the foreground app, so that we don't blow away the
+        // previous app if this activity is being hosted by the process that is actually still the
+        // foreground.
+        WindowProcessController fgApp = null;
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                if (isTopDisplayFocusedStack(stack)) {
+                    final ActivityRecord resumedActivity = stack.getResumedActivity();
+                    if (resumedActivity != null) {
+                        fgApp = resumedActivity.app;
+                    } else if (stack.mPausingActivity != null) {
+                        fgApp = stack.mPausingActivity.app;
+                    }
+                    break;
+                }
+            }
+        }
+
+        // Now set this one as the previous process, only if that really makes sense to.
+        if (r.hasProcess() && fgApp != null && r.app != fgApp
+                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
+                && r.app != mService.mHomeProcess) {
+            mService.mPreviousProcess = r.app;
+            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
+        }
+    }
+
+    boolean attachApplication(WindowProcessController app) throws RemoteException {
+        final String processName = app.mName;
+        boolean didSomething = false;
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            final ActivityStack stack = display.getFocusedStack();
+            if (stack == null) {
+                continue;
+            }
+
+            mTmpRemoteException = null;
+            mTmpBoolean = false; // Set to true if an activity was started.
+            final PooledFunction c = PooledLambda.obtainFunction(
+                    RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
+                    PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
+            stack.forAllActivities(c);
+            c.recycle();
+            if (mTmpRemoteException != null) {
+                throw mTmpRemoteException;
+            }
+            didSomething |= mTmpBoolean;
+        }
+        if (!didSomething) {
+            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
+        }
+        return didSomething;
+    }
+
+    private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
+            WindowProcessController app, ActivityRecord top) {
+        if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
+                || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
+            return false;
+        }
+
+        try {
+            if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
+                    true /*checkConfig*/)) {
+                mTmpBoolean = true;
+            }
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Exception in new application when starting activity "
+                    + top.intent.getComponent().flattenToShortString(), e);
+            mTmpRemoteException = e;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Make sure that all activities that need to be visible in the system actually are and update
+     * their configuration.
+     */
+    void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
+            boolean preserveWindows) {
+        ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
+    }
+
+    /**
+     * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
+     */
+    void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
+            boolean preserveWindows, boolean notifyClients) {
+        if (mInEnsureActivitiesVisible) {
+            // Don't do recursive work.
+            return;
+        }
+        mInEnsureActivitiesVisible = true;
+
+        try {
+            mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
+            // First the front stacks. In case any are not fullscreen and are in front of home.
+            for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+                final DisplayContent display = getChildAt(displayNdx);
+                display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
+                        notifyClients);
+            }
+        } finally {
+            mStackSupervisor.getKeyguardController().endActivityVisibilityUpdate();
+            mInEnsureActivitiesVisible = false;
+        }
+    }
+
+    boolean switchUser(int userId, UserState uss) {
+        final int focusStackId = getTopDisplayFocusedStack().getStackId();
+        // We dismiss the docked stack whenever we switch users.
+        final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenPrimaryStack();
+        if (dockedStack != null) {
+            mStackSupervisor.moveTasksToFullscreenStackLocked(
+                    dockedStack, dockedStack.isFocusedStackOnDisplay());
+        }
+        // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
+        // also cause all tasks to be moved to the fullscreen stack at a position that is
+        // appropriate.
+        removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
+
+        mUserStackInFront.put(mCurrentUser, focusStackId);
+        final int restoreStackId =
+                mUserStackInFront.get(userId, getDefaultDisplay().getHomeStack().mStackId);
+        mCurrentUser = userId;
+
+        mStackSupervisor.mStartingUsers.add(uss);
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                stack.switchUser(userId);
+                Task task = stack.getTopMostTask();
+                if (task != null) {
+                    stack.positionChildAtTop(task);
+                }
+            }
+        }
+
+        ActivityStack stack = getStack(restoreStackId);
+        if (stack == null) {
+            stack = getDefaultDisplay().getHomeStack();
+        }
+        final boolean homeInFront = stack.isActivityTypeHome();
+        if (stack.isOnHomeDisplay()) {
+            stack.moveToFront("switchUserOnHomeDisplay");
+        } else {
+            // Stack was moved to another display while user was swapped out.
+            resumeHomeActivity(null, "switchUserOnOtherDisplay", DEFAULT_DISPLAY);
+        }
+        return homeInFront;
+    }
+
+    void removeUser(int userId) {
+        mUserStackInFront.delete(userId);
+    }
+
+    /**
+     * Update the last used stack id for non-current user (current user's last
+     * used stack is the focused stack)
+     */
+    void updateUserStack(int userId, ActivityStack stack) {
+        if (userId != mCurrentUser) {
+            mUserStackInFront.put(userId, stack != null ? stack.getStackId()
+                    : getDefaultDisplay().getHomeStack().mStackId);
+        }
+    }
+
+    /**
+     * Move stack with all its existing content to specified display.
+     * @param stackId Id of stack to move.
+     * @param displayId Id of display to move stack to.
+     * @param onTop Indicates whether container should be place on top or on bottom.
+     */
+    void moveStackToDisplay(int stackId, int displayId, boolean onTop) {
+        final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
+        if (displayContent == null) {
+            throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId="
+                    + displayId);
+        }
+        final ActivityStack stack = getStack(stackId);
+        if (stack == null) {
+            throw new IllegalArgumentException("moveStackToDisplay: Unknown stackId="
+                    + stackId);
+        }
+
+        final DisplayContent currentDisplay = stack.getDisplay();
+        if (currentDisplay == null) {
+            throw new IllegalStateException("moveStackToDisplay: Stack with stack=" + stack
+                    + " is not attached to any display.");
+        }
+
+        if (currentDisplay.mDisplayId == displayId) {
+            throw new IllegalArgumentException("Trying to move stack=" + stack
+                    + " to its current displayId=" + displayId);
+        }
+
+        if (displayContent.isSingleTaskInstance() && displayContent.getStackCount() > 0) {
+            // We don't allow moving stacks to single instance display that already has a child.
+            Slog.e(TAG, "Can not move stack=" + stack
+                    + " to single task instance display=" + displayContent);
+            return;
+        }
+
+        stack.reparent(displayContent.mDisplayContent, onTop);
+        // TODO(multi-display): resize stacks properly if moved from split-screen.
+    }
+
+    boolean moveTopStackActivityToPinnedStack(int stackId) {
+        final ActivityStack stack = getStack(stackId);
+        if (stack == null) {
+            throw new IllegalArgumentException(
+                    "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId);
+        }
+
+        final ActivityRecord r = stack.topRunningActivity();
+        if (r == null) {
+            Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity"
+                    + " in stack=" + stack);
+            return false;
+        }
+
+        if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
+            Slog.w(TAG, "moveTopStackActivityToPinnedStack: Picture-In-Picture not supported for "
+                    + " r=" + r);
+            return false;
+        }
+
+        moveActivityToPinnedStack(r, null /* sourceBounds */, 0f /* aspectRatio */,
+                "moveTopActivityToPinnedStack");
+        return true;
+    }
+
+    void moveActivityToPinnedStack(ActivityRecord r, Rect sourceHintBounds, float aspectRatio,
+            String reason) {
+        mService.deferWindowLayout();
+
+        final DisplayContent display = r.getActivityStack().getDisplay();
+
+        try {
+            final Task task = r.getTask();
+
+            final ActivityStack pinnedStack = display.getPinnedStack();
+            // This will change the pinned stack's windowing mode to its original mode, ensuring
+            // we only have one stack that is in pinned mode.
+            if (pinnedStack != null) {
+                pinnedStack.dismissPip();
+            }
+
+            final boolean singleActivity = task.getChildCount() == 1;
+
+            final ActivityStack stack;
+            if (singleActivity) {
+                stack = r.getActivityStack();
+            } else {
+                // In the case of multiple activities, we will create a new stack for it and then
+                // move the PIP activity into the stack.
+                // We will then perform a windowing mode change for both scenarios.
+                stack = display.createStack(
+                        r.getActivityStack().getRequestedOverrideWindowingMode(),
+                        r.getActivityType(), ON_TOP);
+                // There are multiple activities in the task and moving the top activity should
+                // reveal/leave the other activities in their original task.
+
+                // Currently, we don't support reparenting activities across tasks in two different
+                // stacks, so instead, just create a new task in the same stack, reparent the
+                // activity into that task, and then reparent the whole task to the new stack. This
+                // ensures that all the necessary work to migrate states in the old and new stacks
+                // is also done.
+                final Task newTask = task.getStack().createTask(
+                        mStackSupervisor.getNextTaskIdForUserLocked(r.mUserId), r.info,
+                        r.intent, null, null, true);
+                r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
+
+                // Defer resume until below, and do not schedule PiP changes until we animate below
+                newTask.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
+                        DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
+            }
+
+            stack.setWindowingMode(WINDOWING_MODE_PINNED);
+
+            // Reset the state that indicates it can enter PiP while pausing after we've moved it
+            // to the pinned stack
+            r.supportsEnterPipOnTaskSwitch = false;
+        } finally {
+            mService.continueWindowLayout();
+        }
+
+        // Notify the pinned stack controller to prepare the PiP animation, expect callback
+        // delivered from SystemUI to WM to start the animation.
+        final PinnedStackController pinnedStackController =
+                display.mDisplayContent.getPinnedStackController();
+        pinnedStackController.prepareAnimation(sourceHintBounds, aspectRatio,
+                null /* stackBounds */);
+
+        // TODO: revisit the following statement after the animation is moved from WM to SysUI.
+        // Update the visibility of all activities after the they have been reparented to the new
+        // stack.  This MUST run after the animation above is scheduled to ensure that the windows
+        // drawn signal is scheduled after the bounds animation start call on the bounds animator
+        // thread.
+        ensureActivitiesVisible(null, 0, false /* preserveWindows */);
+        resumeFocusedStacksTopActivities();
+
+        mService.getTaskChangeNotificationController().notifyActivityPinned(r);
+    }
+
+    void executeAppTransitionForAllDisplay() {
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            display.mDisplayContent.executeAppTransition();
+        }
+    }
+
+    void setDockedStackMinimized(boolean minimized) {
+        // Get currently focused stack before setting mIsDockMinimized. We do this because if
+        // split-screen is active, primary stack will not be focusable (see #isFocusable) while
+        // still occluding other stacks. This will cause getTopDisplayFocusedStack() to return null.
+        final ActivityStack current = getTopDisplayFocusedStack();
+        mIsDockMinimized = minimized;
+        if (mIsDockMinimized) {
+            if (current.inSplitScreenPrimaryWindowingMode()) {
+                // The primary split-screen stack can't be focused while it is minimize, so move
+                // focus to something else.
+                current.adjustFocusToNextFocusableStack("setDockedStackMinimized");
+            }
+        }
+    }
+
+    ActivityRecord findTask(ActivityRecord r, int preferredDisplayId) {
+        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
+        mTmpFindTaskResult.clear();
+
+        // Looking up task on preferred display first
+        final DisplayContent preferredDisplay = getDisplayContent(preferredDisplayId);
+        if (preferredDisplay != null) {
+            preferredDisplay.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult);
+            if (mTmpFindTaskResult.mIdealMatch) {
+                return mTmpFindTaskResult.mRecord;
+            }
+        }
+
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            if (display.mDisplayId == preferredDisplayId) {
+                continue;
+            }
+
+            display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult);
+            if (mTmpFindTaskResult.mIdealMatch) {
+                return mTmpFindTaskResult.mRecord;
+            }
+        }
+
+        if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found");
+        return mTmpFindTaskResult.mRecord;
+    }
+
+    /**
+     * Finish the topmost activities in all stacks that belong to the crashed app.
+     * @param app The app that crashed.
+     * @param reason Reason to perform this action.
+     * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
+     */
+    int finishTopCrashedActivities(WindowProcessController app, String reason) {
+        Task finishedTask = null;
+        ActivityStack focusedStack = getTopDisplayFocusedStack();
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            // It is possible that request to finish activity might also remove its task and stack,
+            // so we need to be careful with indexes in the loop and check child count every time.
+            for (int stackNdx = 0; stackNdx < display.getStackCount(); ++stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                final Task t = stack.finishTopCrashedActivityLocked(app, reason);
+                if (stack == focusedStack || finishedTask == null) {
+                    finishedTask = t;
+                }
+            }
+        }
+        return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID;
+    }
+
+    boolean resumeFocusedStacksTopActivities() {
+        return resumeFocusedStacksTopActivities(null, null, null);
+    }
+
+    boolean resumeFocusedStacksTopActivities(
+            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
+
+        if (!mStackSupervisor.readyToResume()) {
+            return false;
+        }
+
+        boolean result = false;
+        if (targetStack != null && (targetStack.isTopStackOnDisplay()
+                || getTopDisplayFocusedStack() == targetStack)) {
+            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
+        }
+
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            boolean resumedOnDisplay = false;
+            final DisplayContent display = getChildAt(displayNdx);
+            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                final ActivityRecord topRunningActivity = stack.topRunningActivity();
+                if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
+                    continue;
+                }
+                if (stack == targetStack) {
+                    // Simply update the result for targetStack because the targetStack had
+                    // already resumed in above. We don't want to resume it again, especially in
+                    // some cases, it would cause a second launch failure if app process was dead.
+                    resumedOnDisplay |= result;
+                    continue;
+                }
+                if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
+                    // Kick off any lingering app transitions form the MoveTaskToFront operation,
+                    // but only consider the top task and stack on that display.
+                    stack.executeAppTransition(targetOptions);
+                } else {
+                    resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
+                }
+            }
+            if (!resumedOnDisplay) {
+                // In cases when there are no valid activities (e.g. device just booted or launcher
+                // crashed) it's possible that nothing was resumed on a display. Requesting resume
+                // of top activity in focused stack explicitly will make sure that at least home
+                // activity is started and resumed, and no recursion occurs.
+                final ActivityStack focusedStack = display.getFocusedStack();
+                if (focusedStack != null) {
+                    result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
+                } else if (targetStack == null && display.getStackCount() == 0) {
+                    result |= resumeHomeActivity(null /* prev */, "empty-display",
+                            display.mDisplayId);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    void applySleepTokens(boolean applyToStacks) {
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            // Set the sleeping state of the display.
+            final DisplayContent display = getChildAt(displayNdx);
+            final boolean displayShouldSleep = display.shouldSleep();
+            if (displayShouldSleep == display.isSleeping()) {
+                continue;
+            }
+            display.setIsSleeping(displayShouldSleep);
+
+            if (!applyToStacks) {
+                continue;
+            }
+
+            // Set the sleeping state of the stacks on the display.
+            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                if (displayShouldSleep) {
+                    stack.goToSleepIfPossible(false /* shuttingDown */);
+                } else {
+                    // When the display which can only contain one task turns on, start a special
+                    // transition. {@link AppTransitionController#handleAppTransitionReady} later
+                    // picks up the transition, and schedules
+                    // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is
+                    // triggered after contents are drawn on the display.
+                    if (display.isSingleTaskInstance()) {
+                        display.mDisplayContent.prepareAppTransition(
+                                TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false);
+                    }
+                    stack.awakeFromSleepingLocked();
+                    if (stack.isFocusedStackOnDisplay()
+                            && !mStackSupervisor.getKeyguardController()
+                            .isKeyguardOrAodShowing(display.mDisplayId)) {
+                        // If the keyguard is unlocked - resume immediately.
+                        // It is possible that the display will not be awake at the time we
+                        // process the keyguard going away, which can happen before the sleep token
+                        // is released. As a result, it is important we resume the activity here.
+                        resumeFocusedStacksTopActivities();
+                    }
+                }
+            }
+
+            if (displayShouldSleep || mStackSupervisor.mGoingToSleepActivities.isEmpty()) {
+                continue;
+            }
+            // The display is awake now, so clean up the going to sleep list.
+            for (Iterator<ActivityRecord> it =
+                    mStackSupervisor.mGoingToSleepActivities.iterator(); it.hasNext(); ) {
+                final ActivityRecord r = it.next();
+                if (r.getDisplayId() == display.mDisplayId) {
+                    it.remove();
+                }
+            }
+        }
+    }
+
+    protected ActivityStack getStack(int stackId) {
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final ActivityStack stack = getChildAt(i).getStack(stackId);
+            if (stack != null) {
+                return stack;
+            }
+        }
+        return null;
+    }
+
+    /** @see DisplayContent#getStack(int, int) */
+    ActivityStack getStack(int windowingMode, int activityType) {
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final ActivityStack stack = getChildAt(i).getStack(windowingMode, activityType);
+            if (stack != null) {
+                return stack;
+            }
+        }
+        return null;
+    }
+
+    private ActivityStack getStack(int windowingMode, int activityType,
+            int displayId) {
+        DisplayContent display = getDisplayContent(displayId);
+        if (display == null) {
+            return null;
+        }
+        return display.getStack(windowingMode, activityType);
+    }
+
+    private ActivityManager.StackInfo getStackInfo(ActivityStack stack) {
+        final int displayId = stack.mDisplayId;
+        final DisplayContent display = getDisplayContent(displayId);
+        ActivityManager.StackInfo info = new ActivityManager.StackInfo();
+        stack.getBounds(info.bounds);
+        info.displayId = displayId;
+        info.stackId = stack.mStackId;
+        info.stackToken = stack.mRemoteToken;
+        info.userId = stack.mCurrentUser;
+        info.visible = stack.shouldBeVisible(null);
+        // A stack might be not attached to a display.
+        info.position = display != null ? display.getIndexOf(stack) : 0;
+        info.configuration.setTo(stack.getConfiguration());
+
+        final int numTasks = stack.getChildCount();
+        info.taskIds = new int[numTasks];
+        info.taskNames = new String[numTasks];
+        info.taskBounds = new Rect[numTasks];
+        info.taskUserIds = new int[numTasks];
+        final int[] currenIndex = {0};
+
+        final PooledConsumer c = PooledLambda.obtainConsumer(
+                RootWindowContainer::processTaskForStackInfo, PooledLambda.__(Task.class), info,
+                currenIndex);
+        stack.forAllTasks(c, false);
+        c.recycle();
+
+        final ActivityRecord top = stack.topRunningActivity();
+        info.topActivity = top != null ? top.intent.getComponent() : null;
+        return info;
+    }
+
+    private static void processTaskForStackInfo(
+            Task task, ActivityManager.StackInfo info, int[] currentIndex) {
+        int i = currentIndex[0];
+        info.taskIds[i] = task.mTaskId;
+        info.taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
+                : task.realActivity != null ? task.realActivity.flattenToString()
+                        : task.getTopNonFinishingActivity() != null
+                                ? task.getTopNonFinishingActivity().packageName : "unknown";
+        info.taskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId);
+        info.taskUserIds[i] = task.mUserId;
+        currentIndex[0] = ++i;
+    }
+
+    ActivityManager.StackInfo getStackInfo(int stackId) {
+        ActivityStack stack = getStack(stackId);
+        if (stack != null) {
+            return getStackInfo(stack);
+        }
+        return null;
+    }
+
+    ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
+        final ActivityStack stack = getStack(windowingMode, activityType);
+        return (stack != null) ? getStackInfo(stack) : null;
+    }
+
+    ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType, int displayId) {
+        final ActivityStack stack = getStack(windowingMode, activityType, displayId);
+        return (stack != null) ? getStackInfo(stack) : null;
+    }
+
+    /** If displayId == INVALID_DISPLAY, this will get stack infos on all displays */
+    ArrayList<ActivityManager.StackInfo> getAllStackInfos(int displayId) {
+        ArrayList<ActivityManager.StackInfo> list = new ArrayList<>();
+        if (displayId == INVALID_DISPLAY) {
+            for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
+                final DisplayContent display = getChildAt(displayNdx);
+                for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                    final ActivityStack stack = display.getStackAt(stackNdx);
+                    list.add(getStackInfo(stack));
+                }
+            }
+            return list;
+        }
+        final DisplayContent display = getDisplayContent(displayId);
+        if (display == null) {
+            return list;
+        }
+        for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = display.getStackAt(stackNdx);
+            list.add(getStackInfo(stack));
+        }
+        return list;
+    }
+
+    void deferUpdateBounds(int activityType) {
+        final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
+        if (stack != null) {
+            stack.deferUpdateBounds();
+        }
+    }
+
+    void continueUpdateBounds(int activityType) {
+        final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
+        if (stack != null) {
+            stack.continueUpdateBounds();
+        }
+    }
+
+    @Override
+    public void onDisplayAdded(int displayId) {
+        if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
+        synchronized (mService.mGlobalLock) {
+            final DisplayContent display = getDisplayContentOrCreate(displayId);
+            if (display == null) {
+                return;
+            }
+            // Do not start home before booting, or it may accidentally finish booting before it
+            // starts. Instead, we expect home activities to be launched when the system is ready
+            // (ActivityManagerService#systemReady).
+            if (mService.isBooted() || mService.isBooting()) {
+                startSystemDecorations(display.mDisplayContent);
+            }
+        }
+    }
+
+    private void startSystemDecorations(final DisplayContent displayContent) {
+        startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
+        displayContent.getDisplayPolicy().notifyDisplayReady();
+    }
+
+    @Override
+    public void onDisplayRemoved(int displayId) {
+        if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
+        if (displayId == DEFAULT_DISPLAY) {
+            throw new IllegalArgumentException("Can't remove the primary display.");
+        }
+
+        synchronized (mService.mGlobalLock) {
+            final DisplayContent displayContent = getDisplayContent(displayId);
+            if (displayContent == null) {
+                return;
+            }
+
+            displayContent.remove();
+        }
+    }
+
+    @Override
+    public void onDisplayChanged(int displayId) {
+        if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
+        synchronized (mService.mGlobalLock) {
+            final DisplayContent displayContent = getDisplayContent(displayId);
+            if (displayContent != null) {
+                displayContent.onDisplayChanged();
+            }
+        }
+    }
+
+    /** Update lists of UIDs that are present on displays and have access to them. */
+    void updateUIDsPresentOnDisplay() {
+        mDisplayAccessUIDs.clear();
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent displayContent = getChildAt(displayNdx);
+            // Only bother calculating the whitelist for private displays
+            if (displayContent.isPrivate()) {
+                mDisplayAccessUIDs.append(
+                        displayContent.mDisplayId, displayContent.getPresentUIDs());
+            }
+        }
+        // Store updated lists in DisplayManager. Callers from outside of AM should get them there.
+        mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
+    }
+
+    ActivityStack findStackBehind(ActivityStack stack) {
+        final DisplayContent display = getDisplayContent(stack.mDisplayId);
+        if (display != null) {
+            for (int i = display.getStackCount() - 1; i >= 0; i--) {
+                if (display.getStackAt(i) == stack && i > 0) {
+                    return display.getStackAt(i - 1);
+                }
+            }
+        }
+        throw new IllegalStateException("Failed to find a stack behind stack=" + stack
+                + " in=" + display);
+    }
+
+    @Override
+    void positionChildAt(int position, DisplayContent child, boolean includingParents) {
+        super.positionChildAt(position, child, includingParents);
+        mStackSupervisor.updateTopResumedActivityIfNeeded();
+    }
+
+    Configuration getDisplayOverrideConfiguration(int displayId) {
+        final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
+        if (displayContent == null) {
+            throw new IllegalArgumentException("No display found with id: " + displayId);
+        }
+
+        return displayContent.getRequestedOverrideConfiguration();
+    }
+
+    void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) {
+        final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
+        if (displayContent == null) {
+            throw new IllegalArgumentException("No display found with id: " + displayId);
+        }
+
+        displayContent.onRequestedOverrideConfigurationChanged(overrideConfiguration);
+    }
+
+    void prepareForShutdown() {
+        for (int i = 0; i < getChildCount(); i++) {
+            createSleepToken("shutdown", getChildAt(i).mDisplayId);
+        }
+    }
+
+    ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) {
+        final DisplayContent display = getDisplayContent(displayId);
+        if (display == null) {
+            throw new IllegalArgumentException("Invalid display: " + displayId);
+        }
+
+        final SleepTokenImpl token = new SleepTokenImpl(tag, displayId);
+        mSleepTokens.add(token);
+        display.mAllSleepTokens.add(token);
+        return token;
+    }
+
+    private void removeSleepToken(SleepTokenImpl token) {
+        mSleepTokens.remove(token);
+
+        final DisplayContent display = getDisplayContent(token.mDisplayId);
+        if (display != null) {
+            display.mAllSleepTokens.remove(token);
+            if (display.mAllSleepTokens.isEmpty()) {
+                mService.updateSleepIfNeededLocked();
+            }
+        }
+    }
+
+    void addStartingWindowsForVisibleActivities() {
+        forAllActivities((r) -> {
+            if (r.mVisibleRequested) {
+                r.showStartingWindow(null /* prev */, false /* newTask */, true /*taskSwitch*/);
+            }
+        });
+    }
+
+    void invalidateTaskLayers() {
+        mTaskLayersChanged = true;
+    }
+
+    void rankTaskLayersIfNeeded() {
+        if (!mTaskLayersChanged) {
+            return;
+        }
+        mTaskLayersChanged = false;
+        mTmpTaskLayerRank = 0;
+        final PooledConsumer c = PooledLambda.obtainConsumer(
+                RootWindowContainer::rankTaskLayerForActivity, this,
+                PooledLambda.__(ActivityRecord.class));
+        forAllActivities(c);
+        c.recycle();
+    }
+
+    private void rankTaskLayerForActivity(ActivityRecord r) {
+        if (r.canBeTopRunning() && r.mVisibleRequested) {
+            r.getTask().mLayerRank = ++mTmpTaskLayerRank;
+        } else {
+            r.getTask().mLayerRank = -1;
+        }
+    }
+
+    void clearOtherAppTimeTrackers(AppTimeTracker except) {
+        final PooledConsumer c = PooledLambda.obtainConsumer(
+                RootWindowContainer::clearOtherAppTimeTrackers,
+                PooledLambda.__(ActivityRecord.class), except);
+        forAllActivities(c);
+        c.recycle();
+    }
+
+    private static void clearOtherAppTimeTrackers(ActivityRecord r, AppTimeTracker except) {
+        if (r.appTimeTracker != except) {
+            r.appTimeTracker = null;
+        }
+    }
+
+    void scheduleDestroyAllActivities(String reason) {
+        mDestroyAllActivitiesReason = reason;
+        mService.mH.post(mDestroyAllActivitiesRunnable);
+    }
+
+    private void destroyActivity(ActivityRecord r) {
+        if (r.finishing || !r.isDestroyable()) return;
+
+        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.getState()
+                + " resumed=" + r.getStack().mResumedActivity + " pausing="
+                + r.getStack().mPausingActivity + " for reason " + mDestroyAllActivitiesReason);
+
+        r.destroyImmediately(true /* removeFromTask */, mDestroyAllActivitiesReason);
+    }
+
+    // Tries to put all activity stacks to sleep. Returns true if all stacks were
+    // successfully put to sleep.
+    boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) {
+        boolean allSleep = true;
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                // Stacks and activities could be removed while putting activities to sleep if
+                // the app process was gone. This prevents us getting exception by accessing an
+                // invalid stack index.
+                if (stackNdx >= display.getStackCount()) {
+                    continue;
+                }
+
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                if (allowDelay) {
+                    allSleep &= stack.goToSleepIfPossible(shuttingDown);
+                } else {
+                    stack.goToSleep();
+                }
+            }
+        }
+        return allSleep;
+    }
+
+    void handleAppCrash(WindowProcessController app) {
+        final PooledConsumer c = PooledLambda.obtainConsumer(
+                RootWindowContainer::handleAppCrash, PooledLambda.__(ActivityRecord.class), app);
+        forAllActivities(c);
+        c.recycle();
+    }
+
+    private static void handleAppCrash(ActivityRecord r, WindowProcessController app) {
+        if (r.app != app) return;
+        Slog.w(TAG, "  Force finishing activity "
+                + r.intent.getComponent().flattenToShortString());
+        r.app = null;
+        r.getDisplay().mDisplayContent.prepareAppTransition(
+                TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
+        r.destroyIfPossible("handleAppCrashed");
+    }
+
+    ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) {
+        ComponentName cls = intent.getComponent();
+        if (info.targetActivity != null) {
+            cls = new ComponentName(info.packageName, info.targetActivity);
+        }
+        final int userId = UserHandle.getUserId(info.applicationInfo.uid);
+
+        final PooledPredicate p = PooledLambda.obtainPredicate(
+                RootWindowContainer::matchesActivity, PooledLambda.__(ActivityRecord.class),
+                userId, compareIntentFilters, intent, cls);
+        final ActivityRecord r = getActivity(p);
+        p.recycle();
+        return r;
+    }
+
+    private static boolean matchesActivity(ActivityRecord r, int userId,
+            boolean compareIntentFilters, Intent intent, ComponentName cls) {
+        if (!r.canBeTopRunning() || r.mUserId != userId)  return false;
+
+        if (compareIntentFilters) {
+            if (r.intent.filterEquals(intent)) {
+                return true;
+            }
+        } else {
+            if (r.intent.getComponent().equals(cls)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean hasAwakeDisplay() {
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            if (!display.shouldSleep()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    ActivityStack getLaunchStack(@Nullable ActivityRecord r,
+            @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) {
+        return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
+                -1 /* no realCallingPid */, -1 /* no realCallingUid */);
+    }
+
+    /**
+     * Returns the right stack to use for launching factoring in all the input parameters.
+     *
+     * @param r The activity we are trying to launch. Can be null.
+     * @param options The activity options used to the launch. Can be null.
+     * @param candidateTask The possible task the activity might be launched in. Can be null.
+     * @param launchParams The resolved launch params to use.
+     * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
+     * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
+     *
+     * @return The stack to use for the launch or INVALID_STACK_ID.
+     */
+    ActivityStack getLaunchStack(@Nullable ActivityRecord r,
+            @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop,
+            @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
+            int realCallingUid) {
+        int taskId = INVALID_TASK_ID;
+        int displayId = INVALID_DISPLAY;
+        //Rect bounds = null;
+
+        // We give preference to the launch preference in activity options.
+        if (options != null) {
+            taskId = options.getLaunchTaskId();
+            displayId = options.getLaunchDisplayId();
+        }
+
+        // First preference for stack goes to the task Id set in the activity options. Use the stack
+        // associated with that if possible.
+        if (taskId != INVALID_TASK_ID) {
+            // Temporarily set the task id to invalid in case in re-entry.
+            options.setLaunchTaskId(INVALID_TASK_ID);
+            final Task task = anyTaskForId(taskId,
+                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
+            options.setLaunchTaskId(taskId);
+            if (task != null) {
+                return task.getStack();
+            }
+        }
+
+        final int activityType = resolveActivityType(r, options, candidateTask);
+        ActivityStack stack;
+
+        // Next preference for stack goes to the display Id set the candidate display.
+        if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
+            displayId = launchParams.mPreferredDisplayId;
+        }
+        final boolean canLaunchOnDisplayFromStartRequest =
+                realCallingPid != 0 && realCallingUid > 0 && r != null
+                        && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid,
+                        realCallingUid, r.info);
+        // Checking if the activity's launch caller, or the realCallerId of the activity from
+        // start request (i.e. entity that invokes PendingIntent) is allowed to launch on the
+        // display.
+        if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId)
+                || canLaunchOnDisplayFromStartRequest)) {
+            if (r != null) {
+                stack = getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
+                        launchParams);
+                if (stack != null) {
+                    return stack;
+                }
+            }
+            final DisplayContent display = getDisplayContentOrCreate(displayId);
+            if (display != null) {
+                stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
+                if (stack != null) {
+                    return stack;
+                }
+            }
+        }
+
+        // Give preference to the stack and display of the input task and activity if they match the
+        // mode we want to launch into.
+        stack = null;
+        DisplayContent display = null;
+        if (candidateTask != null) {
+            stack = candidateTask.getStack();
+        }
+        if (stack == null && r != null) {
+            stack = r.getActivityStack();
+        }
+        if (stack != null) {
+            display = stack.getDisplay();
+            if (display != null && canLaunchOnDisplay(r, display.mDisplayId)) {
+                int windowingMode = launchParams != null ? launchParams.mWindowingMode
+                        : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+                if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
+                    windowingMode = display.resolveWindowingMode(r, options, candidateTask,
+                            activityType);
+                }
+                if (stack.isCompatible(windowingMode, activityType)) {
+                    return stack;
+                }
+                if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
+                        && display.getSplitScreenPrimaryStack() == stack
+                        && candidateTask == stack.getTopMostTask()) {
+                    // This is a special case when we try to launch an activity that is currently on
+                    // top of split-screen primary stack, but is targeting split-screen secondary.
+                    // In this case we don't want to move it to another stack.
+                    // TODO(b/78788972): Remove after differentiating between preferred and required
+                    // launch options.
+                    return stack;
+                }
+            }
+        }
+
+        if (display == null || !canLaunchOnDisplay(r, display.mDisplayId)) {
+            display = getDefaultDisplay();
+        }
+
+        return display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
+    }
+
+    /** @return true if activity record is null or can be launched on provided display. */
+    private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) {
+        if (r == null) {
+            return true;
+        }
+        return r.canBeLaunchedOnDisplay(displayId);
+    }
+
+    /**
+     * Get a topmost stack on the display, that is a valid launch stack for specified activity.
+     * If there is no such stack, new dynamic stack can be created.
+     * @param displayId Target display.
+     * @param r Activity that should be launched there.
+     * @param candidateTask The possible task the activity might be put in.
+     * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
+     */
+    private ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
+            @Nullable Task candidateTask, @Nullable ActivityOptions options,
+            @Nullable LaunchParamsController.LaunchParams launchParams) {
+        final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
+        if (displayContent == null) {
+            throw new IllegalArgumentException(
+                    "Display with displayId=" + displayId + " not found.");
+        }
+
+        if (!r.canBeLaunchedOnDisplay(displayId)) {
+            return null;
+        }
+
+        // If {@code r} is already in target display and its task is the same as the candidate task,
+        // the intention should be getting a launch stack for the reusable activity, so we can use
+        // the existing stack.
+        if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) {
+            final int attachedDisplayId = r.getDisplayId();
+            if (attachedDisplayId == INVALID_DISPLAY || attachedDisplayId == displayId) {
+                return candidateTask.getStack();
+            }
+        }
+
+        int windowingMode;
+        if (launchParams != null) {
+            // When launch params is not null, we always defer to its windowing mode. Sometimes
+            // it could be unspecified, which indicates it should inherit windowing mode from
+            // display.
+            windowingMode = launchParams.mWindowingMode;
+        } else {
+            windowingMode = options != null ? options.getLaunchWindowingMode()
+                    : r.getWindowingMode();
+        }
+        windowingMode = displayContent.validateWindowingMode(windowingMode, r, candidateTask,
+                r.getActivityType());
+
+        // Return the topmost valid stack on the display.
+        for (int i = displayContent.getStackCount() - 1; i >= 0; --i) {
+            final ActivityStack stack = displayContent.getStackAt(i);
+            if (isValidLaunchStack(stack, r, windowingMode)) {
+                return stack;
+            }
+        }
+
+        // If there is no valid stack on the external display - check if new dynamic stack will do.
+        if (displayId != DEFAULT_DISPLAY) {
+            final int activityType =
+                    options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
+                            ? options.getLaunchActivityType() : r.getActivityType();
+            return displayContent.createStack(windowingMode, activityType, true /*onTop*/);
+        }
+
+        return null;
+    }
+
+    ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
+            @Nullable ActivityOptions options,
+            @Nullable LaunchParamsController.LaunchParams launchParams) {
+        return getValidLaunchStackOnDisplay(displayId, r, null /* candidateTask */, options,
+                launchParams);
+    }
+
+    // TODO: Can probably be consolidated into getLaunchStack()...
+    private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) {
+        switch (stack.getActivityType()) {
+            case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome();
+            case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
+            case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
+        }
+        // There is a 1-to-1 relationship between stack and task when not in
+        // primary split-windowing mode.
+        if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
+                && r.supportsSplitScreenWindowingMode()
+                && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
+                || windowingMode == WINDOWING_MODE_UNDEFINED)) {
+            return true;
+        }
+        return false;
+    }
+
+    int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
+            @Nullable Task task) {
+        // Preference is given to the activity type for the activity then the task since the type
+        // once set shouldn't change.
+        int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
+        if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) {
+            activityType = task.getActivityType();
+        }
+        if (activityType != ACTIVITY_TYPE_UNDEFINED) {
+            return activityType;
+        }
+        if (options != null) {
+            activityType = options.getLaunchActivityType();
+        }
+        return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD;
+    }
+
+    /**
+     * Get next focusable stack in the system. This will search through the stack on the same
+     * display as the current focused stack, looking for a focusable and visible stack, different
+     * from the target stack. If no valid candidates will be found, it will then go through all
+     * displays and stacks in last-focused order.
+     *
+     * @param currentFocus The stack that previously had focus.
+     * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
+     *                     candidate.
+     * @return Next focusable {@link ActivityStack}, {@code null} if not found.
+     */
+    ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus,
+            boolean ignoreCurrent) {
+        // First look for next focusable stack on the same display
+        DisplayContent preferredDisplay = currentFocus.getDisplay();
+        if (preferredDisplay == null) {
+            // Stack is currently detached because it is being removed. Use the previous display it
+            // was on.
+            preferredDisplay = getDisplayContent(currentFocus.mPrevDisplayId);
+        }
+        final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack(
+                currentFocus, ignoreCurrent);
+        if (preferredFocusableStack != null) {
+            return preferredFocusableStack;
+        }
+        if (preferredDisplay.supportsSystemDecorations()) {
+            // Stop looking for focusable stack on other displays because the preferred display
+            // supports system decorations. Home activity would be launched on the same display if
+            // no focusable stack found.
+            return null;
+        }
+
+        // Now look through all displays
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final DisplayContent display = getChildAt(i);
+            if (display == preferredDisplay) {
+                // We've already checked this one
+                continue;
+            }
+            final ActivityStack nextFocusableStack = display.getNextFocusableStack(currentFocus,
+                    ignoreCurrent);
+            if (nextFocusableStack != null) {
+                return nextFocusableStack;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Get next valid stack for launching provided activity in the system. This will search across
+     * displays and stacks in last-focused order for a focusable and visible stack, except those
+     * that are on a currently focused display.
+     *
+     * @param r The activity that is being launched.
+     * @param currentFocus The display that previously had focus and thus needs to be ignored when
+     *                     searching for the next candidate.
+     * @return Next valid {@link ActivityStack}, null if not found.
+     */
+    ActivityStack getNextValidLaunchStack(@NonNull ActivityRecord r, int currentFocus) {
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final DisplayContent display = getChildAt(i);
+            if (display.mDisplayId == currentFocus) {
+                continue;
+            }
+            final ActivityStack stack = getValidLaunchStackOnDisplay(display.mDisplayId, r,
+                    null /* options */, null /* launchParams */);
+            if (stack != null) {
+                return stack;
+            }
+        }
+        return null;
+    }
+
+    boolean handleAppDied(WindowProcessController app) {
+        boolean hasVisibleActivities = false;
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                hasVisibleActivities |= stack.handleAppDied(app);
+            }
+        }
+        return hasVisibleActivities;
+    }
+
+    void closeSystemDialogs() {
+        forAllActivities((r) -> {
+            if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
+                r.finishIfPossible("close-sys", true /* oomAdj */);
+            }
+        });
+    }
+
+    FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper =
+            new FinishDisabledPackageActivitiesHelper();
+    class FinishDisabledPackageActivitiesHelper {
+        private boolean mDidSomething;
+        private String mPackageName;
+        private Set<String> mFilterByClasses;
+        private boolean mDoit;
+        private boolean mEvenPersistent;
+        private int mUserId;
+        private Task mLastTask;
+        private ComponentName mHomeActivity;
+
+        private void reset(String packageName, Set<String> filterByClasses,
+                boolean doit, boolean evenPersistent, int userId) {
+            mDidSomething = false;
+            mPackageName = packageName;
+            mFilterByClasses = filterByClasses;
+            mDoit = doit;
+            mEvenPersistent = evenPersistent;
+            mUserId = userId;
+            mLastTask = null;
+            mHomeActivity = null;
+        }
+
+        boolean process(String packageName, Set<String> filterByClasses,
+                boolean doit, boolean evenPersistent, int userId) {
+            reset(packageName, filterByClasses, doit, evenPersistent, userId);
+
+            final PooledFunction f = PooledLambda.obtainFunction(
+                    FinishDisabledPackageActivitiesHelper::processActivity, this,
+                    PooledLambda.__(ActivityRecord.class));
+            forAllActivities(f);
+            f.recycle();
+            return mDidSomething;
+        }
+
+        private boolean processActivity(ActivityRecord r) {
+            final boolean sameComponent =
+                    (r.packageName.equals(mPackageName) && (mFilterByClasses == null
+                            || mFilterByClasses.contains(r.mActivityComponent.getClassName())))
+                            || (mPackageName == null && r.mUserId == mUserId);
+            if ((mUserId == UserHandle.USER_ALL || r.mUserId == mUserId)
+                    && (sameComponent || r.getTask() == mLastTask)
+                    && (r.app == null || mEvenPersistent || !r.app.isPersistent())) {
+                if (!mDoit) {
+                    if (r.finishing) {
+                        // If this activity is just finishing, then it is not
+                        // interesting as far as something to stop.
+                        return false;
+                    }
+                    return true;
+                }
+                if (r.isActivityTypeHome()) {
+                    if (mHomeActivity != null && mHomeActivity.equals(r.mActivityComponent)) {
+                        Slog.i(TAG, "Skip force-stop again " + r);
+                        return false;
+                    } else {
+                        mHomeActivity = r.mActivityComponent;
+                    }
+                }
+                mDidSomething = true;
+                Slog.i(TAG, "  Force finishing activity " + r);
+                mLastTask = r.getTask();
+                r.finishIfPossible("force-stop", true);
+            }
+
+            return false;
+        }
+    }
+
+    /** @return true if some activity was finished (or would have finished if doit were true). */
+    boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
+            boolean doit, boolean evenPersistent, int userId) {
+        return mFinishDisabledPackageActivitiesHelper.process(packageName, filterByClasses, doit,
+                evenPersistent, userId);
+    }
+
+    void updateActivityApplicationInfo(ApplicationInfo aInfo) {
+        final String packageName = aInfo.packageName;
+        final int userId = UserHandle.getUserId(aInfo.uid);
+        final PooledConsumer c = PooledLambda.obtainConsumer(
+                RootWindowContainer::updateActivityApplicationInfo,
+                PooledLambda.__(ActivityRecord.class), aInfo, userId, packageName);
+        forAllActivities(c);
+        c.recycle();
+    }
+
+    private static void updateActivityApplicationInfo(
+            ActivityRecord r, ApplicationInfo aInfo, int userId, String packageName) {
+        if (r.mUserId == userId && packageName.equals(r.packageName)) {
+            r.updateApplicationInfo(aInfo);
+        }
+    }
+
+    void finishVoiceTask(IVoiceInteractionSession session) {
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            final int numStacks = display.getStackCount();
+            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                stack.finishVoiceTask(session);
+            }
+        }
+    }
+
+    /**
+     * Removes stacks in the input windowing modes from the system if they are of activity type
+     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
+     */
+    void removeStacksInWindowingModes(int... windowingModes) {
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            getChildAt(i).removeStacksInWindowingModes(windowingModes);
+        }
+    }
+
+    void removeStacksWithActivityTypes(int... activityTypes) {
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            getChildAt(i).removeStacksWithActivityTypes(activityTypes);
+        }
+    }
+
+    ActivityRecord topRunningActivity() {
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final ActivityRecord topActivity = getChildAt(i).topRunningActivity();
+            if (topActivity != null) {
+                return topActivity;
+            }
+        }
+        return null;
+    }
+
+    boolean allResumedActivitiesIdle() {
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            // TODO(b/117135575): Check resumed activities on all visible stacks.
+            final DisplayContent display = getChildAt(displayNdx);
+            if (display.isSleeping()) {
+                // No resumed activities while display is sleeping.
+                continue;
+            }
+
+            // If the focused stack is not null or not empty, there should have some activities
+            // resuming or resumed. Make sure these activities are idle.
+            final ActivityStack stack = display.getFocusedStack();
+            if (stack == null || !stack.hasActivity()) {
+                continue;
+            }
+            final ActivityRecord resumedActivity = stack.getResumedActivity();
+            if (resumedActivity == null || !resumedActivity.idle) {
+                if (DEBUG_STATES) {
+                    Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
+                            + stack.mStackId + " " + resumedActivity + " not idle");
+                }
+                return false;
+            }
+        }
+        // Send launch end powerhint when idle
+        sendPowerHintForLaunchEndIfNeeded();
+        return true;
+    }
+
+    boolean allResumedActivitiesVisible() {
+        boolean foundResumed = false;
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                final ActivityRecord r = stack.getResumedActivity();
+                if (r != null) {
+                    if (!r.nowVisible) {
+                        return false;
+                    }
+                    foundResumed = true;
+                }
+            }
+        }
+        return foundResumed;
+    }
+
+    boolean allPausedActivitiesComplete() {
+        boolean pausing = true;
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                final ActivityRecord r = stack.mPausingActivity;
+                if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
+                    if (DEBUG_STATES) {
+                        Slog.d(TAG_STATES,
+                                "allPausedActivitiesComplete: r=" + r + " state=" + r.getState());
+                        pausing = false;
+                    } else {
+                        return false;
+                    }
+                }
+            }
+        }
+        return pausing;
+    }
+
+    /**
+     * Find all visible task stacks containing {@param userId} and intercept them with an activity
+     * to block out the contents and possibly start a credential-confirming intent.
+     *
+     * @param userId user handle for the locked managed profile.
+     */
+    void lockAllProfileTasks(@UserIdInt int userId) {
+        mService.deferWindowLayout();
+        try {
+            final PooledConsumer c = PooledLambda.obtainConsumer(
+                    RootWindowContainer::taskTopActivityIsUser, this, PooledLambda.__(Task.class),
+                    userId);
+            forAllTasks(c);
+            c.recycle();
+        } finally {
+            mService.continueWindowLayout();
+        }
+    }
+
+    /**
+     * Detects whether we should show a lock screen in front of this task for a locked user.
+     * <p>
+     * We'll do this if either of the following holds:
+     * <ul>
+     *   <li>The top activity explicitly belongs to {@param userId}.</li>
+     *   <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
+     * </ul>
+     *
+     * @return {@code true} if the top activity looks like it belongs to {@param userId}.
+     */
+    private void taskTopActivityIsUser(Task task, @UserIdInt int userId) {
+        // To handle the case that work app is in the task but just is not the top one.
+        final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
+        final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
+
+        // Check the task for a top activity belonging to userId, or returning a
+        // result to an activity belonging to userId. Example case: a document
+        // picker for personal files, opened by a work app, should still get locked.
+        if ((activityRecord != null && activityRecord.mUserId == userId)
+                || (resultTo != null && resultTo.mUserId == userId)) {
+            mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
+                    task.mTaskId, userId);
+        }
+    }
+
+    void cancelInitializingActivities() {
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                stack.cancelInitializingActivities();
+            }
+        }
+    }
+
+    Task anyTaskForId(int id) {
+        return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE);
+    }
+
+    Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode) {
+        return anyTaskForId(id, matchMode, null, !ON_TOP);
+    }
+
+    /**
+     * Returns a {@link Task} for the input id if available. {@code null} otherwise.
+     * @param id Id of the task we would like returned.
+     * @param matchMode The mode to match the given task id in.
+     * @param aOptions The activity options to use for restoration. Can be null.
+     * @param onTop If the stack for the task should be the topmost on the display.
+     */
+    Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode,
+            @Nullable ActivityOptions aOptions, boolean onTop) {
+        // If options are set, ensure that we are attempting to actually restore a task
+        if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
+            throw new IllegalArgumentException("Should not specify activity options for non-restore"
+                    + " lookup");
+        }
+
+        final PooledPredicate p = PooledLambda.obtainPredicate(
+                Task::isTaskId, PooledLambda.__(Task.class), id);
+        Task task = getTask(p);
+        p.recycle();
+
+        if (task != null) {
+            if (aOptions != null) {
+                // Resolve the stack the task should be placed in now based on options
+                // and reparent if needed.
+                final ActivityStack launchStack =
+                        getLaunchStack(null, aOptions, task, onTop);
+                if (launchStack != null && task.getStack() != launchStack) {
+                    final int reparentMode = onTop
+                            ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
+                    task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
+                            "anyTaskForId");
+                }
+            }
+            return task;
+        }
+
+        // If we are matching stack tasks only, return now
+        if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
+            return null;
+        }
+
+        // Otherwise, check the recent tasks and return if we find it there and we are not restoring
+        // the task from recents
+        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
+        task = mStackSupervisor.mRecentTasks.getTask(id);
+
+        if (task == null) {
+            if (DEBUG_RECENTS) {
+                Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
+            }
+
+            return null;
+        }
+
+        if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
+            return task;
+        }
+
+        // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
+        if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
+            if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
+                    "Couldn't restore task id=" + id + " found in recents");
+            return null;
+        }
+        if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
+        return task;
+    }
+
+    ActivityRecord isInAnyStack(IBinder token) {
+        int numDisplays = getChildCount();
+        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            final DisplayContent display = getChildAt(displayNdx);
+            for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = display.getStackAt(stackNdx);
+                final ActivityRecord r = stack.isInStackLocked(token);
+                if (r != null) {
+                    return r;
+                }
+            }
+        }
+        return null;
+    }
+
+    @VisibleForTesting
+    void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
+            @WindowConfiguration.ActivityType int ignoreActivityType,
+            @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid,
+            boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
+        mStackSupervisor.getRunningTasks().getTasks(maxNum, list, ignoreActivityType,
+                ignoreWindowingMode, this, callingUid, allowed, crossUser, profileIds);
+    }
+
+    void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
+        boolean sendHint = forceSend;
+
+        if (!sendHint) {
+            // Send power hint if we don't know what we're launching yet
+            sendHint = targetActivity == null || targetActivity.app == null;
+        }
+
+        if (!sendHint) { // targetActivity != null
+            // Send power hint when the activity's process is different than the current resumed
+            // activity on all displays, or if there are no resumed activities in the system.
+            boolean noResumedActivities = true;
+            boolean allFocusedProcessesDiffer = true;
+            for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
+                final DisplayContent displayContent = getChildAt(displayNdx);
+                final ActivityRecord resumedActivity = displayContent.getResumedActivity();
+                final WindowProcessController resumedActivityProcess =
+                        resumedActivity == null ? null : resumedActivity.app;
+
+                noResumedActivities &= resumedActivityProcess == null;
+                if (resumedActivityProcess != null) {
+                    allFocusedProcessesDiffer &= !resumedActivityProcess.equals(targetActivity.app);
+                }
+            }
+            sendHint = noResumedActivities || allFocusedProcessesDiffer;
+        }
+
+        if (sendHint && mService.mPowerManagerInternal != null) {
+            mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
+            mPowerHintSent = true;
+        }
+    }
+
+    void sendPowerHintForLaunchEndIfNeeded() {
+        // Trigger launch power hint if activity is launched
+        if (mPowerHintSent && mService.mPowerManagerInternal != null) {
+            mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
+            mPowerHintSent = false;
+        }
+    }
+
+    private void calculateDefaultMinimalSizeOfResizeableTasks() {
+        final Resources res = mService.mContext.getResources();
+        final float minimalSize = res.getDimension(
+                com.android.internal.R.dimen.default_minimal_size_resizable_task);
+        final DisplayMetrics dm = res.getDisplayMetrics();
+
+        mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density);
+    }
+
+    /**
+     * Dumps the activities matching the given {@param name} in the either the focused stack
+     * or all visible stacks if {@param dumpVisibleStacks} is true.
+     */
+    ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly,
+            boolean dumpFocusedStackOnly) {
+        if (dumpFocusedStackOnly) {
+            return getTopDisplayFocusedStack().getDumpActivitiesLocked(name);
+        } else {
+            ArrayList<ActivityRecord> activities = new ArrayList<>();
+            int numDisplays = getChildCount();
+            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+                final DisplayContent display = getChildAt(displayNdx);
+                for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                    final ActivityStack stack = display.getStackAt(stackNdx);
+                    if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
+                        activities.addAll(stack.getDumpActivitiesLocked(name));
+                    }
+                }
+            }
+            return activities;
+        }
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix);
+        pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final DisplayContent display = getChildAt(i);
+            display.dump(pw, prefix, true /* dumpAll */);
+        }
+    }
+
+    /**
+     * Dump all connected displays' configurations.
+     * @param prefix Prefix to apply to each line of the dump.
+     */
+    void dumpDisplayConfigs(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.println("Display override configurations:");
+        final int displayCount = getChildCount();
+        for (int i = 0; i < displayCount; i++) {
+            final DisplayContent displayContent = getChildAt(i);
+            pw.print(prefix); pw.print("  "); pw.print(displayContent.mDisplayId); pw.print(": ");
+            pw.println(displayContent.getRequestedOverrideConfiguration());
+        }
+    }
+
+    public void dumpDisplays(PrintWriter pw) {
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            final DisplayContent display = getChildAt(i);
+            pw.print("[id:" + display.mDisplayId + " stacks:");
+            display.dumpStacks(pw);
+            pw.print("]");
+        }
+    }
+
+    boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
+            String dumpPackage) {
+        boolean printed = false;
+        boolean needSep = false;
+        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
+            DisplayContent displayContent = getChildAt(displayNdx);
+            pw.print("Display #"); pw.print(displayContent.mDisplayId);
+            pw.println(" (activities from top to bottom):");
+            for (int stackNdx = displayContent.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+                final ActivityStack stack = displayContent.getStackAt(stackNdx);
+                pw.println();
+                printed = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, needSep);
+                needSep = printed;
+            }
+            printThisActivity(pw, displayContent.getResumedActivity(), dumpPackage, needSep,
+                    " ResumedActivity:");
+        }
+
+        printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, "  ",
+                "Fin", false, !dumpAll,
+                false, dumpPackage, true, "  Activities waiting to finish:", null);
+        printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, "  ",
+                "Stop", false, !dumpAll,
+                false, dumpPackage, true, "  Activities waiting to stop:", null);
+        printed |= dumpHistoryList(fd, pw, mStackSupervisor.mGoingToSleepActivities,
+                "  ", "Sleep", false, !dumpAll,
+                false, dumpPackage, true, "  Activities waiting to sleep:", null);
+
+        return printed;
+    }
+
+    @Override
+    public void dumpDebug(ProtoOutputStream proto, long fieldId,
+            @WindowTraceLogLevel int logLevel) {
+        final long token = proto.start(fieldId);
+        dumpDebugInner(proto, ROOT_WINDOW_CONTAINER, logLevel);
+        for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
+            final DisplayContent displayContent = getChildAt(displayNdx);
+            displayContent.dumpDebug(proto,
+                    com.android.server.am.ActivityStackSupervisorProto.DISPLAYS, logLevel);
+        }
+        mStackSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER);
+        // TODO(b/111541062): Update tests to look for resumed activities on all displays
+        final ActivityStack focusedStack = getTopDisplayFocusedStack();
+        if (focusedStack != null) {
+            proto.write(FOCUSED_STACK_ID, focusedStack.mStackId);
+            final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity();
+            if (focusedActivity != null) {
+                focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
+            }
+        } else {
+            proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
+        }
+        proto.write(IS_HOME_RECENTS_COMPONENT,
+                mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
+        mService.getActivityStartController().dumpDebug(proto, PENDING_ACTIVITIES);
+        proto.end(token);
+    }
+
+    private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken {
+        private final String mTag;
+        private final long mAcquireTime;
+        private final int mDisplayId;
+
+        public SleepTokenImpl(String tag, int displayId) {
+            mTag = tag;
+            mDisplayId = displayId;
+            mAcquireTime = SystemClock.uptimeMillis();
+        }
+
+        @Override
+        public void release() {
+            synchronized (mService.mGlobalLock) {
+                removeSleepToken(this);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "{\"" + mTag + "\", display " + mDisplayId
+                    + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 53c0dd0..98127ab 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -56,7 +56,7 @@
     private ActivityStack mTopDisplayFocusStack;
 
     void getTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType,
-            @WindowingMode int ignoreWindowingMode, RootActivityContainer root,
+            @WindowingMode int ignoreWindowingMode, RootWindowContainer root,
             int callingUid, boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
         // Return early if there are no tasks to fetch
         if (maxNum <= 0) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 45c012e..987ecc5 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -548,8 +548,8 @@
             return;
         }
         mResizeMode = resizeMode;
-        mAtmService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
-        mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
+        mAtmService.mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+        mAtmService.mRootWindowContainer.resumeFocusedStacksTopActivities();
         updateTaskDescription();
     }
 
@@ -602,10 +602,10 @@
                     // this won't cause tons of irrelevant windows being preserved because only
                     // activities in this task may experience a bounds change. Configs for other
                     // activities stay the same.
-                    mAtmService.mRootActivityContainer.ensureActivitiesVisible(r, 0,
+                    mAtmService.mRootWindowContainer.ensureActivitiesVisible(r, 0,
                             preserveWindow);
                     if (!kept) {
-                        mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
+                        mAtmService.mRootWindowContainer.resumeFocusedStacksTopActivities();
                     }
                 }
             }
@@ -670,7 +670,7 @@
             @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
             boolean schedulePictureInPictureModeChange, String reason) {
         final ActivityStackSupervisor supervisor = mAtmService.mStackSupervisor;
-        final RootActivityContainer root = mAtmService.mRootActivityContainer;
+        final RootWindowContainer root = mAtmService.mRootWindowContainer;
         final WindowManagerService windowManager = mAtmService.mWindowManager;
         final ActivityStack sourceStack = getStack();
         final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
@@ -1028,7 +1028,7 @@
             forceWindowsScaleable(false /* force */);
         }
 
-        mAtmService.mRootActivityContainer.updateUIDsPresentOnDisplay();
+        mAtmService.mRootWindowContainer.updateUIDsPresentOnDisplay();
     }
 
     void updateTaskMovement(boolean toFront) {
@@ -1041,7 +1041,7 @@
                 mLastTimeMoved *= -1;
             }
         }
-        mAtmService.mRootActivityContainer.invalidateTaskLayers();
+        mAtmService.mRootWindowContainer.invalidateTaskLayers();
     }
 
     /**
@@ -1218,7 +1218,7 @@
 
         // Make sure the list of display UID whitelists is updated
         // now that this record is in a new task.
-        mAtmService.mRootActivityContainer.updateUIDsPresentOnDisplay();
+        mAtmService.mRootWindowContainer.updateUIDsPresentOnDisplay();
     }
 
     void addChild(ActivityRecord r) {
@@ -1581,9 +1581,9 @@
         // to do this for the pinned stack as the bounds are controlled by the system.
         if (!inPinnedWindowingMode() && mStack != null) {
             final int defaultMinSizeDp =
-                    mAtmService.mRootActivityContainer.mDefaultMinSizeOfResizeableTaskDp;
+                    mAtmService.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp;
             final DisplayContent display =
-                    mAtmService.mRootActivityContainer.getDisplayContent(mStack.mDisplayId);
+                    mAtmService.mRootWindowContainer.getDisplayContent(mStack.mDisplayId);
             final float density =
                     (float) display.getConfiguration().densityDpi / DisplayMetrics.DENSITY_DEFAULT;
             final int defaultMinSize = (int) (defaultMinSizeDp * density);
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 4de61f0..b8f3abe 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -137,7 +137,7 @@
         // STEP 1: Determine the display to launch the activity/task.
         final int displayId = getPreferredLaunchDisplay(task, options, source, currentParams);
         outParams.mPreferredDisplayId = displayId;
-        DisplayContent display = mSupervisor.mRootActivityContainer.getDisplayContent(displayId);
+        DisplayContent display = mSupervisor.mRootWindowContainer.getDisplayContent(displayId);
         if (DEBUG) {
             appendLog("display-id=" + outParams.mPreferredDisplayId + " display-windowing-mode="
                     + display.getWindowingMode());
@@ -333,13 +333,13 @@
         }
 
         if (displayId != INVALID_DISPLAY
-                && mSupervisor.mRootActivityContainer.getDisplayContent(displayId) == null) {
+                && mSupervisor.mRootWindowContainer.getDisplayContent(displayId) == null) {
             displayId = currentParams.mPreferredDisplayId;
         }
         displayId = (displayId == INVALID_DISPLAY) ? currentParams.mPreferredDisplayId : displayId;
 
         return (displayId != INVALID_DISPLAY
-                && mSupervisor.mRootActivityContainer.getDisplayContent(displayId) != null)
+                && mSupervisor.mRootWindowContainer.getDisplayContent(displayId) != null)
                 ? displayId : DEFAULT_DISPLAY;
     }
 
@@ -656,7 +656,7 @@
             // There is no way for us to fit the bounds in the display without changing width
             // or height. Just move the start to align with the display.
             final int layoutDirection =
-                    mSupervisor.mRootActivityContainer.getConfiguration().getLayoutDirection();
+                    mSupervisor.mRootWindowContainer.getConfiguration().getLayoutDirection();
             final int left = layoutDirection == View.LAYOUT_DIRECTION_RTL
                     ? displayStableBounds.right - inOutBounds.right + inOutBounds.left
                     : displayStableBounds.left;
diff --git a/services/core/java/com/android/server/wm/TaskPersister.java b/services/core/java/com/android/server/wm/TaskPersister.java
index eb130a1..8cff99b 100644
--- a/services/core/java/com/android/server/wm/TaskPersister.java
+++ b/services/core/java/com/android/server/wm/TaskPersister.java
@@ -16,7 +16,7 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
+import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
 
 import android.annotation.NonNull;
 import android.graphics.Bitmap;
@@ -39,7 +39,6 @@
 import libcore.io.IoUtils;
 
 import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.BufferedReader;
@@ -330,7 +329,7 @@
                                 // mWriteQueue.add(new TaskWriteQueueItem(task));
 
                                 final int taskId = task.mTaskId;
-                                if (mService.mRootActivityContainer.anyTaskForId(taskId,
+                                if (mService.mRootWindowContainer.anyTaskForId(taskId,
                                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) != null) {
                                     // Should not happen.
                                     Slog.wtf(TAG, "Existing task with taskId " + taskId + "found");
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 85b507f..ab3419c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1116,7 +1116,7 @@
         mDisplayWindowSettings = new DisplayWindowSettings(this);
         mPolicy = policy;
         mAnimator = new WindowAnimator(this);
-        mRoot = new RootActivityContainer(mAtmService, this);
+        mRoot = new RootWindowContainer(this);
 
         mWindowPlacerLocked = new WindowSurfacePlacer(this);
         mTaskSnapshotController = new TaskSnapshotController(this);
@@ -1722,7 +1722,7 @@
             }
         }
 
-        return mAtmService.mRootActivityContainer.getDisplayContentOrCreate(displayId);
+        return mRoot.getDisplayContentOrCreate(displayId);
     }
 
     private boolean doesAddToastWindowRequireToken(String packageName, int callingUid,
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index f6dd71b..9a40b1b1 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -981,7 +981,7 @@
             return;
         }
         final DisplayContent displayContent =
-                mAtm.mRootActivityContainer.getDisplayContent(mDisplayId);
+                mAtm.mRootWindowContainer.getDisplayContent(mDisplayId);
         if (displayContent != null) {
             displayContent.unregisterConfigurationChangeListener(this);
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index 9c17de9..ed9cdf4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -61,9 +61,9 @@
     @Test
     public void testLastFocusedStackIsUpdatedWhenMovingStack() {
         // Create a stack at bottom.
-        final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         final ActivityStack stack =
-                new StackBuilder(mRootActivityContainer).setOnTop(!ON_TOP).build();
+                new StackBuilder(mRootWindowContainer).setOnTop(!ON_TOP).build();
         final ActivityStack prevFocusedStack = display.getFocusedStack();
 
         stack.moveToFront("moveStackToFront");
@@ -83,7 +83,7 @@
     @Test
     public void testFullscreenStackCanBeFocusedWhenFocusablePinnedStackExists() {
         // Create a pinned stack and move to front.
-        final ActivityStack pinnedStack = mRootActivityContainer.getDefaultDisplay().createStack(
+        final ActivityStack pinnedStack = mRootWindowContainer.getDefaultDisplay().createStack(
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP);
         final Task pinnedTask = new TaskBuilder(mService.mStackSupervisor)
                 .setStack(pinnedStack).build();
@@ -96,7 +96,7 @@
 
         // Create a fullscreen stack and move to front.
         final ActivityStack fullscreenStack = createFullscreenStackWithSimpleActivityAt(
-                mRootActivityContainer.getDefaultDisplay());
+                mRootWindowContainer.getDefaultDisplay());
         fullscreenStack.moveToFront("moveFullscreenStackToFront");
 
         // The focused stack should be the fullscreen stack.
@@ -140,7 +140,7 @@
         doReturn(false).when(display).shouldDestroyContentOnRemove();
 
         // Put home stack on the display.
-        final ActivityStack homeStack = new StackBuilder(mRootActivityContainer)
+        final ActivityStack homeStack = new StackBuilder(mRootWindowContainer)
                 .setDisplay(display).setActivityType(ACTIVITY_TYPE_HOME).build();
 
         // Put a finishing standard activity which will be reparented.
@@ -169,14 +169,14 @@
      */
     @Test
     public void testTopRunningActivity() {
-        final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         final KeyguardController keyguard = mSupervisor.getKeyguardController();
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer).build();
         final ActivityRecord activity = stack.getTopNonFinishingActivity();
 
         // Create empty stack on top.
         final ActivityStack emptyStack =
-                new StackBuilder(mRootActivityContainer).setCreateActivity(false).build();
+                new StackBuilder(mRootWindowContainer).setCreateActivity(false).build();
 
         // Make sure the top running activity is not affected when keyguard is not locked.
         assertTopRunningActivity(activity, display);
@@ -219,7 +219,7 @@
      */
     @Test
     public void testAlwaysOnTopStackLocation() {
-        final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         final ActivityStack alwaysOnTopStack = display.createStack(WINDOWING_MODE_FREEFORM,
                 ACTIVITY_TYPE_STANDARD, true /* onTop */);
         final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
@@ -273,18 +273,18 @@
 
     @Test
     public void testRemoveStackInWindowingModes() {
-        removeStackTests(() -> mRootActivityContainer.removeStacksInWindowingModes(
+        removeStackTests(() -> mRootWindowContainer.removeStacksInWindowingModes(
                 WINDOWING_MODE_FULLSCREEN));
     }
 
     @Test
     public void testRemoveStackWithActivityTypes() {
         removeStackTests(
-                () -> mRootActivityContainer.removeStacksWithActivityTypes(ACTIVITY_TYPE_STANDARD));
+                () -> mRootWindowContainer.removeStacksWithActivityTypes(ACTIVITY_TYPE_STANDARD));
     }
 
     private void removeStackTests(Runnable runnable) {
-        final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         final ActivityStack stack1 = display.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_STANDARD, ON_TOP);
         final ActivityStack stack2 = display.createStack(WINDOWING_MODE_FULLSCREEN,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 3eee031..7204a81 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -341,7 +341,7 @@
     public void testConsecutiveLaunchOnDifferentDisplay() {
         onActivityLaunched(mTopActivity);
 
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer)
                 .setDisplay(addNewDisplayContentAt(DisplayContent.POSITION_BOTTOM))
                 .setCreateActivity(false)
                 .build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 14c0ca1..d6bd1d0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -109,7 +109,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mStack = new StackBuilder(mRootActivityContainer).build();
+        mStack = new StackBuilder(mRootWindowContainer).build();
         mTask = mStack.getBottomMostTask();
         mActivity = mTask.getTopNonFinishingActivity();
 
@@ -133,7 +133,7 @@
     public void testStackCleanupOnTaskRemoval() {
         mStack.removeChild(mTask, null /*reason*/);
         // Stack should be gone on task removal.
-        assertNull(mService.mRootActivityContainer.getStack(mStack.mStackId));
+        assertNull(mService.mRootWindowContainer.getStack(mStack.mStackId));
     }
 
     @Test
@@ -485,7 +485,7 @@
                 .build();
         mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
 
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer).build();
         try {
             doReturn(false).when(stack).isStackTranslucent(any());
             assertFalse(mStack.shouldBeVisible(null /* starting */));
@@ -693,14 +693,14 @@
     @Test
     public void testFinishActivityIfPossible_adjustStackOrder() {
         // Prepare the stacks with order (top to bottom): mStack, stack1, stack2.
-        final ActivityStack stack1 = new StackBuilder(mRootActivityContainer).build();
+        final ActivityStack stack1 = new StackBuilder(mRootWindowContainer).build();
         mStack.moveToFront("test");
         // The stack2 is needed here for moving back to simulate the
         // {@link DisplayContent#mPreferredTopFocusableStack} is cleared, so
         // {@link DisplayContent#getFocusedStack} will rely on the order of focusable-and-visible
         // stacks. Then when mActivity is finishing, its stack will be invisible (no running
         // activities in the stack) that is the key condition to verify.
-        final ActivityStack stack2 = new StackBuilder(mRootActivityContainer).build();
+        final ActivityStack stack2 = new StackBuilder(mRootWindowContainer).build();
         stack2.moveToBack("test", stack2.getBottomMostTask());
 
         assertTrue(mStack.isTopStackOnDisplay());
@@ -852,7 +852,7 @@
 
         // Simulates that {@code currentTop} starts an existing activity from background (so its
         // state is stopped) and the starting flow just goes to place it at top.
-        final ActivityStack nextStack = new StackBuilder(mRootActivityContainer).build();
+        final ActivityStack nextStack = new StackBuilder(mRootWindowContainer).build();
         final ActivityRecord nextTop = nextStack.getTopNonFinishingActivity();
         nextTop.setState(STOPPED, "test");
 
@@ -974,7 +974,7 @@
 
         // Add another stack to become focused and make the activity there visible. This way it
         // simulates finishing in non-focused stack in split-screen.
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer).build();
         final ActivityRecord focusedActivity = stack.getTopMostActivity();
         focusedActivity.nowVisible = true;
         focusedActivity.mVisibleRequested = true;
@@ -991,7 +991,7 @@
      */
     @Test
     public void testDestroyIfPossible() {
-        doReturn(false).when(mRootActivityContainer).resumeFocusedStacksTopActivities();
+        doReturn(false).when(mRootWindowContainer).resumeFocusedStacksTopActivities();
         spyOn(mStack);
         mActivity.destroyIfPossible("test");
 
@@ -1011,7 +1011,7 @@
         final ActivityStack homeStack = mActivity.getDisplay().getHomeStack();
         homeStack.forAllTasks((t) -> { homeStack.removeChild(t, "test"); });
         mActivity.finishing = true;
-        doReturn(false).when(mRootActivityContainer).resumeFocusedStacksTopActivities();
+        doReturn(false).when(mRootWindowContainer).resumeFocusedStacksTopActivities();
         spyOn(mStack);
 
         // Try to destroy the last activity above the home stack.
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index 530adb5..9647178 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -60,7 +60,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mFullscreenStack = mRootActivityContainer.getDefaultDisplay().createStack(
+        mFullscreenStack = mRootWindowContainer.getDefaultDisplay().createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
     }
 
@@ -113,7 +113,7 @@
     public void testHandleNonResizableTaskOnSecondaryDisplay() {
         // Create an unresizable task on secondary display.
         final DisplayContent newDisplay = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer)
                 .setDisplay(newDisplay).build();
         final ActivityRecord unresizableActivity = stack.getTopNonFinishingActivity();
         final Task task = unresizableActivity.getTask();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 4f7f513..c24ce2b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -83,7 +83,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mDefaultDisplay = mRootActivityContainer.getDefaultDisplay();
+        mDefaultDisplay = mRootWindowContainer.getDefaultDisplay();
         mStack = mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
                 true /* onTop */);
         spyOn(mStack);
@@ -107,7 +107,7 @@
         r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
         assertEquals(r, mStack.getResumedActivity());
 
-        final ActivityStack destStack = mRootActivityContainer.getDefaultDisplay().createStack(
+        final ActivityStack destStack = mRootWindowContainer.getDefaultDisplay().createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
         mTask.reparent(destStack, true /* toTop */, Task.REPARENT_KEEP_STACK_AT_FRONT,
@@ -125,7 +125,7 @@
         r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
         assertEquals(r, mStack.getResumedActivity());
 
-        final ActivityStack destStack = mRootActivityContainer.getDefaultDisplay().createStack(
+        final ActivityStack destStack = mRootWindowContainer.getDefaultDisplay().createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         mTask.reparent(destStack, true /*toTop*/, REPARENT_MOVE_STACK_TO_FRONT, false, false,
                 "testResumedActivityFromActivityReparenting");
@@ -238,8 +238,8 @@
                 .setUid(UserHandle.PER_USER_RANGE * 2).build();
         taskOverlay.mTaskOverlay = true;
 
-        final RootActivityContainer.FindTaskResult result =
-                new RootActivityContainer.FindTaskResult();
+        final RootWindowContainer.FindTaskResult result =
+                new RootWindowContainer.FindTaskResult();
         result.process(r, mStack);
 
         assertEquals(r, task.getTopNonFinishingActivity(false /* includeOverlays */));
@@ -264,14 +264,14 @@
         // Using target activity to find task.
         final ActivityRecord r1 = new ActivityBuilder(mService).setComponent(
                 target).setTargetActivity(targetActivity).build();
-        RootActivityContainer.FindTaskResult result = new RootActivityContainer.FindTaskResult();
+        RootWindowContainer.FindTaskResult result = new RootWindowContainer.FindTaskResult();
         result.process(r1, mStack);
         assertThat(result.mRecord).isNotNull();
 
         // Using alias activity to find task.
         final ActivityRecord r2 = new ActivityBuilder(mService).setComponent(
                 alias).setTargetActivity(targetActivity).build();
-        result = new RootActivityContainer.FindTaskResult();
+        result = new RootWindowContainer.FindTaskResult();
         result.process(r2, mStack);
         assertThat(result.mRecord).isNotNull();
     }
@@ -825,7 +825,7 @@
                 mDefaultDisplay.positionStackAtBottom(stack);
             }
         } else {
-            stack = new StackBuilder(mRootActivityContainer)
+            stack = new StackBuilder(mRootWindowContainer)
                     .setDisplay(display)
                     .setWindowingMode(windowingMode)
                     .setActivityType(activityType)
@@ -845,7 +845,7 @@
         mStack.mResumedActivity = secondActivity;
 
         // Note the activities have non-null ActivityRecord.app, so it won't remove directly.
-        mRootActivityContainer.mFinishDisabledPackageActivitiesHelper.process(
+        mRootWindowContainer.mFinishDisabledPackageActivitiesHelper.process(
                 firstActivity.packageName, null /* filterByClasses */, true /* doit */,
                 true /* evenPersistent */, UserHandle.USER_ALL);
 
@@ -874,7 +874,7 @@
 
         assertEquals(2, mTask.getChildCount());
 
-        mRootActivityContainer.mFinishDisabledPackageActivitiesHelper.process(
+        mRootWindowContainer.mFinishDisabledPackageActivitiesHelper.process(
                 activity.packageName, null  /* filterByClasses */, true /* doit */,
                 true /* evenPersistent */, UserHandle.USER_ALL);
 
@@ -901,7 +901,7 @@
 
         assertEquals(2, mTask.getChildCount());
 
-        mRootActivityContainer.handleAppDied(secondActivity.app);
+        mRootWindowContainer.handleAppDied(secondActivity.app);
 
         assertFalse(mTask.hasChild());
         assertFalse(mStack.hasChild());
@@ -915,7 +915,7 @@
         activity.launchCount = 1;
         activity.setSavedState(null /* savedState */);
 
-        mRootActivityContainer.handleAppDied(activity.app);
+        mRootWindowContainer.handleAppDied(activity.app);
 
         assertEquals(1, mTask.getChildCount());
         assertEquals(1, mStack.getChildCount());
@@ -929,7 +929,7 @@
         activity.launchCount = 3;
         activity.setSavedState(null /* savedState */);
 
-        mRootActivityContainer.handleAppDied(activity.app);
+        mRootWindowContainer.handleAppDied(activity.app);
 
         assertFalse(mTask.hasChild());
         assertFalse(mStack.hasChild());
@@ -943,7 +943,7 @@
         activity.launchCount = 1;
         activity.setSavedState(null /* savedState */);
 
-        mRootActivityContainer.handleAppDied(activity.app);
+        mRootWindowContainer.handleAppDied(activity.app);
 
         assertEquals(1, mTask.getChildCount());
         assertEquals(1, mStack.getChildCount());
@@ -957,7 +957,7 @@
         activity.launchCount = 3;
         activity.setSavedState(null /* savedState */);
 
-        mRootActivityContainer.handleAppDied(activity.app);
+        mRootWindowContainer.handleAppDied(activity.app);
 
         assertFalse(mTask.hasChild());
         assertFalse(mStack.hasChild());
@@ -1014,7 +1014,7 @@
         // should be destroyed immediately with updating configuration to restore original state.
         final ActivityRecord activity1 = finishTopActivity(stack1);
         assertEquals(DESTROYING, activity1.getState());
-        verify(mRootActivityContainer).ensureVisibilityAndConfig(eq(null) /* starting */,
+        verify(mRootWindowContainer).ensureVisibilityAndConfig(eq(null) /* starting */,
                 eq(display.mDisplayId), anyBoolean(), anyBoolean());
     }
 
@@ -1129,7 +1129,7 @@
         assertFalse(unknownAppVisibilityController.allResolved());
 
         // Assume the top activity is going to resume and
-        // {@link RootActivityContainer#cancelInitializingActivities} should clear the unknown
+        // {@link RootWindowContainer#cancelInitializingActivities} should clear the unknown
         // visibility records that are occluded.
         mStack.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */);
         // Assume the top activity relayouted, just remove it directly.
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
index 11aac3c..76a761c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
@@ -77,7 +77,7 @@
                 .setCreateTask(true)
                 .build();
         final int startFlags = random.nextInt();
-        final ActivityStack stack = mService.mRootActivityContainer.getDefaultDisplay().createStack(
+        final ActivityStack stack = mService.mRootWindowContainer.getDefaultDisplay().createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         final WindowProcessController wpc = new WindowProcessController(mService,
                 mService.mContext.getApplicationInfo(), "name", 12345,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
index 4234720..399cf49 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
@@ -24,7 +24,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 
@@ -91,7 +90,7 @@
     @Mock
     private ActivityTaskManagerService mService;
     @Mock
-    private RootActivityContainer mRootActivityContainer;
+    private RootWindowContainer mRootWindowContainer;
     @Mock
     private ActivityStackSupervisor mSupervisor;
     @Mock
@@ -115,7 +114,7 @@
         MockitoAnnotations.initMocks(this);
         mService.mAmInternal = mAmInternal;
         mInterceptor = new ActivityStartInterceptor(
-                mService, mSupervisor, mRootActivityContainer, mContext);
+                mService, mSupervisor, mRootWindowContainer, mContext);
         mInterceptor.setStates(TEST_USER_ID, TEST_REAL_CALLING_PID, TEST_REAL_CALLING_UID,
                 TEST_START_FLAGS, TEST_CALLING_PACKAGE);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 6462d6a..b1132f6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -134,7 +134,7 @@
     public void testUpdateLaunchBounds() {
         // When in a non-resizeable stack, the task bounds should be updated.
         final Task task = new TaskBuilder(mService.mStackSupervisor)
-                .setStack(mService.mRootActivityContainer.getDefaultDisplay().createStack(
+                .setStack(mService.mRootWindowContainer.getDefaultDisplay().createStack(
                         WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */))
                 .build();
         final Rect bounds = new Rect(10, 10, 100, 100);
@@ -145,7 +145,7 @@
 
         // When in a resizeable stack, the stack bounds should be updated as well.
         final Task task2 = new TaskBuilder(mService.mStackSupervisor)
-                .setStack(mService.mRootActivityContainer.getDefaultDisplay().createStack(
+                .setStack(mService.mRootWindowContainer.getDefaultDisplay().createStack(
                         WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */))
                 .build();
         assertThat((Object) task2.getStack()).isInstanceOf(ActivityStack.class);
@@ -336,7 +336,7 @@
      * Creates a {@link ActivityStarter} with default parameters and necessary mocks.
      *
      * @param launchFlags The intent flags to launch activity.
-     * @param mockGetLaunchStack Whether to mock {@link RootActivityContainer#getLaunchStack} for
+     * @param mockGetLaunchStack Whether to mock {@link RootWindowContainer#getLaunchStack} for
      *                           always launching to the testing stack. Set to false when allowing
      *                           the activity can be launched to any stack that is decided by real
      *                           implementation.
@@ -351,13 +351,13 @@
 
         if (mockGetLaunchStack) {
             // Instrument the stack and task used.
-            final ActivityStack stack = mRootActivityContainer.getDefaultDisplay().createStack(
+            final ActivityStack stack = mRootWindowContainer.getDefaultDisplay().createStack(
                     WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
             // Direct starter to use spy stack.
-            doReturn(stack).when(mRootActivityContainer)
+            doReturn(stack).when(mRootWindowContainer)
                     .getLaunchStack(any(), any(), any(), anyBoolean());
-            doReturn(stack).when(mRootActivityContainer)
+            doReturn(stack).when(mRootWindowContainer)
                     .getLaunchStack(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt());
         }
 
@@ -457,7 +457,7 @@
         final ActivityStack focusStack = focusActivity.getActivityStack();
         focusStack.moveToFront("testSplitScreenDeliverToTop");
 
-        doReturn(reusableActivity).when(mRootActivityContainer).findTask(any(), anyInt());
+        doReturn(reusableActivity).when(mRootWindowContainer).findTask(any(), anyInt());
 
         final int result = starter.setReason("testSplitScreenDeliverToTop").execute();
 
@@ -489,7 +489,7 @@
         // Enter split-screen. Primary stack should have focus.
         focusActivity.getActivityStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
 
-        doReturn(reusableActivity).when(mRootActivityContainer).findTask(any(), anyInt());
+        doReturn(reusableActivity).when(mRootWindowContainer).findTask(any(), anyInt());
 
         final int result = starter.setReason("testSplitScreenMoveToFront").execute();
 
@@ -502,7 +502,7 @@
      */
     @Test
     public void testTaskModeViolation() {
-        final DisplayContent display = mService.mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay();
         display.removeAllTasks();
         assertNoTasks(display);
 
@@ -738,7 +738,7 @@
                 .setCreateTask(true).build();
         finishingTopActivity.getActivityStack().moveToFront("finishingTopActivity");
 
-        assertEquals(finishingTopActivity, mRootActivityContainer.topRunningActivity());
+        assertEquals(finishingTopActivity, mRootWindowContainer.topRunningActivity());
         finishingTopActivity.finishing = true;
 
         // Launch the bottom task of the target stack.
@@ -747,7 +747,7 @@
                 .setIntent(activity.intent)
                 .execute();
         // The hierarchies of the activity should move to front.
-        assertEquals(activity, mRootActivityContainer.topRunningActivity());
+        assertEquals(activity, mRootWindowContainer.topRunningActivity());
     }
 
     /**
@@ -802,7 +802,7 @@
         // Create a secondary display with an activity.
         final TestDisplayContent secondaryDisplay =
                 new TestDisplayContent.Builder(mService, 1000, 1500).build();
-        mRootActivityContainer.positionChildAt(POSITION_TOP, secondaryDisplay,
+        mRootWindowContainer.positionChildAt(POSITION_TOP, secondaryDisplay,
                 false /* includingParents */);
         final ActivityRecord singleTaskActivity = createSingleTaskActivityOn(
                 secondaryDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
@@ -970,7 +970,7 @@
         final ActivityStarter starter = prepareStarter(0 /* flags */);
         starter.mStartActivity = new ActivityBuilder(mService).build();
         final Task task = new TaskBuilder(mService.mStackSupervisor)
-                .setStack(mService.mRootActivityContainer.getDefaultDisplay().createStack(
+                .setStack(mService.mRootWindowContainer.getDefaultDisplay().createStack(
                         WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */))
                 .setUserId(10)
                 .build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 438de78..079c49f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -79,7 +79,7 @@
     /** Verify that activity is finished correctly upon request. */
     @Test
     public void testActivityFinish() {
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer).build();
         final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
         assertTrue("Activity must be finished", mService.finishActivity(activity.appToken,
                 0 /* resultCode */, null /* resultData */,
@@ -93,7 +93,7 @@
 
     @Test
     public void testOnPictureInPictureRequested() throws RemoteException {
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer).build();
         final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
         ClientLifecycleManager lifecycleManager = mService.getLifecycleManager();
         doNothing().when(lifecycleManager).scheduleTransaction(any());
@@ -112,7 +112,7 @@
 
     @Test(expected = IllegalStateException.class)
     public void testOnPictureInPictureRequested_cannotEnterPip() throws RemoteException {
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer).build();
         final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
         ClientLifecycleManager lifecycleManager = mService.getLifecycleManager();
         doNothing().when(lifecycleManager).scheduleTransaction(any());
@@ -127,7 +127,7 @@
     @Test
     public void testTaskTransaction() {
         removeGlobalMinSizeRestriction();
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
         final Task task = stack.getTopMostTask();
         WindowContainerTransaction t = new WindowContainerTransaction();
@@ -140,7 +140,7 @@
     @Test
     public void testStackTransaction() {
         removeGlobalMinSizeRestriction();
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
         ActivityManager.StackInfo info =
                 mService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
@@ -189,7 +189,7 @@
         Configuration c = new Configuration(newDisp1.getRequestedOverrideConfiguration());
         c.windowConfiguration.setBounds(new Rect(0, 0, 1000, 1300));
         newDisp1.onRequestedOverrideConfigurationChanged(c);
-        mService.mRootActivityContainer.ensureVisibilityAndConfig(null /* starting */,
+        mService.mRootWindowContainer.ensureVisibilityAndConfig(null /* starting */,
                 newDisp1.mDisplayId, false /* markFrozenIfConfigChanged */,
                 false /* deferResume */);
         assertEquals(0, added.size());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 108d45b..0f22724 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -55,7 +55,7 @@
     final Context mContext = getInstrumentation().getTargetContext();
 
     ActivityTaskManagerService mService;
-    RootActivityContainer mRootActivityContainer;
+    RootWindowContainer mRootWindowContainer;
     ActivityStackSupervisor mSupervisor;
 
     // Default package name
@@ -73,7 +73,7 @@
     public void setUpBase() {
         mService = mSystemServicesTestRule.getActivityTaskManagerService();
         mSupervisor = mService.mStackSupervisor;
-        mRootActivityContainer = mService.mRootActivityContainer;
+        mRootWindowContainer = mService.mRootWindowContainer;
     }
 
     /** Creates and adds a {@link TestDisplayContent} to supervisor at the given position. */
@@ -83,7 +83,7 @@
 
     /** Sets the default minimum task size to 1 so that tests can use small task sizes */
     public void removeGlobalMinSizeRestriction() {
-        mService.mRootActivityContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
+        mService.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
     }
 
     /**
@@ -273,7 +273,7 @@
                     activity.processName, activity.info.applicationInfo.uid);
 
             // Resume top activities to make sure all other signals in the system are connected.
-            mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
+            mService.mRootWindowContainer.resumeFocusedStacksTopActivities();
             return activity;
         }
     }
@@ -345,7 +345,7 @@
 
         Task build() {
             if (mStack == null && mCreateStack) {
-                mStack = mSupervisor.mRootActivityContainer.getDefaultDisplay().createStack(
+                mStack = mSupervisor.mRootWindowContainer.getDefaultDisplay().createStack(
                         WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
                 spyOn(mStack);
             }
@@ -379,7 +379,7 @@
     }
 
     static class StackBuilder {
-        private final RootActivityContainer mRootActivityContainer;
+        private final RootWindowContainer mRootWindowContainer;
         private DisplayContent mDisplay;
         private int mStackId = -1;
         private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
@@ -387,9 +387,9 @@
         private boolean mOnTop = true;
         private boolean mCreateActivity = true;
 
-        StackBuilder(RootActivityContainer root) {
-            mRootActivityContainer = root;
-            mDisplay = mRootActivityContainer.getDefaultDisplay();
+        StackBuilder(RootWindowContainer root) {
+            mRootWindowContainer = root;
+            mDisplay = mRootWindowContainer.getDefaultDisplay();
         }
 
         StackBuilder setWindowingMode(int windowingMode) {
@@ -425,7 +425,7 @@
         ActivityStack build() {
             final int stackId = mStackId >= 0 ? mStackId : mDisplay.getNextStackId();
             final ActivityStack stack;
-            final ActivityStackSupervisor supervisor = mRootActivityContainer.mStackSupervisor;
+            final ActivityStackSupervisor supervisor = mRootWindowContainer.mStackSupervisor;
 
             stack = mDisplay.createStackUnchecked(mWindowingMode, mActivityType, stackId, mOnTop);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 612e051..0758eeb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -713,13 +713,13 @@
                 IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
 
         final ActivityStack stack =
-                new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
+                new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
                         .setDisplay(dc)
                         .build();
         doReturn(true).when(stack).isVisible();
 
         final ActivityStack freeformStack =
-                new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
+                new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
                         .setDisplay(dc)
                         .setWindowingMode(WINDOWING_MODE_FREEFORM)
                         .build();
@@ -747,7 +747,7 @@
                 : SCREEN_ORIENTATION_LANDSCAPE;
 
         final ActivityStack stack =
-                new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
+                new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
                         .setDisplay(dc).build();
         final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity();
 
@@ -769,7 +769,7 @@
                 : SCREEN_ORIENTATION_LANDSCAPE;
 
         final ActivityStack stack =
-                new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
+                new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
                         .setDisplay(dc).build();
         final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index 84914bb..ac4c228 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -106,7 +106,7 @@
         mDisplayUniqueId = "test:" + Integer.toString(sNextUniqueId++);
         mTestDisplay = new TestDisplayContent.Builder(mService, 1000, 1500)
                 .setUniqueId(mDisplayUniqueId).build();
-        when(mRootActivityContainer.getDisplayContent(eq(mDisplayUniqueId)))
+        when(mRootWindowContainer.getDisplayContent(eq(mDisplayUniqueId)))
                 .thenReturn(mTestDisplay);
 
         ActivityStack stack = mTestDisplay.createStack(TEST_WINDOWING_MODE,
@@ -180,7 +180,7 @@
     public void testReturnsEmptyDisplayIfDisplayIsNotFound() {
         mTarget.saveTask(mTestTask);
 
-        when(mRootActivityContainer.getDisplayContent(eq(mDisplayUniqueId))).thenReturn(null);
+        when(mRootWindowContainer.getDisplayContent(eq(mDisplayUniqueId))).thenReturn(null);
 
         mTarget.getLaunchParams(mTestTask, null, mResult);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
index ef5b8c5..039ff60 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
@@ -105,7 +105,6 @@
             new DexmakerShareClassLoaderRule();
 
     @Mock private ActivityStackSupervisor mSupervisor;
-    @Mock private RootActivityContainer mRootActivityContainer;
     @Mock private RootWindowContainer mRootWindowContainer;
     @Mock private IDevicePolicyManager mDevicePolicyManager;
     @Mock private IStatusBarService mStatusBarService;
@@ -134,7 +133,7 @@
         }
 
         mSupervisor.mRecentTasks = mRecentTasks;
-        mSupervisor.mRootActivityContainer = mRootActivityContainer;
+        mSupervisor.mRootWindowContainer = mRootWindowContainer;
 
         mLockTaskController = new LockTaskController(mContext, mSupervisor,
                 new ImmediatelyExecuteHandler());
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index eaf4aa3..55a139a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -45,7 +45,6 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -117,7 +116,7 @@
     public void setUp() throws Exception {
         mTaskPersister = new TestTaskPersister(mContext.getFilesDir());
         spyOn(mTaskPersister);
-        mDisplay = mRootActivityContainer.getDisplayContent(DEFAULT_DISPLAY);
+        mDisplay = mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY);
 
         // Set the recent tasks we should use for testing in this class.
         mRecentTasks = new TestRecentTasks(mService, mTaskPersister);
@@ -773,7 +772,7 @@
 
         ActivityStack stack = mTasks.get(2).getStack();
         stack.moveToFront("", mTasks.get(2));
-        doReturn(stack).when(mService.mRootActivityContainer).getTopDisplayFocusedStack();
+        doReturn(stack).when(mService.mRootWindowContainer).getTopDisplayFocusedStack();
 
         // Simulate the reset from the timeout
         mRecentTasks.resetFreezeTaskListReorderingOnTimeout();
@@ -1327,7 +1326,7 @@
 
         @Override
         void getTasks(int maxNum, List<RunningTaskInfo> list, int ignoreActivityType,
-                int ignoreWindowingMode, RootActivityContainer root,
+                int ignoreWindowingMode, RootWindowContainer root,
                 int callingUid, boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
             mLastAllowed = allowed;
             super.getTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, root,
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 186f001..7e42c62 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -88,7 +88,7 @@
 
     @Test
     public void testRecentsActivityVisiblility() {
-        DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         ActivityStack recentsStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_RECENTS, true /* onTop */);
         ActivityRecord recentActivity = new ActivityBuilder(mService)
@@ -99,7 +99,7 @@
         ActivityRecord topActivity = new ActivityBuilder(mService).setCreateTask(true).build();
         topActivity.getActivityStack().moveToFront("testRecentsActivityVisiblility");
 
-        doCallRealMethod().when(mRootActivityContainer).ensureActivitiesVisible(
+        doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
                 any() /* starting */, anyInt() /* configChanges */,
                 anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
 
@@ -116,7 +116,7 @@
 
     @Test
     public void testPreloadRecentsActivity() {
-        final DisplayContent defaultDisplay = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent defaultDisplay = mRootWindowContainer.getDefaultDisplay();
         final ActivityStack homeStack =
                 defaultDisplay.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
         defaultDisplay.positionStackAtTop(homeStack, false /* includingParents */);
@@ -149,7 +149,7 @@
         mService.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
                 null /* recentsAnimationRunner */);
 
-        DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         ActivityStack recentsStack = display.getStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_RECENTS);
         assertThat(recentsStack).isNotNull();
@@ -178,7 +178,7 @@
     @Test
     public void testRestartRecentsActivity() throws Exception {
         // Have a recents activity that is not attached to its process (ActivityRecord.app = null).
-        DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         ActivityStack recentsStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_RECENTS, true /* onTop */);
         ActivityRecord recentActivity = new ActivityBuilder(mService).setComponent(
@@ -190,7 +190,7 @@
         new ActivityBuilder(mService).setCreateTask(true).build().getActivityStack().moveToFront(
                 "testRestartRecentsActivity");
 
-        doCallRealMethod().when(mRootActivityContainer).ensureActivitiesVisible(
+        doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
                 any() /* starting */, anyInt() /* configChanges */,
                 anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
         doReturn(app).when(mService).getProcessController(eq(recentActivity.processName), anyInt());
@@ -200,14 +200,14 @@
         startRecentsActivity();
 
         // Recents activity must be restarted, but not be resumed while running recents animation.
-        verify(mRootActivityContainer.mStackSupervisor).startSpecificActivity(
+        verify(mRootWindowContainer.mStackSupervisor).startSpecificActivity(
                 eq(recentActivity), eq(false), anyBoolean());
         assertThat(recentActivity.getState()).isEqualTo(PAUSED);
     }
 
     @Test
     public void testSetLaunchTaskBehindOfTargetActivity() {
-        DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         display.mDisplayContent.mBoundsAnimationController = mock(BoundsAnimationController.class);
         ActivityStack homeStack = display.getHomeStack();
         // Assume the home activity support recents.
@@ -253,7 +253,7 @@
 
     @Test
     public void testCancelAnimationOnVisibleStackOrderChange() {
-        DisplayContent display = mService.mRootActivityContainer.getDefaultDisplay();
+        DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay();
         display.mDisplayContent.mBoundsAnimationController = mock(BoundsAnimationController.class);
         ActivityStack fullscreenStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_STANDARD, true /* onTop */);
@@ -299,7 +299,7 @@
 
     @Test
     public void testKeepAnimationOnHiddenStackOrderChange() {
-        DisplayContent display = mService.mRootActivityContainer.getDefaultDisplay();
+        DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay();
         ActivityStack fullscreenStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_STANDARD, true /* onTop */);
         new ActivityBuilder(mService)
@@ -335,7 +335,7 @@
 
     @Test
     public void testMultipleUserHomeActivity_findUserHomeTask() {
-        DisplayContent display = mService.mRootActivityContainer.getDefaultDisplay();
+        DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay();
         ActivityStack homeStack = display.getStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME);
         ActivityRecord otherUserHomeActivity = new ActivityBuilder(mService)
                 .setStack(homeStack)
@@ -353,7 +353,7 @@
                 .build();
 
         doReturn(TEST_USER_ID).when(mService).getCurrentUserId();
-        doCallRealMethod().when(mRootActivityContainer).ensureActivitiesVisible(
+        doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
                 any() /* starting */, anyInt() /* configChanges */,
                 anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 05242e2..9f092835 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -37,7 +37,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
-import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
+import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -77,7 +77,7 @@
 import java.util.function.Consumer;
 
 /**
- * Tests for the {@link RootActivityContainer} class.
+ * Tests for the {@link RootWindowContainer} class.
  *
  * Build/Install/Run:
  *  atest WmTests:RootActivityContainerTests
@@ -90,7 +90,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mFullscreenStack = mRootActivityContainer.getDefaultDisplay().createStack(
+        mFullscreenStack = mRootWindowContainer.getDefaultDisplay().createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         doNothing().when(mService).updateSleepIfNeededLocked();
     }
@@ -101,8 +101,8 @@
      */
     @Test
     public void testRestoringInvalidTask() {
-        mRootActivityContainer.getDefaultDisplay().removeAllTasks();
-        Task task = mRootActivityContainer.anyTaskForId(0 /*taskId*/,
+        mRootWindowContainer.getDefaultDisplay().removeAllTasks();
+        Task task = mRootWindowContainer.anyTaskForId(0 /*taskId*/,
                 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, null, false /* onTop */);
         assertNull(task);
     }
@@ -127,7 +127,7 @@
 
         // Move first activity to pinned stack.
         final Rect sourceBounds = new Rect();
-        mRootActivityContainer.moveActivityToPinnedStack(firstActivity, sourceBounds,
+        mRootWindowContainer.moveActivityToPinnedStack(firstActivity, sourceBounds,
                 0f /*aspectRatio*/, "initialMove");
 
         final DisplayContent display = mFullscreenStack.getDisplay();
@@ -137,7 +137,7 @@
         ensureStackPlacement(mFullscreenStack, secondActivity);
 
         // Move second activity to pinned stack.
-        mRootActivityContainer.moveActivityToPinnedStack(secondActivity, sourceBounds,
+        mRootWindowContainer.moveActivityToPinnedStack(secondActivity, sourceBounds,
                 0f /*aspectRatio*/, "secondMove");
 
         // Need to get stacks again as a new instance might have been created.
@@ -168,9 +168,9 @@
 
     @Test
     public void testApplySleepTokens() {
-        final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         final KeyguardController keyguard = mSupervisor.getKeyguardController();
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer)
                 .setCreateActivity(false)
                 .setDisplay(display)
                 .setOnTop(false)
@@ -216,7 +216,7 @@
 
         doReturn(isFocusedStack).when(stack).isFocusedStackOnDisplay();
         doReturn(isFocusedStack ? stack : null).when(display).getFocusedStack();
-        mRootActivityContainer.applySleepTokens(true);
+        mRootWindowContainer.applySleepTokens(true);
         verify(stack, times(expectWakeFromSleep ? 1 : 0)).awakeFromSleepingLocked();
         verify(stack, times(expectResumeTopActivity ? 1 : 0)).resumeTopActivityUncheckedLocked(
                 null /* target */, null /* targetOptions */);
@@ -227,9 +227,9 @@
      */
     @Test
     public void testRemovingStackOnAppCrash() {
-        final DisplayContent defaultDisplay = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent defaultDisplay = mRootWindowContainer.getDefaultDisplay();
         final int originalStackCount = defaultDisplay.getStackCount();
-        final ActivityStack stack = mRootActivityContainer.getDefaultDisplay().createStack(
+        final ActivityStack stack = mRootWindowContainer.getDefaultDisplay().createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
         final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
                 .setStack(stack).build();
@@ -238,7 +238,7 @@
 
         // Let's pretend that the app has crashed.
         firstActivity.app.setThread(null);
-        mRootActivityContainer.finishTopCrashedActivities(firstActivity.app, "test");
+        mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test");
 
         // Verify that the stack was removed.
         assertEquals(originalStackCount, defaultDisplay.getStackCount());
@@ -246,22 +246,22 @@
 
     @Test
     public void testFocusability() {
-        final ActivityStack stack = mRootActivityContainer.getDefaultDisplay().createStack(
+        final ActivityStack stack = mRootWindowContainer.getDefaultDisplay().createStack(
                 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
                 .setStack(stack).build();
 
         // Under split screen primary we should be focusable when not minimized
-        mRootActivityContainer.setDockedStackMinimized(false);
+        mRootWindowContainer.setDockedStackMinimized(false);
         assertTrue(stack.isFocusable());
         assertTrue(activity.isFocusable());
 
         // Under split screen primary we should not be focusable when minimized
-        mRootActivityContainer.setDockedStackMinimized(true);
+        mRootWindowContainer.setDockedStackMinimized(true);
         assertFalse(stack.isFocusable());
         assertFalse(activity.isFocusable());
 
-        final ActivityStack pinnedStack = mRootActivityContainer.getDefaultDisplay().createStack(
+        final ActivityStack pinnedStack = mRootWindowContainer.getDefaultDisplay().createStack(
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         final ActivityRecord pinnedActivity = new ActivityBuilder(mService).setCreateTask(true)
                 .setStack(pinnedStack).build();
@@ -290,7 +290,7 @@
     @Test
     public void testSplitScreenPrimaryChosenWhenTopActivityLaunchedToSecondary() {
         // Create primary split-screen stack with a task and an activity.
-        final ActivityStack primaryStack = mRootActivityContainer.getDefaultDisplay()
+        final ActivityStack primaryStack = mRootWindowContainer.getDefaultDisplay()
                 .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
                         true /* onTop */);
         final Task task = new TaskBuilder(mSupervisor).setStack(primaryStack).build();
@@ -301,7 +301,7 @@
         final ActivityOptions options = ActivityOptions.makeBasic();
         options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
         final ActivityStack result =
-                mRootActivityContainer.getLaunchStack(r, options, task, true /* onTop */);
+                mRootWindowContainer.getLaunchStack(r, options, task, true /* onTop */);
 
         // Assert that the primary stack is returned.
         assertEquals(primaryStack, result);
@@ -317,7 +317,7 @@
         final Rect stackSize = new Rect(0, 0, 300, 300);
 
         // Create primary split-screen stack with a task.
-        final ActivityStack primaryStack = new StackBuilder(mRootActivityContainer)
+        final ActivityStack primaryStack = new StackBuilder(mRootWindowContainer)
                 .setActivityType(ACTIVITY_TYPE_STANDARD)
                 .setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)
                 .setOnTop(true)
@@ -338,14 +338,14 @@
     @Test
     public void testFindTaskToMoveToFrontWhenRecentsOnTop() {
         // Create stack/task on default display.
-        final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
-        final ActivityStack targetStack = new StackBuilder(mRootActivityContainer)
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
+        final ActivityStack targetStack = new StackBuilder(mRootWindowContainer)
                 .setOnTop(false)
                 .build();
         final Task targetTask = targetStack.getBottomMostTask();
 
         // Create Recents on top of the display.
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer).setActivityType(
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer).setActivityType(
                 ACTIVITY_TYPE_RECENTS).build();
 
         final String reason = "findTaskToMoveToFront";
@@ -362,7 +362,7 @@
     @Test
     public void testFindTaskToMoveToFrontWhenRecentsOnOtherDisplay() {
         // Create stack/task on default display.
-        final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         final ActivityStack targetStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_STANDARD, false /* onTop */);
         final Task targetTask = new TaskBuilder(mSupervisor).setStack(targetStack).build();
@@ -389,7 +389,7 @@
     @Test
     public void testResumeActivityWhenNonTopmostStackIsTopFocused() {
         // Create a stack at bottom.
-        final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         final ActivityStack targetStack = spy(display.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_STANDARD, false /* onTop */));
         final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
@@ -399,10 +399,10 @@
         // Assume the stack is not at the topmost position (e.g. behind always-on-top stacks) but it
         // is the current top focused stack.
         assertFalse(targetStack.isTopStackOnDisplay());
-        doReturn(targetStack).when(mRootActivityContainer).getTopDisplayFocusedStack();
+        doReturn(targetStack).when(mRootWindowContainer).getTopDisplayFocusedStack();
 
         // Use the stack as target to resume.
-        mRootActivityContainer.resumeFocusedStacksTopActivities(
+        mRootWindowContainer.resumeFocusedStacksTopActivities(
                 targetStack, activity, null /* targetOptions */);
 
         // Verify the target stack should resume its activity.
@@ -417,20 +417,20 @@
     @Test
     public void testResumeFocusedStacksStartsHomeActivity_NoActivities() {
         mFullscreenStack.removeIfPossible();
-        mService.mRootActivityContainer.getDisplayContent(DEFAULT_DISPLAY).getHomeStack()
+        mService.mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY).getHomeStack()
                 .removeIfPossible();
-        mService.mRootActivityContainer.getDisplayContent(DEFAULT_DISPLAY)
+        mService.mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY)
                 .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
 
-        doReturn(true).when(mRootActivityContainer).resumeHomeActivity(any(), any(), anyInt());
+        doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), anyInt());
 
         mService.setBooted(true);
 
         // Trigger resume on all displays
-        mRootActivityContainer.resumeFocusedStacksTopActivities();
+        mRootWindowContainer.resumeFocusedStacksTopActivities();
 
         // Verify that home activity was started on the default display
-        verify(mRootActivityContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
+        verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
     }
 
     /**
@@ -440,9 +440,9 @@
     @Test
     public void testResumeFocusedStacksStartsHomeActivity_ActivityOnSecondaryScreen() {
         mFullscreenStack.removeIfPossible();
-        mService.mRootActivityContainer.getDisplayContent(DEFAULT_DISPLAY).getHomeStack()
+        mService.mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY).getHomeStack()
                 .removeIfPossible();
-        mService.mRootActivityContainer.getDisplayContent(DEFAULT_DISPLAY)
+        mService.mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY)
                 .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
 
         // Create an activity on secondary display.
@@ -453,15 +453,15 @@
         final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
         new ActivityBuilder(mService).setTask(task).build();
 
-        doReturn(true).when(mRootActivityContainer).resumeHomeActivity(any(), any(), anyInt());
+        doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), anyInt());
 
         mService.setBooted(true);
 
         // Trigger resume on all displays
-        mRootActivityContainer.resumeFocusedStacksTopActivities();
+        mRootWindowContainer.resumeFocusedStacksTopActivities();
 
         // Verify that home activity was started on the default display
-        verify(mRootActivityContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
+        verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
     }
 
     /**
@@ -471,7 +471,7 @@
     @Test
     public void testResumeActivityLingeringTransition() {
         // Create a stack at top.
-        final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         final ActivityStack targetStack = spy(display.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_STANDARD, false /* onTop */));
         final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
@@ -482,7 +482,7 @@
         assertTrue(targetStack.isTopStackOnDisplay());
 
         // Use the stack as target to resume.
-        mRootActivityContainer.resumeFocusedStacksTopActivities();
+        mRootWindowContainer.resumeFocusedStacksTopActivities();
 
         // Verify the lingering app transition is being executed because it's already resumed
         verify(targetStack, times(1)).executeAppTransition(any());
@@ -491,7 +491,7 @@
     @Test
     public void testResumeActivityLingeringTransition_notExecuted() {
         // Create a stack at bottom.
-        final DisplayContent display = mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
         final ActivityStack targetStack = spy(display.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_STANDARD, false /* onTop */));
         final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
@@ -501,10 +501,10 @@
 
         // Assume the stack is at the topmost position
         assertFalse(targetStack.isTopStackOnDisplay());
-        doReturn(targetStack).when(mRootActivityContainer).getTopDisplayFocusedStack();
+        doReturn(targetStack).when(mRootWindowContainer).getTopDisplayFocusedStack();
 
         // Use the stack as target to resume.
-        mRootActivityContainer.resumeFocusedStacksTopActivities();
+        mRootWindowContainer.resumeFocusedStacksTopActivities();
 
         // Verify the lingering app transition is being executed because it's already resumed
         verify(targetStack, never()).executeAppTransition(any());
@@ -523,14 +523,14 @@
                 new TestDisplayContent.Builder(mService, 1000, 1500)
                         .setSystemDecorations(true).build();
 
-        doReturn(true).when(mRootActivityContainer)
+        doReturn(true).when(mRootWindowContainer)
                 .ensureVisibilityAndConfig(any(), anyInt(), anyBoolean(), anyBoolean());
-        doReturn(true).when(mRootActivityContainer).canStartHomeOnDisplay(
+        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplay(
                 any(), anyInt(), anyBoolean());
 
-        mRootActivityContainer.startHomeOnAllDisplays(0, "testStartHome");
+        mRootWindowContainer.startHomeOnAllDisplays(0, "testStartHome");
 
-        assertTrue(mRootActivityContainer.getDefaultDisplay().getTopStack().isActivityTypeHome());
+        assertTrue(mRootWindowContainer.getDefaultDisplay().getTopStack().isActivityTypeHome());
         assertNotNull(secondDisplay.getTopStack());
         assertTrue(secondDisplay.getTopStack().isActivityTypeHome());
     }
@@ -546,8 +546,8 @@
         try {
             mService.mAmInternal.setBooting(false);
             mService.mAmInternal.setBooted(false);
-            mRootActivityContainer.onDisplayAdded(displayId);
-            verify(mRootActivityContainer, never()).startHomeOnDisplay(anyInt(), any(), anyInt());
+            mRootWindowContainer.onDisplayAdded(displayId);
+            verify(mRootWindowContainer, never()).startHomeOnDisplay(anyInt(), any(), anyInt());
         } finally {
             mService.mAmInternal.setBooting(isBooting);
             mService.mAmInternal.setBooted(isBooted);
@@ -566,17 +566,17 @@
 
         // Can not start home if we don't want to start home while home is being instrumented.
         doReturn(true).when(app).isInstrumenting();
-        assertFalse(mRootActivityContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
+        assertFalse(mRootWindowContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
                 false /* allowInstrumenting*/));
 
         // Can start home for other cases.
-        assertTrue(mRootActivityContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
+        assertTrue(mRootWindowContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
                 true /* allowInstrumenting*/));
 
         doReturn(false).when(app).isInstrumenting();
-        assertTrue(mRootActivityContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
+        assertTrue(mRootWindowContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
                 false /* allowInstrumenting*/));
-        assertTrue(mRootActivityContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
+        assertTrue(mRootWindowContainer.canStartHomeOnDisplay(info, DEFAULT_DISPLAY,
                 true /* allowInstrumenting*/));
     }
 
@@ -591,17 +591,17 @@
                         .setSystemDecorations(true).build();
 
         // Use invalid user id to let StorageManager.isUserKeyUnlocked() return false.
-        final int currentUser = mRootActivityContainer.mCurrentUser;
-        mRootActivityContainer.mCurrentUser = -1;
+        final int currentUser = mRootWindowContainer.mCurrentUser;
+        mRootWindowContainer.mCurrentUser = -1;
 
-        mRootActivityContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
+        mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
                 secondDisplay.mDisplayId, true /* allowInstrumenting */, true /* fromHomeKey */);
 
         try {
-            verify(mRootActivityContainer, never()).resolveSecondaryHomeActivity(anyInt(),
+            verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(),
                     anyInt());
         } finally {
-            mRootActivityContainer.mCurrentUser = currentUser;
+            mRootWindowContainer.mCurrentUser = currentUser;
         }
     }
 
@@ -616,10 +616,10 @@
                 new TestDisplayContent.Builder(mService, 1000, 1500)
                         .setSystemDecorations(false).build();
 
-        mRootActivityContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
+        mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
                 secondDisplay.mDisplayId, true /* allowInstrumenting */, true /* fromHomeKey */);
 
-        verify(mRootActivityContainer, never()).resolveSecondaryHomeActivity(anyInt(), anyInt());
+        verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(), anyInt());
     }
 
     /**
@@ -632,10 +632,10 @@
         info.applicationInfo = new ApplicationInfo();
         info.applicationInfo.packageName = "android";
         info.name = ResolverActivity.class.getName();
-        doReturn(info).when(mRootActivityContainer).resolveHomeActivity(anyInt(), any());
+        doReturn(info).when(mRootWindowContainer).resolveHomeActivity(anyInt(), any());
 
-        mRootActivityContainer.startHomeOnDisplay(0 /* userId */, "test", DEFAULT_DISPLAY);
-        final ActivityRecord resolverActivity = mRootActivityContainer.topRunningActivity();
+        mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "test", DEFAULT_DISPLAY);
+        final ActivityRecord resolverActivity = mRootWindowContainer.topRunningActivity();
 
         assertEquals(info, resolverActivity.info);
         assertEquals(ACTIVITY_TYPE_STANDARD, resolverActivity.getActivityStack().getActivityType());
@@ -649,7 +649,7 @@
         final Intent defaultHomeIntent = mService.getHomeIntent();
         final ActivityInfo aInfoDefault = new ActivityInfo();
         aInfoDefault.name = ResolverActivity.class.getName();
-        doReturn(aInfoDefault).when(mRootActivityContainer).resolveHomeActivity(anyInt(),
+        doReturn(aInfoDefault).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
                 refEq(defaultHomeIntent));
 
         final String secondaryHomeComponent = mService.mContext.getResources().getString(
@@ -658,11 +658,11 @@
         final Intent secondaryHomeIntent = mService.getSecondaryHomeIntent(null);
         final ActivityInfo aInfoSecondary = new ActivityInfo();
         aInfoSecondary.name = comp.getClassName();
-        doReturn(aInfoSecondary).when(mRootActivityContainer).resolveHomeActivity(anyInt(),
+        doReturn(aInfoSecondary).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
                 refEq(secondaryHomeIntent));
 
         // Should fallback to secondary home if default home not set.
-        final Pair<ActivityInfo, Intent> resolvedInfo = mRootActivityContainer
+        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
                 .resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
 
         assertEquals(comp.getClassName(), resolvedInfo.first.name);
@@ -692,14 +692,14 @@
             aInfoSecondary.name = secondaryComp.getClassName();
             aInfoSecondary.applicationInfo = new ApplicationInfo();
             aInfoSecondary.applicationInfo.packageName = secondaryComp.getPackageName();
-            doReturn(aInfoSecondary).when(mRootActivityContainer).resolveHomeActivity(anyInt(),
+            doReturn(aInfoSecondary).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
                     refEq(secondaryHomeIntent));
             final Intent homeIntent = mService.getHomeIntent();
             final ActivityInfo aInfoDefault = new ActivityInfo();
             aInfoDefault.name = "fakeHomeActivity";
             aInfoDefault.applicationInfo = new ApplicationInfo();
             aInfoDefault.applicationInfo.packageName = "fakeHomePackage";
-            doReturn(aInfoDefault).when(mRootActivityContainer).resolveHomeActivity(anyInt(),
+            doReturn(aInfoDefault).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
                     refEq(homeIntent));
             // Let resolveActivities call to validate both main launcher and second launcher so that
             // resolveActivities call does not work as enabler for secondary.
@@ -709,7 +709,7 @@
             resolveInfo1.activityInfo.name = aInfoDefault.name;
             resolveInfo1.activityInfo.applicationInfo = aInfoDefault.applicationInfo;
             resolutions1.add(resolveInfo1);
-            doReturn(resolutions1).when(mRootActivityContainer).resolveActivities(anyInt(),
+            doReturn(resolutions1).when(mRootWindowContainer).resolveActivities(anyInt(),
                     refEq(homeIntent));
             final List<ResolveInfo> resolutions2 = new ArrayList<>();
             final ResolveInfo resolveInfo2 = new ResolveInfo();
@@ -717,13 +717,13 @@
             resolveInfo2.activityInfo.name = aInfoSecondary.name;
             resolveInfo2.activityInfo.applicationInfo = aInfoSecondary.applicationInfo;
             resolutions2.add(resolveInfo2);
-            doReturn(resolutions2).when(mRootActivityContainer).resolveActivities(anyInt(),
+            doReturn(resolutions2).when(mRootWindowContainer).resolveActivities(anyInt(),
                     refEq(secondaryHomeIntent));
-            doReturn(true).when(mRootActivityContainer).canStartHomeOnDisplay(
+            doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplay(
                     any(), anyInt(), anyBoolean());
 
             // Run the test
-            final Pair<ActivityInfo, Intent> resolvedInfo = mRootActivityContainer
+            final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
                     .resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
             assertEquals(secondaryComp.getClassName(), resolvedInfo.first.name);
             assertEquals(secondaryComp.getPackageName(),
@@ -744,7 +744,7 @@
         mockResolveHomeActivity();
 
         final List<ResolveInfo> resolutions = new ArrayList<>();
-        doReturn(resolutions).when(mRootActivityContainer).resolveActivities(anyInt(), any());
+        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any());
 
         final String secondaryHomeComponent = mService.mContext.getResources().getString(
                 com.android.internal.R.string.config_secondaryHomeComponent);
@@ -752,12 +752,12 @@
         final Intent secondaryHomeIntent = mService.getSecondaryHomeIntent(null);
         final ActivityInfo aInfoSecondary = new ActivityInfo();
         aInfoSecondary.name = comp.getClassName();
-        doReturn(aInfoSecondary).when(mRootActivityContainer).resolveHomeActivity(anyInt(),
+        doReturn(aInfoSecondary).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
                 refEq(secondaryHomeIntent));
 
         // Should fallback to secondary home if selected default home not support secondary displays
         // or there is no matched activity in the same package as selected default home.
-        final Pair<ActivityInfo, Intent> resolvedInfo = mRootActivityContainer
+        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
                 .resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
 
         assertEquals(comp.getClassName(), resolvedInfo.first.name);
@@ -780,13 +780,13 @@
         infoFake2.activityInfo = aInfoDefault;
         resolutions.add(infoFake1);
         resolutions.add(infoFake2);
-        doReturn(resolutions).when(mRootActivityContainer).resolveActivities(anyInt(), any());
+        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any());
 
-        doReturn(true).when(mRootActivityContainer).canStartHomeOnDisplay(
+        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplay(
                 any(), anyInt(), anyBoolean());
 
         // Use default home activity if it support secondary displays.
-        final Pair<ActivityInfo, Intent> resolvedInfo = mRootActivityContainer
+        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
                 .resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
 
         assertEquals(aInfoDefault.applicationInfo.packageName,
@@ -814,13 +814,13 @@
         infoFake2.activityInfo.applicationInfo.packageName = "fakePackage2";
         resolutions.add(infoFake1);
         resolutions.add(infoFake2);
-        doReturn(resolutions).when(mRootActivityContainer).resolveActivities(anyInt(), any());
+        doReturn(resolutions).when(mRootWindowContainer).resolveActivities(anyInt(), any());
 
-        doReturn(true).when(mRootActivityContainer).canStartHomeOnDisplay(
+        doReturn(true).when(mRootWindowContainer).canStartHomeOnDisplay(
                 any(), anyInt(), anyBoolean());
 
         // Use the first one of matched activities in the same package as selected default home.
-        final Pair<ActivityInfo, Intent> resolvedInfo = mRootActivityContainer
+        final Pair<ActivityInfo, Intent> resolvedInfo = mRootWindowContainer
                 .resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
 
         assertEquals(infoFake1.activityInfo.applicationInfo.packageName,
@@ -829,7 +829,7 @@
     }
 
     /**
-     * Test that {@link RootActivityContainer#getLaunchStack} with the real caller id will get the
+     * Test that {@link RootWindowContainer#getLaunchStack} with the real caller id will get the
      * expected stack when requesting the activity launch on the secondary display.
      */
     @Test
@@ -850,7 +850,7 @@
         options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
         doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId,
                 300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info);
-        final ActivityStack result = mRootActivityContainer.getLaunchStack(r, options,
+        final ActivityStack result = mRootWindowContainer.getLaunchStack(r, options,
                 null /* task */, true /* onTop */, null, 300 /* test realCallerPid */,
                 300 /* test realCallerUid */);
 
@@ -861,7 +861,7 @@
     }
 
     /**
-     * Mock {@link RootActivityContainer#resolveHomeActivity} for returning consistent activity
+     * Mock {@link RootWindowContainer#resolveHomeActivity} for returning consistent activity
      * info for test cases (the original implementation will resolve from the real package manager).
      */
     private ActivityInfo mockResolveHomeActivity() {
@@ -870,13 +870,13 @@
         aInfoDefault.name = "fakeHomeActivity";
         aInfoDefault.applicationInfo = new ApplicationInfo();
         aInfoDefault.applicationInfo.packageName = "fakeHomePackage";
-        doReturn(aInfoDefault).when(mRootActivityContainer).resolveHomeActivity(anyInt(),
+        doReturn(aInfoDefault).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
                 refEq(homeIntent));
         return aInfoDefault;
     }
 
     /**
-     * Mock {@link RootActivityContainer#resolveSecondaryHomeActivity} for returning consistent
+     * Mock {@link RootWindowContainer#resolveSecondaryHomeActivity} for returning consistent
      * activity info for test cases (the original implementation will resolve from the real package
      * manager).
      */
@@ -887,7 +887,7 @@
         aInfoSecondary.name = "fakeSecondaryHomeActivity";
         aInfoSecondary.applicationInfo = new ApplicationInfo();
         aInfoSecondary.applicationInfo.packageName = "fakeSecondaryHomePackage";
-        doReturn(Pair.create(aInfoSecondary, secondaryHomeIntent)).when(mRootActivityContainer)
+        doReturn(Pair.create(aInfoSecondary, secondaryHomeIntent)).when(mRootWindowContainer)
                 .resolveSecondaryHomeActivity(anyInt(), anyInt());
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index b32cb8b..6272070 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -64,7 +64,7 @@
 
         final int numStacks = 2;
         for (int stackIndex = 0; stackIndex < numStacks; stackIndex++) {
-            final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+            final ActivityStack stack = new StackBuilder(mRootWindowContainer)
                     .setCreateActivity(false)
                     .setDisplay(display)
                     .setOnTop(false)
@@ -82,7 +82,7 @@
         final int numFetchTasks = 5;
         ArrayList<RunningTaskInfo> tasks = new ArrayList<>();
         mRunningTasks.getTasks(5, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED,
-                mRootActivityContainer, -1 /* callingUid */, true /* allowed */,
+                mRootWindowContainer, -1 /* callingUid */, true /* allowed */,
                 true /*crossUser */, PROFILE_IDS);
         assertThat(tasks).hasSize(numFetchTasks);
         for (int i = 0; i < numFetchTasks; i++) {
@@ -93,7 +93,7 @@
         // and does not crash
         tasks.clear();
         mRunningTasks.getTasks(100, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED,
-                mRootActivityContainer, -1 /* callingUid */, true /* allowed */,
+                mRootWindowContainer, -1 /* callingUid */, true /* allowed */,
                 true /* crossUser */, PROFILE_IDS);
         assertThat(tasks).hasSize(numTasks);
         for (int i = 0; i < numTasks; i++) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index be0fd2b..64db897 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -68,7 +68,7 @@
     private ActivityRecord mActivity;
 
     private void setUpApp(DisplayContent display) {
-        mStack = new StackBuilder(mRootActivityContainer).setDisplay(display).build();
+        mStack = new StackBuilder(mRootWindowContainer).setDisplay(display).build();
         mTask = mStack.getBottomMostTask();
         mActivity = mTask.getTopNonFinishingActivity();
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 798c2c5..f90eca3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -271,11 +271,11 @@
         spyOn(mWmService);
         spyOn(mWmService.mRoot);
         // Invoked during {@link ActivityStack} creation.
-        doNothing().when((RootActivityContainer) mWmService.mRoot).updateUIDsPresentOnDisplay();
+        doNothing().when(mWmService.mRoot).updateUIDsPresentOnDisplay();
         // Always keep things awake.
-        doReturn(true).when((RootActivityContainer) mWmService.mRoot).hasAwakeDisplay();
+        doReturn(true).when(mWmService.mRoot).hasAwakeDisplay();
         // Called when moving activity to pinned stack.
-        doNothing().when((RootActivityContainer) mWmService.mRoot).ensureActivitiesVisible(any(),
+        doNothing().when(mWmService.mRoot).ensureActivitiesVisible(any(),
                 anyInt(), anyBoolean(), anyBoolean());
 
         // Setup factory classes to prevent calls to native code.
@@ -293,7 +293,7 @@
         mWmService.getDefaultDisplayContentLocked().reconfigureDisplayLocked();
 
         // Mock default display, and home stack.
-        final DisplayContent display = mAtmService.mRootActivityContainer.getDefaultDisplay();
+        final DisplayContent display = mAtmService.mRootWindowContainer.getDefaultDisplay();
         // Set default display to be in fullscreen mode. Devices with PC feature may start their
         // default display in freeform mode but some of tests in WmTests have implicit assumption on
         // that the default display is in fullscreen mode.
@@ -307,7 +307,7 @@
     private void tearDown() {
         // Unregister display listener from root to avoid issues with subsequent tests.
         mContext.getSystemService(DisplayManager.class)
-                .unregisterDisplayListener(mAtmService.mRootActivityContainer);
+                .unregisterDisplayListener(mAtmService.mRootWindowContainer);
         // The constructor of WindowManagerService registers WindowManagerConstants and
         // HighRefreshRateBlacklist with DeviceConfig. We need to undo that here to avoid
         // leaking mWmService.
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 5aa41eb..a3446d1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -1047,10 +1047,10 @@
     @Test
     public void testAdjustBoundsToFitNewDisplay_LargerThanDisplay_RTL() {
         final Configuration overrideConfig =
-                mRootActivityContainer.getRequestedOverrideConfiguration();
+                mRootWindowContainer.getRequestedOverrideConfiguration();
         // Egyptian Arabic is a RTL language.
         overrideConfig.setLayoutDirection(new Locale("ar", "EG"));
-        mRootActivityContainer.onRequestedOverrideConfigurationChanged(overrideConfig);
+        mRootWindowContainer.onRequestedOverrideConfigurationChanged(overrideConfig);
 
         final TestDisplayContent freeformDisplay = createNewDisplayContent(
                 WINDOWING_MODE_FREEFORM);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index de6d752..9f2bfa7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -193,7 +193,7 @@
     @FlakyTest(bugId = 137879065)
     public void testFitWithinBounds() {
         final Rect parentBounds = new Rect(10, 10, 200, 200);
-        DisplayContent display = mService.mRootActivityContainer.getDefaultDisplay();
+        DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay();
         ActivityStack stack = display.createStack(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
                 true /* onTop */);
         Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
@@ -232,8 +232,8 @@
     @Test
     @FlakyTest(bugId = 137879065)
     public void testBoundsOnModeChangeFreeformToFullscreen() {
-        DisplayContent display = mService.mRootActivityContainer.getDefaultDisplay();
-        ActivityStack stack = new StackBuilder(mRootActivityContainer).setDisplay(display)
+        DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay();
+        ActivityStack stack = new StackBuilder(mRootWindowContainer).setDisplay(display)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
         Task task = stack.getBottomMostTask();
         task.getRootActivity().setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
@@ -267,14 +267,14 @@
         final Rect fullScreenBoundsPort = new Rect(0, 0, 1080, 1920);
         DisplayContent display = new TestDisplayContent.Builder(
                 mService, fullScreenBounds.width(), fullScreenBounds.height()).build();
-        assertTrue(mRootActivityContainer.getDisplayContent(display.mDisplayId) != null);
+        assertTrue(mRootWindowContainer.getDisplayContent(display.mDisplayId) != null);
         // Fix the display orientation to landscape which is the natural rotation (0) for the test
         // display.
         final DisplayRotation dr = display.mDisplayContent.getDisplayRotation();
         dr.setFixedToUserRotation(FIXED_TO_USER_ROTATION_ENABLED);
         dr.setUserRotation(USER_ROTATION_FREE, ROTATION_0);
 
-        ActivityStack stack = new StackBuilder(mRootActivityContainer)
+        ActivityStack stack = new StackBuilder(mRootWindowContainer)
                 .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
         Task task = stack.getBottomMostTask();
         ActivityRecord root = task.getTopNonFinishingActivity();
@@ -335,7 +335,7 @@
                 Configuration.ORIENTATION_LANDSCAPE;
         display.onRequestedOverrideConfigurationChanged(
                 display.getRequestedOverrideConfiguration());
-        ActivityStack stack = new StackBuilder(mRootActivityContainer)
+        ActivityStack stack = new StackBuilder(mRootWindowContainer)
                 .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
         Task task = stack.getBottomMostTask();
         ActivityRecord root = task.getTopNonFinishingActivity();
@@ -429,7 +429,7 @@
 
     @Test
     public void testInsetDisregardedWhenFreeformOverlapsNavBar() {
-        DisplayContent display = mService.mRootActivityContainer.getDefaultDisplay();
+        DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay();
         ActivityStack stack = display.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
                 true /* onTop */);
         DisplayInfo displayInfo = new DisplayInfo();
@@ -857,14 +857,14 @@
     }
 
     private Task getTestTask() {
-        final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
+        final ActivityStack stack = new StackBuilder(mRootWindowContainer).build();
         return stack.getBottomMostTask();
     }
 
     private void testStackBoundsConfiguration(int windowingMode, Rect parentBounds, Rect bounds,
             Rect expectedConfigBounds) {
 
-        DisplayContent display = mService.mRootActivityContainer.getDefaultDisplay();
+        DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay();
         ActivityStack stack = display.createStack(windowingMode, ACTIVITY_TYPE_STANDARD,
                 true /* onTop */);
         Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index 4ed1b35..e5121b9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -39,7 +39,7 @@
     private final ActivityStackSupervisor mSupervisor;
 
     private TestDisplayContent(ActivityStackSupervisor supervisor, Display display) {
-        super(display, supervisor.mService.mRootActivityContainer);
+        super(display, supervisor.mService.mRootWindowContainer);
         // Normally this comes from display-properties as exposed by WM. Without that, just
         // hard-code to FULLSCREEN for tests.
         setWindowingMode(WINDOWING_MODE_FULLSCREEN);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 6108db3..421a4582 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -87,7 +87,7 @@
         // Unregistration still work even if the display was removed.
         mWpc.registerDisplayConfigurationListenerLocked(testDisplayContent1);
         assertEquals(testDisplayContent1.mDisplayId, mWpc.getDisplayId());
-        mRootActivityContainer.removeChild(testDisplayContent1);
+        mRootWindowContainer.removeChild(testDisplayContent1);
         mWpc.unregisterDisplayConfigurationListenerLocked();
         assertEquals(INVALID_DISPLAY, mWpc.getDisplayId());
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index f89e700..ea88315 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -320,7 +320,7 @@
     ActivityStack createTaskStackOnDisplay(int windowingMode, int activityType, DisplayContent dc) {
         synchronized (mWm.mGlobalLock) {
             return new ActivityTestsBase.StackBuilder(
-                    dc.mWmService.mAtmService.mRootActivityContainer)
+                    dc.mWmService.mAtmService.mRootWindowContainer)
                     .setDisplay(dc)
                     .setWindowingMode(windowingMode)
                     .setActivityType(activityType)
@@ -379,6 +379,6 @@
 
     /** Sets the default minimum task size to 1 so that tests can use small task sizes */
     void removeGlobalMinSizeRestriction() {
-        mWm.mAtmService.mRootActivityContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
+        mWm.mAtmService.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
     }
 }
