Ask back navigation target to start rendering asap after gesture finish

After gesture finish, use launch behind to ask app start rendering
before entire close transition finish, the snapshot will be removed once
the opening target report drawn.

Flag: ACONFIG com.android.window.flags.predictive_back_system_anim
Flag: ACONFIG com.android.window.flags.activity_snapshot_by_default
Bug: 328664843
Test: verify snapshot can be removed much faster.
Change-Id: Ifa4ea469c0f882ec51b6d1920d02234afa3e3431
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 80578e4..22de5b7 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -4126,7 +4126,6 @@
     method @NonNull public static String typeToString(int);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.window.BackNavigationInfo> CREATOR;
-    field public static final String KEY_TRIGGER_BACK = "TriggerBack";
     field public static final int TYPE_CALLBACK = 4; // 0x4
     field public static final int TYPE_CROSS_ACTIVITY = 2; // 0x2
     field public static final int TYPE_CROSS_TASK = 3; // 0x3
diff --git a/core/java/android/window/BackNavigationInfo.java b/core/java/android/window/BackNavigationInfo.java
index 4816f35..b1cf834 100644
--- a/core/java/android/window/BackNavigationInfo.java
+++ b/core/java/android/window/BackNavigationInfo.java
@@ -72,8 +72,17 @@
     /**
      * Key to access the boolean value passed in {#mOnBackNavigationDone} result bundle
      * that represents if back navigation has been triggered.
+     * @hide
      */
-    public static final String KEY_TRIGGER_BACK = "TriggerBack";
+    public static final String KEY_NAVIGATION_FINISHED = "NavigationFinished";
+
+    /**
+     * Key to access the boolean value passed in {#mOnBackNavigationDone} result bundle
+     * that represents if back gesture has been triggered.
+     * @hide
+     */
+    public static final String KEY_GESTURE_FINISHED = "GestureFinished";
+
 
     /**
      * Defines the type of back destinations a back even can lead to. This is used to define the
@@ -192,7 +201,21 @@
     public void onBackNavigationFinished(boolean triggerBack) {
         if (mOnBackNavigationDone != null) {
             Bundle result = new Bundle();
-            result.putBoolean(KEY_TRIGGER_BACK, triggerBack);
+            result.putBoolean(KEY_NAVIGATION_FINISHED, triggerBack);
+            mOnBackNavigationDone.sendResult(result);
+        }
+    }
+
+    /**
+     * Callback to be called when the back gesture is finished in order to notify the server that
+     * it can ask app to start rendering.
+     * @hide
+     * @param triggerBack Boolean indicating if back gesture has been triggered.
+     */
+    public void onBackGestureFinished(boolean triggerBack) {
+        if (mOnBackNavigationDone != null) {
+            Bundle result = new Bundle();
+            result.putBoolean(KEY_GESTURE_FINISHED, triggerBack);
             mOnBackNavigationDone.sendResult(result);
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 97bf8f7..7c078b1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -828,6 +828,8 @@
 
         // The next callback should be {@link #onBackAnimationFinished}.
         if (mCurrentTracker.getTriggerBack()) {
+            // notify gesture finished
+            mBackNavigationInfo.onBackGestureFinished(true);
             dispatchOrAnimateOnBackInvoked(mActiveCallback, mCurrentTracker);
         } else {
             tryDispatchOnBackCancelled(mActiveCallback);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 2ff1ddd..64323a8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -16,7 +16,7 @@
 
 package com.android.wm.shell.back;
 
-import static android.window.BackNavigationInfo.KEY_TRIGGER_BACK;
+import static android.window.BackNavigationInfo.KEY_NAVIGATION_FINISHED;
 
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -677,7 +677,7 @@
         @Override
         public void onResult(@Nullable Bundle result) {
             mBackNavigationDone = true;
-            mTriggerBack = result.getBoolean(KEY_TRIGGER_BACK);
+            mTriggerBack = result.getBoolean(KEY_NAVIGATION_FINISHED);
         }
     }
 }
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index f7b4a67..fcaf960 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -1783,18 +1783,39 @@
     }
 
     private void onBackNavigationDone(Bundle result, int backType) {
-        boolean triggerBack = result != null && result.getBoolean(
-                BackNavigationInfo.KEY_TRIGGER_BACK);
-        ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "onBackNavigationDone backType=%s, "
-                + "triggerBack=%b", backType, triggerBack);
+        if (result == null) {
+            return;
+        }
+        if (result.containsKey(BackNavigationInfo.KEY_NAVIGATION_FINISHED)) {
+            final boolean triggerBack = result.getBoolean(
+                    BackNavigationInfo.KEY_NAVIGATION_FINISHED);
+            ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "onBackNavigationDone backType=%s, "
+                    + "triggerBack=%b", backType, triggerBack);
 
-        synchronized (mWindowManagerService.mGlobalLock) {
-            mNavigationMonitor.stopMonitorForRemote();
-            mBackAnimationInProgress = false;
-            mShowWallpaper = false;
-            // All animation should be done, clear any un-send animation.
-            mPendingAnimation = null;
-            mPendingAnimationBuilder = null;
+            synchronized (mWindowManagerService.mGlobalLock) {
+                mNavigationMonitor.stopMonitorForRemote();
+                mBackAnimationInProgress = false;
+                mShowWallpaper = false;
+                // All animation should be done, clear any un-send animation.
+                mPendingAnimation = null;
+                mPendingAnimationBuilder = null;
+            }
+        }
+        if (result.getBoolean(BackNavigationInfo.KEY_GESTURE_FINISHED)) {
+            synchronized (mWindowManagerService.mGlobalLock) {
+                final AnimationHandler ah = mAnimationHandler;
+                if (!ah.mComposed || ah.mWaitTransition || ah.mOpenActivities == null
+                        || (ah.mSwitchType != AnimationHandler.TASK_SWITCH
+                        && ah.mSwitchType != AnimationHandler.ACTIVITY_SWITCH)) {
+                    return;
+                }
+                for (int i = mAnimationHandler.mOpenActivities.length - 1; i >= 0; --i) {
+                    final ActivityRecord preDrawActivity = mAnimationHandler.mOpenActivities[i];
+                    if (!preDrawActivity.mLaunchTaskBehind) {
+                        setLaunchBehind(preDrawActivity);
+                    }
+                }
+            }
         }
     }