diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java index 7714458bb1671..7f1b4c0d0dd3b 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.app.IActivityTaskManager; 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 com.android.internal.annotations.VisibleForTesting; 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 @@ class TaskPositioner { 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 @@ class TaskPositioner { } mDisplayContent.resumeRotationLocked(); mDisplayContent = null; + mClientCallback.unlinkToDeath(this, 0 /* flags */); } void startDrag(WindowState win, boolean resize, boolean preserveOrientation, float startX, @@ -355,6 +359,14 @@ class TaskPositioner { + ", 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 @@ class TaskPositioner { return sFactory.create(service); } + @Override + public void binderDied() { + mService.mTaskPositioningController.finishTaskPositioning(); + } + interface Factory { default TaskPositioner create(WindowManagerService service) { return new TaskPositioner(service); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java index 9cdb465dc445c..df55b39b08178 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.wm.TaskPositioner.MIN_ASPECT; import static com.android.server.wm.WindowManagerService.dipToPixel; import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP; @@ -29,6 +30,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import android.app.IActivityTaskManager; import android.graphics.Rect; @@ -37,6 +40,7 @@ import android.util.DisplayMetrics; import android.util.Log; import android.view.Display; +import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import org.junit.After; @@ -494,4 +498,15 @@ public class TaskPositionerTests extends WindowTestsBase { assertEquals("top", expected.top, actual.top); assertEquals("bottom", expected.bottom, actual.bottom); } + + @FlakyTest(bugId = 129492888) + @Test + public void testFinishingMovingWhenBinderDied() { + spyOn(mWm.mTaskPositioningController); + + mPositioner.startDrag(mWindow, false, false, 0 /* startX */, 0 /* startY */); + verify(mWm.mTaskPositioningController, never()).finishTaskPositioning(); + mPositioner.binderDied(); + verify(mWm.mTaskPositioningController).finishTaskPositioning(); + } }