From fc78fe9acc589868891d9a35be4447989d7aa511 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Thu, 18 Jan 2018 09:31:12 -0800 Subject: [PATCH] 3/ Add input consumer to capture touches during a Recents transition Bug: 70180552 Test: go/wm-smoke Test: Manual, swipe up with suitable launcher build Change-Id: I5cbd21ed13fdce1a5dbf8ff8bfb48dc263c7a54d --- core/java/android/view/WindowManager.java | 8 +++-- .../java/com/android/server/wm/InputMonitor.java | 28 ++++++++++++++--- .../server/wm/RecentsAnimationController.java | 36 ++++++++++++++-------- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 3bb3a4c17b8f..1c5e87197750 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -98,11 +98,13 @@ public interface WindowManager extends ViewManager { int DOCKED_BOTTOM = 4; /** @hide */ - final static String INPUT_CONSUMER_PIP = "pip_input_consumer"; + String INPUT_CONSUMER_PIP = "pip_input_consumer"; /** @hide */ - final static String INPUT_CONSUMER_NAVIGATION = "nav_input_consumer"; + String INPUT_CONSUMER_NAVIGATION = "nav_input_consumer"; /** @hide */ - final static String INPUT_CONSUMER_WALLPAPER = "wallpaper_input_consumer"; + String INPUT_CONSUMER_WALLPAPER = "wallpaper_input_consumer"; + /** @hide */ + String INPUT_CONSUMER_RECENTS_ANIMATION = "recents_animation_input_consumer"; /** * Not set up for a transition. diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 88b7a11f02fd..281e0a8441e2 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION; import static android.view.WindowManager.INPUT_CONSUMER_PIP; +import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS; @@ -86,6 +87,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { private boolean mAddInputConsumerHandle; private boolean mAddPipInputConsumerHandle; private boolean mAddWallpaperInputConsumerHandle; + private boolean mAddRecentsAnimationInputConsumerHandle; private boolean mDisableWallpaperTouchEvents; private final Rect mTmpRect = new Rect(); private final UpdateInputForAllWindowsConsumer mUpdateInputForAllWindowsConsumer = @@ -612,7 +614,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { InputConsumerImpl navInputConsumer; InputConsumerImpl pipInputConsumer; InputConsumerImpl wallpaperInputConsumer; - Rect pipTouchableBounds; + InputConsumerImpl recentsAnimationInputConsumer; boolean inDrag; WallpaperController wallpaperController; @@ -622,11 +624,13 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { navInputConsumer = getInputConsumer(INPUT_CONSUMER_NAVIGATION, DEFAULT_DISPLAY); pipInputConsumer = getInputConsumer(INPUT_CONSUMER_PIP, DEFAULT_DISPLAY); wallpaperInputConsumer = getInputConsumer(INPUT_CONSUMER_WALLPAPER, DEFAULT_DISPLAY); + recentsAnimationInputConsumer = getInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION, + DEFAULT_DISPLAY); mAddInputConsumerHandle = navInputConsumer != null; mAddPipInputConsumerHandle = pipInputConsumer != null; mAddWallpaperInputConsumerHandle = wallpaperInputConsumer != null; + mAddRecentsAnimationInputConsumerHandle = recentsAnimationInputConsumer != null; mTmpRect.setEmpty(); - pipTouchableBounds = mAddPipInputConsumerHandle ? mTmpRect : null; mDisableWallpaperTouchEvents = false; this.inDrag = inDrag; wallpaperController = mService.mRoot.mWallpaperController; @@ -659,12 +663,28 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { final boolean hasFocus = w == mInputFocus; final boolean isVisible = w.isVisibleLw(); + if (mAddRecentsAnimationInputConsumerHandle) { + final RecentsAnimationController recentsAnimationController = + mService.getRecentsAnimationController(); + if (recentsAnimationController != null + && recentsAnimationController.hasInputConsumerForApp(w.mAppToken)) { + if (recentsAnimationController.updateInputConsumerForApp( + recentsAnimationInputConsumer, hasFocus)) { + addInputWindowHandle(recentsAnimationInputConsumer.mWindowHandle); + mAddRecentsAnimationInputConsumerHandle = false; + } + // Skip adding the window below regardless of whether there is an input consumer + // to handle it + return; + } + } + if (w.inPinnedWindowingMode()) { if (mAddPipInputConsumerHandle && (inputWindowHandle.layer <= pipInputConsumer.mWindowHandle.layer)) { // Update the bounds of the Pip input consumer to match the window bounds. - w.getBounds(pipTouchableBounds); - pipInputConsumer.mWindowHandle.touchableRegion.set(pipTouchableBounds); + w.getBounds(mTmpRect); + pipInputConsumer.mWindowHandle.touchableRegion.set(mTmpRect); addInputWindowHandle(pipInputConsumer.mWindowHandle); mAddPipInputConsumerHandle = false; } diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index c7ad17b8699b..c7d4b8ed0f16 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.view.RemoteAnimationTarget.MODE_CLOSING; +import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -74,6 +75,8 @@ public class RecentsAnimationController { // enabled for it to start intercepting touch events. private boolean mInputConsumerEnabled; + private Rect mTmpRect = new Rect(); + public interface RecentsAnimationCallbacks { void onAnimationFinished(boolean moveHomeToTop); } @@ -263,6 +266,7 @@ public class RecentsAnimationController { mService.mInputMonitor.updateInputWindowsLw(true /*force*/); mService.scheduleAnimationLocked(); + mService.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION); } void checkAnimationReady(WallpaperController wallpaperController) { @@ -281,21 +285,33 @@ public class RecentsAnimationController { && isHomeAppOverWallpaper(); } - boolean isHomeAppOverWallpaper() { - if (mHomeAppToken == null) { - return false; + boolean hasInputConsumerForApp(AppWindowToken appToken) { + return mInputConsumerEnabled && isAnimatingApp(appToken); + } + + boolean updateInputConsumerForApp(InputConsumerImpl recentsAnimationInputConsumer, + boolean hasFocus) { + // Update the input consumer touchable region to match the home app main window + final WindowState homeAppMainWindow = mHomeAppToken != null + ? mHomeAppToken.findMainWindow() + : null; + if (homeAppMainWindow != null) { + homeAppMainWindow.getBounds(mTmpRect); + recentsAnimationInputConsumer.mWindowHandle.hasFocus = hasFocus; + recentsAnimationInputConsumer.mWindowHandle.touchableRegion.set(mTmpRect); + return true; } - return mHomeAppToken.windowsCanBeWallpaperTarget(); + return false; } - WindowState getHomeAppMainWindow() { + private boolean isHomeAppOverWallpaper() { if (mHomeAppToken == null) { - return null; + return false; } - return mHomeAppToken.findMainWindow(); + return mHomeAppToken.windowsCanBeWallpaperTarget(); } - boolean isAnimatingApp(AppWindowToken appToken) { + private boolean isAnimatingApp(AppWindowToken appToken) { for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { final Task task = mPendingAnimations.get(i).mTask; for (int j = task.getChildCount() - 1; j >= 0; j--) { @@ -308,10 +324,6 @@ public class RecentsAnimationController { return false; } - boolean isInputConsumerEnabled() { - return mInputConsumerEnabled; - } - private class TaskAnimationAdapter implements AnimationAdapter { private Task mTask; -- 2.11.0