diff options
| author | 2018-10-03 14:25:34 -0700 | |
|---|---|---|
| committer | 2018-10-18 11:31:54 -0700 | |
| commit | db111ee2ee9fb332ea80f99af236bcb3e4015689 (patch) | |
| tree | 4dfc7aef8a24cedd0f3fe6646be690cd3b351d7e | |
| parent | e5bc538a9f1603aee63aa5b464406c831545a498 (diff) | |
Allow recents animation controller to control input consumer lifecycle
- Removing race between the system cleaning up the input consumer and the
controller who is also managing the input consumer lifecycle (it's
preferable for the controller to keep the input consumer registered,
and only to toggle the enabled state). Instead, we only ensure that we
clean up if the runner is unexpected destroyed.
- Also ensure that we don't add the input consumer on top of the runner's
app window
Bug: 117224991
Test: atest FrameworksServicesTests:RecentsAnimationTest
Test: atest FrameworksServicesTests:com.android.server.wm.RecentsAnimationControllerTest
Change-Id: I258f655417220b95112ba784e2ab2f30a9ee2a4a
3 files changed, 20 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 15f693872158..ed3e6c6ad810 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -435,14 +435,14 @@ final class InputMonitor { final RecentsAnimationController recentsAnimationController = mService.getRecentsAnimationController(); if (recentsAnimationController != null - && recentsAnimationController.hasInputConsumerForApp(w.mAppToken)) { + && recentsAnimationController.shouldApplyInputConsumer(w.mAppToken)) { if (recentsAnimationController.updateInputConsumerForApp( recentsAnimationInputConsumer.mWindowHandle, hasFocus)) { addInputWindowHandle(recentsAnimationInputConsumer.mWindowHandle); mAddRecentsAnimationInputConsumerHandle = false; } - // Skip adding the window below regardless of whether there is an input consumer - // to handle it + // If the target app window does not yet exist, then we don't add the input + // consumer window, but also don't add the app window below. return; } } diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 6fef16304d42..5c80759c6998 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -458,10 +458,9 @@ public class RecentsAnimationController implements DeathRecipient { mRunner = null; mCanceled = true; - // Clear associated input consumers + // Update the input windows after the animation is complete final InputMonitor inputMonitor = mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor(); - inputMonitor.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION); inputMonitor.updateInputWindowsLw(true /*force*/); // We have deferred all notifications to the target app as a part of the recents animation, @@ -494,6 +493,11 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void binderDied() { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied"); + + // Clear associated input consumers on runner death + final InputMonitor inputMonitor = + mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor(); + inputMonitor.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION); } void checkAnimationReady(WallpaperController wallpaperController) { @@ -516,8 +520,14 @@ public class RecentsAnimationController implements DeathRecipient { && isTargetOverWallpaper(); } - boolean hasInputConsumerForApp(AppWindowToken appToken) { - return mInputConsumerEnabled && isAnimatingApp(appToken); + /** + * @return Whether to use the input consumer to override app input to route home/recents. + */ + boolean shouldApplyInputConsumer(AppWindowToken appToken) { + // Only apply the input consumer if it is enabled, it is not the target (home/recents) + // being revealed with the transition, and we are actively animating the app as a part of + // the animation + return mInputConsumerEnabled && mTargetAppToken != appToken && isAnimatingApp(appToken); } boolean updateInputConsumerForApp(InputWindowHandle inputWindowHandle, @@ -675,6 +685,7 @@ public class RecentsAnimationController implements DeathRecipient { final String innerPrefix = prefix + " "; pw.print(prefix); pw.println(RecentsAnimationController.class.getSimpleName() + ":"); pw.print(innerPrefix); pw.println("mPendingStart=" + mPendingStart); + pw.print(innerPrefix); pw.println("mPendingAnimations=" + mPendingAnimations.size()); pw.print(innerPrefix); pw.println("mCanceled=" + mCanceled); pw.print(innerPrefix); pw.println("mInputConsumerEnabled=" + mInputConsumerEnabled); pw.print(innerPrefix); pw.println("mSplitScreenMinimized=" + mSplitScreenMinimized); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index ad51b17b5604..da6bfd14f9bc 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2685,8 +2685,9 @@ public class WindowManagerService extends IWindowManager.Stub public void cleanupRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode) { synchronized (mWindowMap) { if (mRecentsAnimationController != null) { - mRecentsAnimationController.cleanupAnimation(reorderMode); + final RecentsAnimationController controller = mRecentsAnimationController; mRecentsAnimationController = null; + controller.cleanupAnimation(reorderMode); mAppTransition.updateBooster(); } } |