diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 318b3d293a57a..bae93f38625a5 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -111,7 +111,9 @@ public class RecentsAnimationController implements DeathRecipient { // minimized private boolean mSplitScreenMinimized; - private Rect mTmpRect = new Rect(); + private final Rect mTmpRect = new Rect(); + + private boolean mLinkedToDeathOfRunner; public interface RecentsAnimationCallbacks { void onAnimationFinished(@ReorderMode int reorderMode); @@ -267,7 +269,7 @@ public class RecentsAnimationController implements DeathRecipient { } try { - mRunner.asBinder().linkToDeath(this, 0); + linkToDeathOfRunner(); } catch (RemoteException e) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); return; @@ -393,7 +395,7 @@ public class RecentsAnimationController implements DeathRecipient { removeAnimation(taskAdapter); } - mRunner.asBinder().unlinkToDeath(this, 0); + unlinkToDeathOfRunner(); // Clear associated input consumers mService.mInputMonitor.updateInputWindowsLw(true /*force*/); mService.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION); @@ -403,6 +405,20 @@ public class RecentsAnimationController implements DeathRecipient { mService.mH.postDelayed(mFailsafeRunnable, FAILSAFE_DELAY); } + private void linkToDeathOfRunner() throws RemoteException { + if (!mLinkedToDeathOfRunner) { + mRunner.asBinder().linkToDeath(this, 0); + mLinkedToDeathOfRunner = true; + } + } + + private void unlinkToDeathOfRunner() { + if (mLinkedToDeathOfRunner) { + mRunner.asBinder().unlinkToDeath(this, 0); + mLinkedToDeathOfRunner = false; + } + } + @Override public void binderDied() { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index 3be7b23590e58..16f4cd0d50ed8 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -61,6 +61,7 @@ class RemoteAnimationController implements DeathRecipient { private FinishedCallback mFinishedCallback; private boolean mCanceled; + private boolean mLinkedToDeathOfRunner; RemoteAnimationController(WindowManagerService service, RemoteAnimationAdapter remoteAnimationAdapter, Handler handler) { @@ -106,7 +107,7 @@ class RemoteAnimationController implements DeathRecipient { } mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> { try { - mRemoteAnimationAdapter.getRunner().asBinder().linkToDeath(this, 0); + linkToDeathOfRunner(); mRemoteAnimationAdapter.getRunner().onAnimationStart(animations, mFinishedCallback); } catch (RemoteException e) { Slog.e(TAG, "Failed to start remote animation", e); @@ -164,8 +165,8 @@ class RemoteAnimationController implements DeathRecipient { private void onAnimationFinished() { mHandler.removeCallbacks(mTimeoutRunnable); - mRemoteAnimationAdapter.getRunner().asBinder().unlinkToDeath(this, 0); synchronized (mService.mWindowMap) { + unlinkToDeathOfRunner(); releaseFinishedCallback(); mService.openSurfaceTransaction(); try { @@ -204,6 +205,20 @@ class RemoteAnimationController implements DeathRecipient { mService.sendSetRunningRemoteAnimation(pid, running); } + private void linkToDeathOfRunner() throws RemoteException { + if (!mLinkedToDeathOfRunner) { + mRemoteAnimationAdapter.getRunner().asBinder().linkToDeath(this, 0); + mLinkedToDeathOfRunner = true; + } + } + + private void unlinkToDeathOfRunner() { + if (mLinkedToDeathOfRunner) { + mRemoteAnimationAdapter.getRunner().asBinder().unlinkToDeath(this, 0); + mLinkedToDeathOfRunner = false; + } + } + @Override public void binderDied() { cancelAnimation();