Merge "Do not return stacks to AM that are marked for deferred removal."
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index bd3f302d..2512dbd 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1542,11 +1542,11 @@
      * Callback used to trigger bounds update after configuration change and get ids of stacks whose
      * bounds were updated.
      */
-    void updateStackBoundsAfterConfigChange(@NonNull List<Integer> changedStackList) {
+    void updateStackBoundsAfterConfigChange(@NonNull List<TaskStack> changedStackList) {
         for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
             final TaskStack stack = mTaskStackContainers.getChildAt(i);
             if (stack.updateBoundsAfterConfigChange()) {
-                changedStackList.add(stack.mStackId);
+                changedStackList.add(stack);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 4b7cea7..8d1a822 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -47,6 +47,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.function.Consumer;
 
 import static android.app.AppOpsManager.MODE_ALLOWED;
@@ -126,7 +127,8 @@
     boolean mOrientationChangeComplete = true;
     boolean mWallpaperActionPending = false;
 
-    private final ArrayList<Integer> mChangedStackList = new ArrayList();
+    private final ArrayList<TaskStack> mTmpStackList = new ArrayList();
+    private final ArrayList<Integer> mTmpStackIds = new ArrayList<>();
 
     // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
     // instances will be replaced with an instance that writes a binary representation of all
@@ -333,7 +335,8 @@
 
     /**
      * Set new display override config and return array of ids of stacks that were changed during
-     * update. If called for the default display, global configuration will also be updated.
+     * update. If called for the default display, global configuration will also be updated. Stacks
+     * that are marked for deferred removal are excluded from the returned array.
      */
     int[] setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, int displayId) {
         final DisplayContent displayContent = getDisplayContent(displayId);
@@ -346,24 +349,42 @@
         if (!configChanged) {
             return null;
         }
+
         displayContent.onOverrideConfigurationChanged(newConfiguration);
 
+        mTmpStackList.clear();
         if (displayId == DEFAULT_DISPLAY) {
             // Override configuration of the default display duplicates global config. In this case
             // we also want to update the global config.
-            return setGlobalConfigurationIfNeeded(newConfiguration);
+            setGlobalConfigurationIfNeeded(newConfiguration, mTmpStackList);
         } else {
-            return updateStackBoundsAfterConfigChange(displayId);
+            updateStackBoundsAfterConfigChange(displayId, mTmpStackList);
         }
+
+        mTmpStackIds.clear();
+        final int stackCount = mTmpStackList.size();
+
+        for (int i = 0; i < stackCount; ++i) {
+            final TaskStack stack = mTmpStackList.get(i);
+
+            // We only include stacks that are not marked for removal as they do not exist outside
+            // of WindowManager at this point.
+            if (!stack.mDeferRemoval) {
+                mTmpStackIds.add(stack.mStackId);
+            }
+        }
+
+        return mTmpStackIds.isEmpty() ? null : ArrayUtils.convertToIntArray(mTmpStackIds);
     }
 
-    private int[] setGlobalConfigurationIfNeeded(Configuration newConfiguration) {
+    private void setGlobalConfigurationIfNeeded(Configuration newConfiguration,
+            List<TaskStack> changedStacks) {
         final boolean configChanged = getConfiguration().diff(newConfiguration) != 0;
         if (!configChanged) {
-            return null;
+            return;
         }
         onConfigurationChanged(newConfiguration);
-        return updateStackBoundsAfterConfigChange();
+        updateStackBoundsAfterConfigChange(changedStacks);
     }
 
     @Override
@@ -378,26 +399,18 @@
      * Callback used to trigger bounds update after configuration change and get ids of stacks whose
      * bounds were updated.
      */
-    private int[] updateStackBoundsAfterConfigChange() {
-        mChangedStackList.clear();
-
+    private void updateStackBoundsAfterConfigChange(List<TaskStack> changedStacks) {
         final int numDisplays = mChildren.size();
         for (int i = 0; i < numDisplays; ++i) {
             final DisplayContent dc = mChildren.get(i);
-            dc.updateStackBoundsAfterConfigChange(mChangedStackList);
+            dc.updateStackBoundsAfterConfigChange(changedStacks);
         }
-
-        return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
     }
 
     /** Same as {@link #updateStackBoundsAfterConfigChange()} but only for a specific display. */
-    private int[] updateStackBoundsAfterConfigChange(int displayId) {
-        mChangedStackList.clear();
-
+    private void updateStackBoundsAfterConfigChange(int displayId, List<TaskStack> changedStacks) {
         final DisplayContent dc = getDisplayContent(displayId);
-        dc.updateStackBoundsAfterConfigChange(mChangedStackList);
-
-        return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
+        dc.updateStackBoundsAfterConfigChange(changedStacks);
     }
 
     private void prepareFreezingTaskBounds() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 066e4e6..d565a6a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -24,8 +24,6 @@
 import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
 import static android.app.StatusBarManager.DISABLE_MASK;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_USER_HANDLE;
@@ -125,7 +123,6 @@
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.IAssistDataReceiver;
-import android.app.WindowConfiguration;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -2466,6 +2463,7 @@
                 mWaitingForConfig = false;
                 mLastFinishedFreezeSource = "new-config";
             }
+
             return mRoot.setDisplayOverrideConfigurationIfNeeded(overrideConfig, displayId);
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
new file mode 100644
index 0000000..51b019a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -0,0 +1,50 @@
+package com.android.server.wm;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for the {@link RootWindowContainer} class.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.wm.RootWindowContainerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RootWindowContainerTests extends WindowTestsBase {
+    @Test
+    public void testSetDisplayOverrideConfigurationIfNeeded() throws Exception {
+        // Add first stack we expect to be updated with configuration change.
+        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
+        stack.getOverrideConfiguration().windowConfiguration.setBounds(new Rect(0, 0, 5, 5));
+
+        // Add second task that will be set for deferred removal that should not be returned
+        // with the configuration change.
+        final TaskStack deferredDeletedStack = createTaskStackOnDisplay(mDisplayContent);
+        deferredDeletedStack.getOverrideConfiguration().windowConfiguration.setBounds(
+                new Rect(0, 0, 5, 5));
+        deferredDeletedStack.mDeferRemoval = true;
+
+        final Configuration override = new Configuration(
+                mDisplayContent.getOverrideConfiguration());
+        override.windowConfiguration.setBounds(new Rect(0, 0, 10, 10));
+
+        // Set display override.
+        final int[] results = sWm.mRoot.setDisplayOverrideConfigurationIfNeeded(override,
+                        mDisplayContent.getDisplayId());
+
+        // Ensure only first stack is returned.
+        assertTrue(results.length == 1);
+        assertTrue(results[0] == stack.mStackId);
+    }
+}