Allow controlling SystemUI flags during RecentsAnimation

Such that the bars can flip from light/dark depending on animation
progress.

Test: go/wm-smoke
Test: Swipe up from light bar app
Test: WindowStateTests
Bug: 73498721
Change-Id: Ie4b99c75840474a01225720fcd7372191f035a3e
diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl
index 5607b11..89684ca 100644
--- a/core/java/android/view/IRecentsAnimationController.aidl
+++ b/core/java/android/view/IRecentsAnimationController.aidl
@@ -51,4 +51,12 @@
      * and then enable it mid-animation to start receiving touch events.
      */
     void setInputConsumerEnabled(boolean enabled);
+
+    /**
+    * Informs the system whether the animation targets passed into
+    * IRecentsAnimationRunner.onAnimationStart are currently behind the system bars. If they are,
+    * they can control the SystemUI flags, otherwise the SystemUI flags from home activity will be
+    * taken.
+    */
+    void setAnimationTargetsBehindSystemBars(boolean behindSystemBars);
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
index 9a7abf8..940c9ef 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
@@ -51,6 +51,14 @@
         }
     }
 
+    public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars) {
+        try {
+            mAnimationController.setAnimationTargetsBehindSystemBars(behindSystemBars);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to set whether animation targets are behind system bars", e);
+        }
+    }
+
     public void finish(boolean toHome) {
         try {
             mAnimationController.finish(toHome);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 39b886d..cd01c0f 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -136,6 +136,22 @@
         }
 
         @Override
+        public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars)
+                throws RemoteException {
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mService.getWindowManagerLock()) {
+                    for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
+                        mPendingAnimations.get(i).mTask.setCanAffectSystemUiFlags(behindSystemBars);
+                    }
+                    mService.mWindowPlacerLocked.requestTraversal();
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
         public void setInputConsumerEnabled(boolean enabled) {
             if (DEBUG) Log.d(TAG, "setInputConsumerEnabled(" + enabled + "): mCanceled="
                     + mCanceled);
@@ -279,6 +295,7 @@
                 + mPendingAnimations.size());
         for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
             final TaskAnimationAdapter adapter = mPendingAnimations.get(i);
+            adapter.mTask.setCanAffectSystemUiFlags(true);
             adapter.mCapturedFinishCallback.onAnimationFinished(adapter);
         }
         mPendingAnimations.clear();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 2e86351..a403e6f2 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -96,6 +96,9 @@
     private Dimmer mDimmer = new Dimmer(this);
     private final Rect mTmpDimBoundsRect = new Rect();
 
+    /** @see #setCanAffectSystemUiFlags */
+    private boolean mCanAffectSystemUiFlags = true;
+
     Task(int taskId, TaskStack stack, int userId, WindowManagerService service, int resizeMode,
             boolean supportsPictureInPicture, TaskDescription taskDescription,
             TaskWindowContainerController controller) {
@@ -627,6 +630,21 @@
         callback.accept(this);
     }
 
+    /**
+     * @param canAffectSystemUiFlags If false, all windows in this task can not affect SystemUI
+     *                               flags. See {@link WindowState#canAffectSystemUiFlags()}.
+     */
+    void setCanAffectSystemUiFlags(boolean canAffectSystemUiFlags) {
+        mCanAffectSystemUiFlags = canAffectSystemUiFlags;
+    }
+
+    /**
+     * @see #setCanAffectSystemUiFlags
+     */
+    boolean canAffectSystemUiFlags() {
+        return mCanAffectSystemUiFlags;
+    }
+
     @Override
     public String toString() {
         return "{taskId=" + mTaskId + " appTokens=" + mChildren + " mdr=" + mDeferRemoval + "}";
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f01dc20..f4084ab 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1569,7 +1569,9 @@
             final boolean exiting = mAnimatingExit || mDestroying;
             return shown && !exiting;
         } else {
-            return !mAppToken.isHidden();
+            final Task task = getTask();
+            final boolean canFromTask = task != null && task.canAffectSystemUiFlags();
+            return canFromTask && !mAppToken.isHidden();
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index cdcb949..56b7d9f 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -38,7 +38,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 
 import static org.junit.Assert.assertEquals;
@@ -288,6 +287,16 @@
         app.mToken.setHidden(false);
         app.mAttrs.alpha = 0.0f;
         assertFalse(app.canAffectSystemUiFlags());
+
+    }
+
+    @Test
+    public void testCanAffectSystemUiFlags_disallow() throws Exception {
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        app.mToken.setHidden(false);
+        assertTrue(app.canAffectSystemUiFlags());
+        app.getTask().setCanAffectSystemUiFlags(false);
+        assertFalse(app.canAffectSystemUiFlags());
     }
 
     @Test