Force pinned windows to always be scaleable.

Otherwise we have a race when switching it off at the end
of the animation when we don't move to fullscreen. Ensure
SCALE_TO_WINDOW is always enabled for windows while they
are in the pinned stack.

Bug: 27793381
Change-Id: Ia92465fd0d854f799caa8ed31edb4621af9fdecd
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 2f7c550..f4e5ddf 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -696,6 +696,14 @@
         public static boolean activitiesCanRequestVisibleBehind(int stackId) {
             return stackId == FULLSCREEN_WORKSPACE_STACK_ID;
         }
+
+        /**
+         * Returns true if this stack may be scaled without resizing,
+         * and windows within may need to be configured as such.
+         */
+        public static boolean windowsAreScaleable(int stackId) {
+            return stackId == PINNED_STACK_ID;
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index a289855..96847e8 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -556,6 +556,15 @@
         if (toTop) {
             mDisplayContent.moveStack(this, true);
         }
+
+        if (StackId.windowsAreScaleable(mStackId)) {
+            // We force windows out of SCALING_MODE_FREEZE
+            // so that we can continue to animate them
+            // while a resize is pending.
+            forceWindowsScaleable(task, true);
+        } else {
+            forceWindowsScaleable(task, false);
+        }
         EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.mTaskId, toTop ? 1 : 0, position);
     }
 
@@ -1280,20 +1289,18 @@
         return true;
     }
 
-    void forceWindowsScaleable(boolean force) {
+    void forceWindowsScaleable(Task task, boolean force) {
         SurfaceControl.openTransaction();
         try {
-            for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
-                final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
-                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-                    final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
-                    for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-                        final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
-                        if (winAnimator == null || !winAnimator.hasSurface()) {
-                            continue;
-                        }
-                        winAnimator.mSurfaceController.forceScaleableInTransaction(force);
+            final ArrayList<AppWindowToken> activities = task.mAppTokens;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
+                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+                    final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
+                    if (winAnimator == null || !winAnimator.hasSurface()) {
+                        continue;
                     }
+                    winAnimator.mSurfaceController.forceScaleableInTransaction(force);
                 }
             }
         } finally {
@@ -1304,10 +1311,6 @@
     @Override  // AnimatesBounds
     public void onAnimationStart() {
         synchronized (mService.mWindowMap) {
-            // We force windows out of SCALING_MODE_FREEZE
-            // so that we can continue to animate them
-            // while a resize is pending.
-            forceWindowsScaleable(true);
             mFreezeMovementAnimations = true;
             mBoundsAnimating = true;
         }
@@ -1318,7 +1321,6 @@
         synchronized (mService.mWindowMap) {
             mFreezeMovementAnimations = false;
             mBoundsAnimating = false;
-            forceWindowsScaleable(false);
             mService.requestTraversal();
         }
         if (mStackId == PINNED_STACK_ID) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 8c29c9b..f6330c1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import static android.app.ActivityManager.StackId;
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
 import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
@@ -1683,6 +1684,11 @@
      * @return Returns true if the surface was successfully shown.
      */
     private boolean showSurfaceRobustlyLocked() {
+        final Task task = mWin.getTask();
+        if (task != null && StackId.windowsAreScaleable(task.mStack.mStackId)) {
+            mSurfaceController.forceScaleableInTransaction(true);
+        }
+
         boolean shown = mSurfaceController.showRobustlyInTransaction();
         if (!shown)
             return false;