Pipe finish callback through synthetic recents path

- Launcher still relys on this callback for cleaning up after the
  transition completes

Flag: EXEMPT (unused without enableFallbackOverviewInWindow)
Bug: 366021931
Test: atest RecentsTransitionHandlerTest
Change-Id: I73ec8524e27e30d7d6f5e6bbe5269e79c3cc08e2
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index f7ed1dd..6d4d4b4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -585,7 +585,7 @@
             }
 
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
-                    "[%d] RecentsController.cancelSyntheticTransition reason=%s",
+                    "[%d] RecentsController.cancelSyntheticTransition: reason=%s",
                     mInstanceId, reason);
             try {
                 // TODO(b/366021931): Notify the correct tasks once we build actual targets, and
@@ -602,13 +602,24 @@
          * Called when a synthetic transition is finished.
          * @return
          */
-        boolean finishSyntheticTransition() {
+        boolean finishSyntheticTransition(IResultReceiver runnerFinishCb, String reason) {
             if (!isSyntheticTransition()) {
                 return false;
             }
 
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
-                    "[%d] RecentsController.finishSyntheticTransition", mInstanceId);
+                    "[%d] RecentsController.finishSyntheticTransition: reason=%s", mInstanceId,
+                    reason);
+            if (runnerFinishCb != null) {
+                try {
+                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                            "[%d] RecentsController.finishInner: calling finish callback",
+                            mInstanceId);
+                    runnerFinishCb.send(0, null);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Failed to report transition finished", e);
+                }
+            }
             // TODO(b/366021931): Clean up leashes accordingly
             cleanUp();
             return true;
@@ -1230,7 +1241,7 @@
 
         private void finishInner(boolean toHome, boolean sendUserLeaveHint,
                 IResultReceiver runnerFinishCb, String reason) {
-            if (finishSyntheticTransition()) {
+            if (finishSyntheticTransition(runnerFinishCb, reason)) {
                 return;
             }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
index 0effc3e..6087763 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
@@ -20,6 +20,7 @@
 
 import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -43,6 +44,7 @@
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.internal.os.IResultReceiver;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
@@ -141,8 +143,9 @@
     }
 
     @Test
-    public void testStartSyntheticRecentsTransition_callsOnAnimationStart() throws Exception {
+    public void testStartSyntheticRecentsTransition_callsOnAnimationStartAndFinishCallback() throws Exception {
         final IRecentsAnimationRunner runner = mock(IRecentsAnimationRunner.class);
+        final IResultReceiver finishCallback = mock(IResultReceiver.class);
         doReturn(new Binder()).when(runner).asBinder();
         Bundle options = new Bundle();
         options.putBoolean("is_synthetic_recents_transition", true);
@@ -151,10 +154,11 @@
                 runner);
         verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any());
 
-        // Finish and verify no transition remains
+        // Finish and verify no transition remains and that the provided finish callback is called
         mRecentsTransitionHandler.findController(transition).finish(true /* toHome */,
-                false /* sendUserLeaveHint */, null /* finishCb */);
+                false /* sendUserLeaveHint */, finishCallback);
         mMainExecutor.flushAll();
+        verify(finishCallback).send(anyInt(), any());
         assertNull(mRecentsTransitionHandler.findController(transition));
     }