Unify RootActivityContainer and RootWindowContainer (80/n)

Bug: 80414790
Test: Existing tests pass
Change-Id: I9677de2ea5d50337f6f2902545ff993b5fb9c496
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 331386f..0864c9c 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -825,13 +825,7 @@
         mAppWarnings = createAppWarnings(mUiContext, mH, mUiHandler, systemDir);
         mCompatModePackages = new CompatModePackages(this, systemDir, mH);
         mPendingIntentController = intentController;
-
-        mTempConfig.setToDefaults();
-        mTempConfig.setLocales(LocaleList.getDefault());
-        mConfigurationSeq = mTempConfig.seq = 1;
         mStackSupervisor = createStackSupervisor();
-        mRootActivityContainer = new RootActivityContainer(this);
-        mRootActivityContainer.onConfigurationChanged(mTempConfig);
 
         mTaskChangeNotificationController =
                 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
@@ -868,6 +862,12 @@
     public void setWindowManager(WindowManagerService wm) {
         synchronized (mGlobalLock) {
             mWindowManager = wm;
+            // TODO(merge-root): Remove cast
+            mRootActivityContainer = (RootActivityContainer) wm.mRoot;
+            mTempConfig.setToDefaults();
+            mTempConfig.setLocales(LocaleList.getDefault());
+            mConfigurationSeq = mTempConfig.seq = 1;
+            mRootActivityContainer.onConfigurationChanged(mTempConfig);
             mLockTaskController.setWindowManager(wm);
             mStackSupervisor.setWindowManager(wm);
             mRootActivityContainer.setWindowManager(wm);
@@ -5216,7 +5216,11 @@
      * also corresponds to the merged configuration of the default display.
      */
     Configuration getGlobalConfiguration() {
-        return mRootActivityContainer.getConfiguration();
+        // Return default configuration before mRootActivityContainer initialized, which happens
+        // while initializing process record for system, see {@link
+        // ActivityManagerService#setSystemProcess}.
+        return mRootActivityContainer != null ? mRootActivityContainer.getConfiguration()
+                : new Configuration();
     }
 
     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
@@ -7277,6 +7281,11 @@
         @Override
         public WindowProcessController getTopApp() {
             synchronized (mGlobalLockWithoutBoost) {
+                if (mRootActivityContainer == null) {
+                    // Return null if mRootActivityContainer not yet initialize, while update
+                    // oomadj after AMS created.
+                    return null;
+                }
                 final ActivityRecord top = mRootActivityContainer.getTopResumedActivity();
                 return top != null ? top.app : null;
             }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5a5c102..391bfbe 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1038,7 +1038,7 @@
         onDisplayChanged(this);
 
         // Add itself as a child to the root container.
-        mWmService.mRoot.addChild(this, null);
+        mWmService.mRoot.addChild(this, POSITION_BOTTOM);
 
         // TODO(b/62541591): evaluate whether this is the best spot to declare the
         // {@link DisplayContent} ready for use.
@@ -6410,7 +6410,6 @@
             stack.removeIfPossible();
         } else if (getTopStack() == null) {
             removeIfPossible();
-            mRootActivityContainer.removeChild(this);
             mRootActivityContainer.mStackSupervisor
                     .getKeyguardController().onDisplayRemoved(mDisplayId);
         }
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 7a72b43..0443c40 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -653,7 +653,7 @@
             taskChanged = true;
         }
 
-        mSupervisor.mRootActivityContainer.mRootWindowContainer.forAllTasks(Task::setLockTaskAuth);
+        mSupervisor.mRootActivityContainer.forAllTasks(Task::setLockTaskAuth);
 
         final ActivityRecord r = mSupervisor.mRootActivityContainer.topRunningActivity();
         final Task task = (r != null) ? r.getTask() : null;
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index f778e4d..4ac918c 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -36,13 +36,13 @@
 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.CONFIGURATION_CONTAINER;
 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;
@@ -135,7 +135,7 @@
  * 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 ConfigurationContainer
+class RootActivityContainer extends RootWindowContainer
         implements DisplayManager.DisplayListener {
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "RootActivityContainer" : TAG_ATM;
@@ -168,14 +168,6 @@
     WindowManagerService mWindowManager;
     DisplayManager mDisplayManager;
     private DisplayManagerInternal mDisplayManagerInternal;
-    // TODO(root-unify): Remove after object merge with RootWindowContainer.
-    RootWindowContainer mRootWindowContainer;
-
-    /**
-     * List of displays which contain activities, sorted by z-order.
-     * The last entry in the list is the topmost.
-     */
-    private final ArrayList<DisplayContent> mDisplayContents = new ArrayList<>();
 
     /** Reference to default display so we can quickly look it up. */
     private DisplayContent mDefaultDisplay;
@@ -337,7 +329,8 @@
         }
     }
 
-    RootActivityContainer(ActivityTaskManagerService service) {
+    RootActivityContainer(ActivityTaskManagerService service, WindowManagerService wmService) {
+        super(wmService);
         mService = service;
         mStackSupervisor = service.mStackSupervisor;
         mStackSupervisor.mRootActivityContainer = this;
@@ -345,8 +338,6 @@
 
     void setWindowManager(WindowManagerService wm) {
         mWindowManager = wm;
-        mRootWindowContainer = mWindowManager.mRoot;
-        mRootWindowContainer.setRootActivityContainer(this);
         mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
         mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
@@ -358,14 +349,13 @@
             if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
                 mDefaultDisplay = displayContent;
             }
-            addChild(displayContent, DisplayContent.POSITION_TOP);
         }
         calculateDefaultMinimalSizeOfResizeableTasks();
 
         final DisplayContent defaultDisplay = getDefaultDisplay();
 
         defaultDisplay.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
-        positionChildAt(defaultDisplay, DisplayContent.POSITION_TOP);
+        positionChildAt(POSITION_TOP, defaultDisplay, false /* includingParents */);
     }
 
     // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
@@ -424,7 +414,6 @@
         }
         // The display hasn't been added to ActivityManager yet, create a new record now.
         displayContent = new DisplayContent(display, this);
-        addChild(displayContent, DisplayContent.POSITION_BOTTOM);
         return displayContent;
     }
 
@@ -750,7 +739,7 @@
 
         // Force-update the orientation from the WindowManager, since we need the true configuration
         // to send to the client now.
-        final DisplayContent displayContent = mRootWindowContainer.getDisplayContent(displayId);
+        final DisplayContent displayContent = getDisplayContent(displayId);
         Configuration config = null;
         if (displayContent != null) {
             config = displayContent.updateOrientation(
@@ -1564,57 +1553,11 @@
     }
 
     @Override
-    protected int getChildCount() {
-        return mDisplayContents.size();
-    }
-
-    @Override
-    protected DisplayContent getChildAt(int index) {
-        return mDisplayContents.get(index);
-    }
-
-    @Override
-    protected ConfigurationContainer getParent() {
-        return null;
-    }
-
-    // TODO: remove after object merge with RootWindowContainer
-    void onChildPositionChanged(DisplayContent display, int position) {
-        // Assume AM lock is held from positionChildAt of controller in each hierarchy.
-        if (display != null) {
-            positionChildAt(display, position);
-        }
-    }
-
-    /** Change the z-order of the given display. */
-    private void positionChildAt(DisplayContent display, int position) {
-        if (position >= mDisplayContents.size()) {
-            position = mDisplayContents.size() - 1;
-        } else if (position < 0) {
-            position = 0;
-        }
-
-        if (mDisplayContents.isEmpty()) {
-            mDisplayContents.add(display);
-        } else if (mDisplayContents.get(position) != display) {
-            mDisplayContents.remove(display);
-            mDisplayContents.add(position, display);
-        }
+    void positionChildAt(int position, DisplayContent child, boolean includingParents) {
+        super.positionChildAt(position, child, includingParents);
         mStackSupervisor.updateTopResumedActivityIfNeeded();
     }
 
-    @VisibleForTesting
-    void addChild(DisplayContent displayContent, int position) {
-        positionChildAt(displayContent, position);
-        mRootWindowContainer.positionChildAt(position, displayContent);
-    }
-
-    void removeChild(DisplayContent displayContent) {
-        // The caller must tell the controller of {@link DisplayContent} to release its container
-        // {@link DisplayContent}. That is done in {@link DisplayContent#releaseSelfIfNeeded}).
-        mDisplayContents.remove(displayContent);
-    }
-
     Configuration getDisplayOverrideConfiguration(int displayId) {
         final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
         if (displayContent == null) {
@@ -1664,7 +1607,7 @@
     }
 
     void addStartingWindowsForVisibleActivities() {
-        mRootWindowContainer.forAllActivities((r) -> {
+        forAllActivities((r) -> {
             if (r.mVisibleRequested) {
                 r.showStartingWindow(null /* prev */, false /* newTask */, true /*taskSwitch*/);
             }
@@ -1676,7 +1619,7 @@
     }
 
     void rankTaskLayersIfNeeded() {
-        if (!mTaskLayersChanged || mRootWindowContainer == null) {
+        if (!mTaskLayersChanged) {
             return;
         }
         mTaskLayersChanged = false;
@@ -1684,7 +1627,7 @@
         final PooledConsumer c = PooledLambda.obtainConsumer(
                 RootActivityContainer::rankTaskLayerForActivity, this,
                 PooledLambda.__(ActivityRecord.class));
-        mRootWindowContainer.forAllActivities(c);
+        forAllActivities(c);
         c.recycle();
     }
 
@@ -1700,7 +1643,7 @@
         final PooledConsumer c = PooledLambda.obtainConsumer(
                 RootActivityContainer::clearOtherAppTimeTrackers,
                 PooledLambda.__(ActivityRecord.class), except);
-        mRootWindowContainer.forAllActivities(c);
+        forAllActivities(c);
         c.recycle();
     }
 
@@ -1748,7 +1691,7 @@
     void handleAppCrash(WindowProcessController app) {
         final PooledConsumer c = PooledLambda.obtainConsumer(
                 RootActivityContainer::handleAppCrash, PooledLambda.__(ActivityRecord.class), app);
-        mRootWindowContainer.forAllActivities(c);
+        forAllActivities(c);
         c.recycle();
     }
 
@@ -1773,7 +1716,7 @@
         final PooledPredicate p = PooledLambda.obtainPredicate(
                 RootActivityContainer::matchesActivity, PooledLambda.__(ActivityRecord.class),
                 userId, compareIntentFilters, intent, cls);
-        final ActivityRecord r = mRootWindowContainer.getActivity(p);
+        final ActivityRecord r = getActivity(p);
         p.recycle();
         return r;
     }
@@ -2123,7 +2066,7 @@
     }
 
     void closeSystemDialogs() {
-        mRootWindowContainer.forAllActivities((r) -> {
+        forAllActivities((r) -> {
             if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
                 r.finishIfPossible("close-sys", true /* oomAdj */);
             }
@@ -2161,7 +2104,7 @@
             final PooledFunction f = PooledLambda.obtainFunction(
                     FinishDisabledPackageActivitiesHelper::processActivity, this,
                     PooledLambda.__(ActivityRecord.class));
-            mRootWindowContainer.forAllActivities(f);
+            forAllActivities(f);
             f.recycle();
             return mDidSomething;
         }
@@ -2213,7 +2156,7 @@
         final PooledConsumer c = PooledLambda.obtainConsumer(
                 RootActivityContainer::updateActivityApplicationInfo,
                 PooledLambda.__(ActivityRecord.class), aInfo, userId, packageName);
-        mRootWindowContainer.forAllActivities(c);
+        forAllActivities(c);
         c.recycle();
     }
 
@@ -2341,7 +2284,7 @@
             final PooledConsumer c = PooledLambda.obtainConsumer(
                     RootActivityContainer::taskTopActivityIsUser, this, PooledLambda.__(Task.class),
                     userId);
-            mRootWindowContainer.forAllTasks(c);
+            forAllTasks(c);
             c.recycle();
         } finally {
             mService.continueWindowLayout();
@@ -2409,7 +2352,7 @@
 
         final PooledPredicate p = PooledLambda.obtainPredicate(
                 Task::isTaskId, PooledLambda.__(Task.class), id);
-        Task task = mRootWindowContainer.getTask(p);
+        Task task = getTask(p);
         p.recycle();
 
         if (task != null) {
@@ -2621,10 +2564,11 @@
         return printed;
     }
 
-    protected void dumpDebug(ProtoOutputStream proto, long fieldId,
+    @Override
+    public void dumpDebug(ProtoOutputStream proto, long fieldId,
             @WindowTraceLogLevel int logLevel) {
         final long token = proto.start(fieldId);
-        super.dumpDebug(proto, CONFIGURATION_CONTAINER, logLevel);
+        dumpDebugInner(proto, ROOT_WINDOW_CONTAINER, logLevel);
         for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) {
             final DisplayContent displayContent = getChildAt(displayNdx);
             displayContent.dumpDebug(proto, DISPLAYS, logLevel);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 8b08344..936d643 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -50,7 +50,6 @@
 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
 
-import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -85,16 +84,12 @@
 import java.util.function.Consumer;
 
 /** Root {@link WindowContainer} for the device. */
-class RootWindowContainer extends WindowContainer<DisplayContent>
-        implements ConfigurationContainerListener {
+class RootWindowContainer extends WindowContainer<DisplayContent> {
     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;
 
-    // TODO: Remove after object merge with RootActivityContainer.
-    private RootActivityContainer mRootActivityContainer;
-
     private Object mLastWindowFreezeSource = null;
     private Session mHoldScreen = null;
     private float mScreenBrightness = -1;
@@ -156,13 +151,6 @@
         mHandler = new MyHandler(service.mH.getLooper());
     }
 
-    void setRootActivityContainer(RootActivityContainer container) {
-        mRootActivityContainer = container;
-        if (container != null) {
-            container.registerConfigurationChangeListener(this);
-        }
-    }
-
     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
         mTopFocusedAppByProcess.clear();
         boolean changed = false;
@@ -1006,9 +994,7 @@
         }
     }
 
-    @CallSuper
-    @Override
-    public void dumpDebug(ProtoOutputStream proto, long fieldId,
+    public void dumpDebugInner(ProtoOutputStream proto, long fieldId,
             @WindowTraceLogLevel int logLevel) {
         if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
             return;
@@ -1037,19 +1023,6 @@
     }
 
     @Override
-    void positionChildAt(int position, DisplayContent child, boolean includingParents) {
-        super.positionChildAt(position, child, includingParents);
-        if (mRootActivityContainer != null) {
-            mRootActivityContainer.onChildPositionChanged(child, position);
-        }
-    }
-
-    void positionChildAt(int position, DisplayContent child) {
-        // Only called from controller so no need to notify the change to controller.
-        super.positionChildAt(position, child, false /* includingParents */);
-    }
-
-    @Override
     void scheduleAnimation() {
         mWmService.scheduleAnimationLocked();
     }
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 5783713..53c0dd0 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -76,7 +76,7 @@
 
         final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this,
                 PooledLambda.__(Task.class));
-        root.mRootWindowContainer.forAllTasks(c, false);
+        root.forAllTasks(c, false);
         c.recycle();
 
         // Take the first {@param maxNum} tasks and create running task infos for them
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index be41891..4a4d6eb 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 RootWindowContainer(this);
+        mRoot = new RootActivityContainer(mAtmService, this);
 
         mWindowPlacerLocked = new WindowSurfacePlacer(this);
         mTaskSnapshotController = new TaskSnapshotController(this);
@@ -5787,7 +5787,7 @@
      */
     void dumpDebugLocked(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) {
         mPolicy.dumpDebug(proto, POLICY);
-        mRoot.dumpDebug(proto, ROOT_WINDOW_CONTAINER, logLevel);
+        mRoot.dumpDebugInner(proto, ROOT_WINDOW_CONTAINER, logLevel);
         final DisplayContent topFocusedDisplayContent = mRoot.getTopFocusedDisplayContent();
         if (topFocusedDisplayContent.mCurrentFocus != null) {
             topFocusedDisplayContent.mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW);