[wm]: ensure task positioner controller is always cleaned up

If freeform windowing app is killed while moving, future touch action does not work.
TaskPositioner state is not reset properly. So InputChannel for positioning a task
consumes all touch event.

Finish task positioning when calling session process is killed.

Test: manual - Kill freefrom windowing task process while dragging it
Test: atest WmTests:TaskPositionerTests
Bug: 129492888
Change-Id: I7eb392d6d87a118dd85e7d752eaabfe600920794
(cherry picked from commit 70fe14b649461d9632f24db844b6054879df60b9)
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 7714458..7f1b4c0 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -34,6 +34,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Binder;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.Process;
 import android.os.RemoteException;
@@ -56,7 +57,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-class TaskPositioner {
+class TaskPositioner implements IBinder.DeathRecipient {
     private static final boolean DEBUG_ORIENTATION_VIOLATIONS = false;
     private static final String TAG_LOCAL = "TaskPositioner";
     private static final String TAG = TAG_WITH_CLASS_NAME ? TAG_LOCAL : TAG_WM;
@@ -116,7 +117,9 @@
     private float mStartDragY;
     @CtrlType
     private int mCtrlType = CTRL_NONE;
-    private boolean mDragEnded = false;
+    @VisibleForTesting
+    boolean mDragEnded;
+    private IBinder mClientCallback;
 
     InputChannel mServerChannel;
     InputChannel mClientChannel;
@@ -346,6 +349,7 @@
         }
         mDisplayContent.resumeRotationLocked();
         mDisplayContent = null;
+        mClientCallback.unlinkToDeath(this, 0 /* flags */);
     }
 
     void startDrag(WindowState win, boolean resize, boolean preserveOrientation, float startX,
@@ -355,6 +359,14 @@
                     + ", preserveOrientation=" + preserveOrientation + ", {" + startX + ", "
                     + startY + "}");
         }
+        try {
+            mClientCallback = win.mClient.asBinder();
+            mClientCallback.linkToDeath(this, 0 /* flags */);
+        } catch (RemoteException e) {
+            // The caller has died, so clean up TaskPositioningController.
+            mService.mTaskPositioningController.finishTaskPositioning();
+            return;
+        }
         mTask = win.getTask();
         // Use the bounds of the task which accounts for
         // multiple app windows. Don't use any bounds from win itself as it
@@ -651,6 +663,11 @@
         return sFactory.create(service);
     }
 
+    @Override
+    public void binderDied() {
+        mService.mTaskPositioningController.finishTaskPositioning();
+    }
+
     interface Factory {
         default TaskPositioner create(WindowManagerService service) {
             return new TaskPositioner(service);