Refactor ATMS and WMS methods

Moved updateDisplayOverrideConfiguration
updateDisplayOverrideConfigurationLocked, and
performDisplayOverrideConfigUpdate from ATMS to ActivityDisplay
because all calls to these methods have a reference to either a
DisplayContent or ActivityDisplay, so it is better that the methods
are called directly rather than going through a service that uses
displayId to get access to an object it already could have had access
to. Similarly, sendNewConfiguration has been moved from
WindowManagerService to DisplayContent. These changes are
necessary for situations where methods in ATMS and WMS want
to process ActivityDisplay and DisplayContent objects before they
are added to either hierarchy. These situations will arise when sending
new configurations happens synchronously as opposed to posting to a
handler (as is the current situation with
DisplayContent#sendNewConfiguration).

Bug: 130807132
Test: go/wm-smoke
Change-Id: Ie2bd6c32b2adc2c4c5d585e361defd6c98652f01
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 26720fc..2957309 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -386,15 +386,6 @@
      */
     void resizePinnedStack(in Rect pinnedBounds, in Rect tempPinnedTaskBounds);
 
-    /**
-     * Updates override configuration applied to specific display.
-     * @param values Update values for display configuration. If null is passed it will request the
-     *               Window Manager to compute new config for the specified display.
-     * @param displayId Id of the display to apply the config to.
-     * @throws RemoteException
-     * @return Returns true if the configuration was updated.
-     */
-    boolean updateDisplayOverrideConfiguration(in Configuration values, int displayId);
     void dismissKeyguard(in IBinder token, in IKeyguardDismissCallback callback,
             in CharSequence message);
 
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index 637ad03..fe4811d 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -29,6 +29,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.os.Build.VERSION_CODES.N;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_PRIVATE;
 import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
@@ -55,18 +56,24 @@
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 
 import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
 import android.app.ActivityOptions;
 import android.app.WindowConfiguration;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.os.IBinder;
+import android.os.Message;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.IntArray;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.am.EventLogTags;
 
 import java.io.PrintWriter;
@@ -156,6 +163,9 @@
     // Used in updating the display size
     private Point mTmpDisplaySize = new Point();
 
+    // Used in updating override configurations
+    private final Configuration mTempConfig = new Configuration();
+
     private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
 
     ActivityDisplay(RootActivityContainer root, Display display) {
@@ -999,6 +1009,89 @@
         return mStacks.indexOf(stack);
     }
 
+    boolean updateDisplayOverrideConfigurationLocked() {
+        Configuration values = new Configuration();
+        mDisplayContent.computeScreenConfiguration(values);
+
+        if (mService.mWindowManager != null) {
+            final Message msg = PooledLambda.obtainMessage(
+                    ActivityManagerInternal::updateOomLevelsForDisplay, mService.mAmInternal,
+                    mDisplayId);
+            mService.mH.sendMessage(msg);
+        }
+
+        Settings.System.clearConfiguration(values);
+        updateDisplayOverrideConfigurationLocked(values, null /* starting */,
+                false /* deferResume */, mService.mTmpUpdateConfigurationResult);
+        return mService.mTmpUpdateConfigurationResult.changes != 0;
+    }
+
+    /**
+     * Updates override configuration specific for the selected display. If no config is provided,
+     * new one will be computed in WM based on current display info.
+     */
+    boolean updateDisplayOverrideConfigurationLocked(Configuration values,
+            ActivityRecord starting, boolean deferResume,
+            ActivityTaskManagerService.UpdateConfigurationResult result) {
+
+        int changes = 0;
+        boolean kept = true;
+
+        if (mService.mWindowManager != null) {
+            mService.mWindowManager.deferSurfaceLayout();
+        }
+        try {
+            if (values != null) {
+                if (mDisplayId == DEFAULT_DISPLAY) {
+                    // Override configuration of the default display duplicates global config, so
+                    // we're calling global config update instead for default display. It will also
+                    // apply the correct override config.
+                    changes = mService.updateGlobalConfigurationLocked(values,
+                            false /* initLocale */, false /* persistent */,
+                            UserHandle.USER_NULL /* userId */, deferResume);
+                } else {
+                    changes = performDisplayOverrideConfigUpdate(values, deferResume);
+                }
+            }
+
+            kept = mService.ensureConfigAndVisibilityAfterUpdate(starting, changes);
+        } finally {
+            if (mService.mWindowManager != null) {
+                mService.mWindowManager.continueSurfaceLayout();
+            }
+        }
+
+        if (result != null) {
+            result.changes = changes;
+            result.activityRelaunched = !kept;
+        }
+        return kept;
+    }
+
+    int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume) {
+        mTempConfig.setTo(getRequestedOverrideConfiguration());
+        final int changes = mTempConfig.updateFrom(values);
+        if (changes != 0) {
+            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
+                    + mTempConfig + " for displayId=" + mDisplayId);
+            onRequestedOverrideConfigurationChanged(mTempConfig);
+
+            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
+            if (isDensityChange && mDisplayId == DEFAULT_DISPLAY) {
+                mService.mAppWarnings.onDensityChanged();
+
+                // Post message to start process to avoid possible deadlock of calling into AMS with
+                // the ATMS lock held.
+                final Message msg = PooledLambda.obtainMessage(
+                        ActivityManagerInternal::killAllBackgroundProcessesExcept,
+                        mService.mAmInternal, N,
+                        ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
+                mService.mH.sendMessage(msg);
+            }
+        }
+        return changes;
+    }
+
     @Override
     public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
         final int currRotation =
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index cf4f0a6..f33e227 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -459,7 +459,7 @@
 
     boolean mSuppressResizeConfigChanges;
 
-    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
+    final UpdateConfigurationResult mTmpUpdateConfigurationResult =
             new UpdateConfigurationResult();
 
     static final class UpdateConfigurationResult {
@@ -631,7 +631,7 @@
     /** If non-null, we are tracking the time the user spends in the currently focused app. */
     AppTimeTracker mCurAppTimeTracker;
 
-    private AppWarnings mAppWarnings;
+    AppWarnings mAppWarnings;
 
     /**
      * Packages that the user has asked to have run in screen size
@@ -4377,46 +4377,6 @@
     }
 
     @Override
-    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
-        mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
-
-        synchronized (mGlobalLock) {
-            // Check if display is initialized in AM.
-            if (!mRootActivityContainer.isDisplayAdded(displayId)) {
-                // Call might come when display is not yet added or has already been removed.
-                if (DEBUG_CONFIGURATION) {
-                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
-                            + displayId);
-                }
-                return false;
-            }
-
-            if (values == null && mWindowManager != null) {
-                // sentinel: fetch the current configuration from the window manager
-                values = mWindowManager.computeNewConfiguration(displayId);
-            }
-
-            if (mWindowManager != null) {
-                final Message msg = PooledLambda.obtainMessage(
-                        ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
-                mH.sendMessage(msg);
-            }
-
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                if (values != null) {
-                    Settings.System.clearConfiguration(values);
-                }
-                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
-                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
-                return mTmpUpdateConfigurationResult.changes != 0;
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
     public boolean updateConfiguration(Configuration values) {
         mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
 
@@ -5160,8 +5120,12 @@
     }
 
     /** Update default (global) configuration and notify listeners about changes. */
-    private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
+    int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
             boolean persistent, int userId, boolean deferResume) {
+
+        final ActivityDisplay defaultDisplay =
+                mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY);
+
         mTempConfig.setTo(getGlobalConfiguration());
         final int changes = mTempConfig.updateFrom(values);
         if (changes == 0) {
@@ -5169,7 +5133,7 @@
             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
             // performDisplayOverrideConfigUpdate in order to send the new display configuration
             // (even if there are no actual changes) to unfreeze the window.
-            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
+            defaultDisplay.performDisplayOverrideConfigUpdate(values, deferResume);
             return 0;
         }
 
@@ -5267,82 +5231,12 @@
 
         // Override configuration of the default display duplicates global config, so we need to
         // update it also. This will also notify WindowManager about changes.
-        performDisplayOverrideConfigUpdate(mRootActivityContainer.getConfiguration(), deferResume,
-                DEFAULT_DISPLAY);
+        defaultDisplay.performDisplayOverrideConfigUpdate(mRootActivityContainer.getConfiguration(),
+                deferResume);
 
         return changes;
     }
 
-    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
-            boolean deferResume, int displayId) {
-        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
-                displayId, null /* result */);
-    }
-
-    /**
-     * Updates override configuration specific for the selected display. If no config is provided,
-     * new one will be computed in WM based on current display info.
-     */
-    boolean updateDisplayOverrideConfigurationLocked(Configuration values,
-            ActivityRecord starting, boolean deferResume, int displayId,
-            ActivityTaskManagerService.UpdateConfigurationResult result) {
-        int changes = 0;
-        boolean kept = true;
-
-        if (mWindowManager != null) {
-            mWindowManager.deferSurfaceLayout();
-        }
-        try {
-            if (values != null) {
-                if (displayId == DEFAULT_DISPLAY) {
-                    // Override configuration of the default display duplicates global config, so
-                    // we're calling global config update instead for default display. It will also
-                    // apply the correct override config.
-                    changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
-                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
-                } else {
-                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
-                }
-            }
-
-            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
-        } finally {
-            if (mWindowManager != null) {
-                mWindowManager.continueSurfaceLayout();
-            }
-        }
-
-        if (result != null) {
-            result.changes = changes;
-            result.activityRelaunched = !kept;
-        }
-        return kept;
-    }
-
-    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
-            int displayId) {
-        mTempConfig.setTo(mRootActivityContainer.getDisplayOverrideConfiguration(displayId));
-        final int changes = mTempConfig.updateFrom(values);
-        if (changes != 0) {
-            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
-                    + mTempConfig + " for displayId=" + displayId);
-            mRootActivityContainer.setDisplayOverrideConfiguration(mTempConfig, displayId);
-
-            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
-            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
-                mAppWarnings.onDensityChanged();
-
-                // Post message to start process to avoid possible deadlock of calling into AMS with
-                // the ATMS lock held.
-                final Message msg = PooledLambda.obtainMessage(
-                        ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
-                        N, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
-                mH.sendMessage(msg);
-            }
-        }
-        return changes;
-    }
-
     private void updateEventDispatchingLocked(boolean booted) {
         mWindowManager.setEventDispatching(booted && !mShuttingDown);
     }
@@ -5763,7 +5657,7 @@
     }
 
     /** Applies latest configuration and/or visibility updates if needed. */
-    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
+    boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
         boolean kept = true;
         final ActivityStack mainStack = mRootActivityContainer.getTopDisplayFocusedStack();
         // mainStack is null during startup.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0c91196..8570d06 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1204,10 +1204,29 @@
     }
 
     /** Notify the configuration change of this display. */
-    void sendNewConfiguration() {
+    void postNewConfigurationToHandler() {
         mWmService.mH.obtainMessage(SEND_NEW_CONFIGURATION, this).sendToTarget();
     }
 
+    void sendNewConfiguration() {
+        synchronized (mWmService.mGlobalLock) {
+            final boolean configUpdated = mAcitvityDisplay
+                    .updateDisplayOverrideConfigurationLocked();
+            if (!configUpdated) {
+                // Something changed (E.g. device rotation), but no configuration update is needed.
+                // E.g. changing device rotation by 180 degrees. Go ahead and perform surface
+                // placement to unfreeze the display since we froze it when the rotation was updated
+                // in DisplayContent#updateRotationUnchecked.
+                if (mWaitingForConfig) {
+                    mWaitingForConfig = false;
+                    mWmService.mLastFinishedFreezeSource = "config-unchanged";
+                    setLayoutNeeded();
+                    mWmService.mWindowPlacerLocked.performSurfacePlacement();
+                }
+            }
+        }
+    }
+
     @Override
     boolean onDescendantOrientationChanged(IBinder freezeDisplayToken,
             ConfigurationContainer requestingContainer) {
@@ -1223,8 +1242,8 @@
 
         if (handled && requestingContainer instanceof ActivityRecord) {
             final ActivityRecord activityRecord = (ActivityRecord) requestingContainer;
-            final boolean kept = mWmService.mAtmService.updateDisplayOverrideConfigurationLocked(
-                    config, activityRecord, false /* deferResume */, getDisplayId());
+            final boolean kept = mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(
+                    config, activityRecord, false /* deferResume */, null /* result */);
             activityRecord.frozenBeforeDestroy = true;
             if (!kept) {
                 mWmService.mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
@@ -1232,8 +1251,8 @@
         } else {
             // We have a new configuration to push so we need to update ATMS for now.
             // TODO: Clean up display configuration push between ATMS and WMS after unification.
-            mWmService.mAtmService.updateDisplayOverrideConfigurationLocked(
-                    config, null /* starting */, false /* deferResume */, getDisplayId());
+            mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(
+                    config, null /* starting */, false /* deferResume */, null);
         }
         return handled;
     }
@@ -1323,7 +1342,7 @@
     boolean updateRotationAndSendNewConfigIfNeeded() {
         final boolean changed = updateRotationUnchecked(false /* forceUpdate */);
         if (changed) {
-            sendNewConfiguration();
+            postNewConfigurationToHandler();
         }
         return changed;
     }
@@ -1342,7 +1361,7 @@
      * Update rotation of the DisplayContent with an option to force the update. This updates
      * the container's perception of rotation and, depending on the top activities, will freeze
      * the screen or start seamless rotation. The display itself gets rotated in
-     * {@link #applyRotationLocked} during {@link WindowManagerService#sendNewConfiguration}.
+     * {@link #applyRotationLocked} during {@link DisplayContent#sendNewConfiguration}.
      *
      * @param forceUpdate Force the rotation update. Sometimes in WM we might skip updating
      *                    orientation because we're waiting for some rotation to finish or display
@@ -3688,7 +3707,7 @@
                 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
                 if (updateOrientationFromAppTokens()) {
                     setLayoutNeeded();
-                    sendNewConfiguration();
+                    postNewConfigurationToHandler();
                 }
             }
 
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index 6b500967..b16d956 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -133,7 +133,7 @@
     @Override
     public void notifyConfigurationChanged() {
         // TODO(multi-display): Notify proper displays that are associated with this input device.
-        mService.sendNewConfiguration(DEFAULT_DISPLAY);
+        mService.mRoot.getDisplayContent(DEFAULT_DISPLAY).sendNewConfiguration();
 
         synchronized (mInputDevicesReadyMonitor) {
             if (!mInputDevicesReady) {
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index d58c613..66d42db 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -317,11 +317,6 @@
         return activityDisplay;
     }
 
-    /** Check if display with specified id is added to the list. */
-    boolean isDisplayAdded(int displayId) {
-        return getActivityDisplayOrCreate(displayId) != null;
-    }
-
     ActivityRecord getDefaultDisplayHomeActivity() {
         return getDefaultDisplayHomeActivityForUser(mCurrentUser);
     }
@@ -656,9 +651,13 @@
             starting.frozenBeforeDestroy = true;
         }
 
-        // Update the configuration of the activities on the display.
-        return mService.updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
-                displayId);
+        if (displayContent != null && displayContent.mAcitvityDisplay != null) {
+            // Update the configuration of the activities on the display.
+            return displayContent.mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(config,
+                    starting, deferResume, null /* result */);
+        } else {
+            return true;
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 10f0922..1bf8c17 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1574,10 +1574,10 @@
             if (win.isVisibleOrAdding() && displayContent.updateOrientationFromAppTokens()) {
                 reportNewConfig = true;
             }
-        }
 
-        if (reportNewConfig) {
-            sendNewConfiguration(displayId);
+            if (reportNewConfig) {
+                displayContent.sendNewConfiguration();
+            }
         }
 
         Binder.restoreCallingIdentity(origId);
@@ -1615,7 +1615,7 @@
             final Display display = mDisplayManager.getDisplay(displayId);
 
             if (display != null) {
-                displayContent = mRoot.createDisplayContent(display, null /* controller */);
+                displayContent = mRoot.createDisplayContent(display, null /* activityDisplay */);
             }
         }
 
@@ -2257,13 +2257,15 @@
                 Slog.v(TAG_WM, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
             }
             win.mInRelayout = false;
+
+            if (configChanged) {
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
+                        "relayoutWindow: postNewConfigurationToHandler");
+                displayContent.sendNewConfiguration();
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+            }
         }
 
-        if (configChanged) {
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: sendNewConfiguration");
-            sendNewConfiguration(displayId);
-            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-        }
         Binder.restoreCallingIdentity(origId);
         return result;
     }
@@ -3714,7 +3716,7 @@
                         layoutNeeded = true;
                     }
                     if (rotationChanged || alwaysSendConfiguration) {
-                        displayContent.sendNewConfiguration();
+                        displayContent.postNewConfigurationToHandler();
                     }
                 }
 
@@ -4256,34 +4258,6 @@
         }
     }
 
-    /**
-     * Instruct the Activity Manager to fetch and update the current display's configuration and
-     * broadcast them to config-changed listeners if appropriate.
-     * NOTE: Can't be called with the window manager lock held since it call into activity manager.
-     */
-    void sendNewConfiguration(int displayId) {
-        try {
-            final boolean configUpdated = mActivityTaskManager.updateDisplayOverrideConfiguration(
-                    null /* values */, displayId);
-            if (!configUpdated) {
-                // Something changed (E.g. device rotation), but no configuration update is needed.
-                // E.g. changing device rotation by 180 degrees. Go ahead and perform surface
-                // placement to unfreeze the display since we froze it when the rotation was updated
-                // in DisplayContent#updateRotationUnchecked.
-                synchronized (mGlobalLock) {
-                    final DisplayContent dc = mRoot.getDisplayContent(displayId);
-                    if (dc != null && dc.mWaitingForConfig) {
-                        dc.mWaitingForConfig = false;
-                        mLastFinishedFreezeSource = "config-unchanged";
-                        dc.setLayoutNeeded();
-                        mWindowPlacerLocked.performSurfacePlacement();
-                    }
-                }
-            }
-        } catch (RemoteException e) {
-        }
-    }
-
     public Configuration computeNewConfiguration(int displayId) {
         synchronized (mGlobalLock) {
             return computeNewConfigurationLocked(displayId);
@@ -4709,7 +4683,7 @@
                     final DisplayContent displayContent = (DisplayContent) msg.obj;
                     removeMessages(SEND_NEW_CONFIGURATION, displayContent);
                     if (displayContent.isReady()) {
-                        sendNewConfiguration(displayContent.getDisplayId());
+                        displayContent.sendNewConfiguration();
                     } else {
                         // Message could come after display has already been removed.
                         if (DEBUG_CONFIGURATION) {
@@ -5193,7 +5167,7 @@
             displayContent.mWaitingForConfig = true;
             startFreezingDisplayLocked(0 /* exitAnim */,
                     0 /* enterAnim */, displayContent);
-            displayContent.sendNewConfiguration();
+            displayContent.postNewConfigurationToHandler();
         }
 
         mWindowPlacerLocked.performSurfacePlacement();
@@ -5540,7 +5514,7 @@
         }
 
         if (configChanged) {
-            displayContent.sendNewConfiguration();
+            displayContent.postNewConfigurationToHandler();
         }
         mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN);
     }
@@ -6853,7 +6827,7 @@
                 final long origId = Binder.clearCallingIdentity();
                 try {
                     // direct call since lock is shared.
-                    sendNewConfiguration(displayId);
+                    displayContent.sendNewConfiguration();
                 } finally {
                     Binder.restoreCallingIdentity(origId);
                 }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d1ddbfe..09199df 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2051,7 +2051,7 @@
             if (wasVisible) {
                 final DisplayContent displayContent = getDisplayContent();
                 if (displayContent.updateOrientationFromAppTokens()) {
-                    displayContent.sendNewConfiguration();
+                    displayContent.postNewConfigurationToHandler();
                 }
             }
             mWmService.updateFocusedWindowLocked(isFocused()
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 f49a575..5bd9a46 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -663,8 +663,8 @@
                 dc.onDescendantOrientationChanged(window.mToken.token, activityRecord));
 
         final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class);
-        verify(mWm.mAtmService).updateDisplayOverrideConfigurationLocked(captor.capture(),
-                same(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
+        verify(dc.mAcitvityDisplay).updateDisplayOverrideConfigurationLocked(captor.capture(),
+                same(activityRecord), anyBoolean(), same(null));
         final Configuration newDisplayConfig = captor.getValue();
         assertEquals(Configuration.ORIENTATION_PORTRAIT, newDisplayConfig.orientation);
     }
@@ -688,8 +688,8 @@
         assertFalse("Display shouldn't rotate to handle orientation request if fixed to"
                         + " user rotation.",
                 dc.onDescendantOrientationChanged(window.mToken.token, activityRecord));
-        verify(mWm.mAtmService, never()).updateDisplayOverrideConfigurationLocked(any(),
-                eq(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
+        verify(dc.mAcitvityDisplay, never()).updateDisplayOverrideConfigurationLocked(any(),
+                eq(activityRecord), anyBoolean(), same(null));
     }
 
     @Test