From ee9e277033d959211ba733a480355d41a2f32705 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Thu, 9 Feb 2017 16:30:27 -0800 Subject: [PATCH] Handle focused tasks on multiple displays When the focused task changes displays, make sure to mark the whole previous display as not part of a focused task. This change also adds an adb am command to change the task focus. Test: android.server.cts.ActivityManagerDisplayTests Test: #testStackFocusSwitchOnTouchEvent Bug: 35214007 Change-Id: I9cb7372c21a0b592abb6f6d910077ff5097dd6cf --- .../am/ActivityManagerShellCommand.java | 9 ++++++ .../com/android/server/wm/DisplayContent.java | 32 +++++++++++-------- .../server/wm/RootWindowContainer.java | 2 +- .../server/wm/WindowManagerService.java | 22 ++++++++----- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index a06fa1b8dcfe0..80df26b4ed424 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -2031,6 +2031,8 @@ final class ActivityManagerShellCommand extends ShellCommand { return runTaskDragTaskTest(pw); } else if (op.equals("size-task-test")) { return runTaskSizeTaskTest(pw); + } else if (op.equals("focus")) { + return runTaskFocus(pw); } else { getErrPrintWriter().println("Error: unknown command '" + op + "'"); return -1; @@ -2322,6 +2324,13 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; } + int runTaskFocus(PrintWriter pw) throws RemoteException { + final int taskId = Integer.parseInt(getNextArgRequired()); + pw.println("Setting focus to task " + taskId); + mInterface.setFocusedTask(taskId); + return 0; + } + int runWrite(PrintWriter pw) { mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, "registerUidObserver()"); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c45136ca24726..2c315445577d3 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1072,19 +1072,25 @@ class DisplayContent extends WindowContainer= 0; --stackNdx) { - final TaskStack stack = mTaskStackContainers.get(stackNdx); - stack.setTouchExcludeRegion( - focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2); - } - // If we removed the focused task above, add it back and only leave its - // outside touch area in the exclusion. TapDectector is not interested in - // any touch inside the focused task itself. - if (!mTmpRect2.isEmpty()) { - mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION); + // The provided task is the task on this display with focus, so if WindowManagerService's + // focused app is not on this display, focusedTask will be null. + if (focusedTask == null) { + mTouchExcludeRegion.setEmpty(); + } else { + mTouchExcludeRegion.set(mBaseDisplayRect); + final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics); + mTmpRect2.setEmpty(); + for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) { + final TaskStack stack = mTaskStackContainers.get(stackNdx); + stack.setTouchExcludeRegion( + focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2); + } + // If we removed the focused task above, add it back and only leave its + // outside touch area in the exclusion. TapDectector is not interested in + // any touch inside the focused task itself. + if (!mTmpRect2.isEmpty()) { + mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION); + } } final WindowState inputMethod = mService.mInputMethodWindow; if (inputMethod != null && inputMethod.isVisibleLw()) { diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 80e6655545aa2..126e0800cf07f 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -784,7 +784,7 @@ class RootWindowContainer extends WindowContainer { if (updateInputWindowsNeeded) { mService.mInputMonitor.updateInputWindowsLw(false /*force*/); } - mService.setFocusTaskRegionLocked(); + mService.setFocusTaskRegionLocked(null); // Check to see if we are now in a state where the screen should // be enabled, because the window obscured flags have changed. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 597e8b6ac8fcc..a2946db814252 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2574,13 +2574,18 @@ public class WindowManagerService extends IWindowManager.Stub } } - void setFocusTaskRegionLocked() { + void setFocusTaskRegionLocked(AppWindowToken previousFocus) { final Task focusedTask = mFocusedApp != null ? mFocusedApp.mTask : null; - if (focusedTask != null) { - final DisplayContent displayContent = focusedTask.getDisplayContent(); - if (displayContent != null) { - displayContent.setTouchExcludeRegion(focusedTask); - } + final Task previousTask = previousFocus != null ? previousFocus.mTask : null; + final DisplayContent focusedDisplayContent = + focusedTask != null ? focusedTask.getDisplayContent() : null; + final DisplayContent previousDisplayContent = + previousTask != null ? previousTask.getDisplayContent() : null; + if (previousDisplayContent != null && previousDisplayContent != focusedDisplayContent) { + previousDisplayContent.setTouchExcludeRegion(null); + } + if (focusedDisplayContent != null) { + focusedDisplayContent.setTouchExcludeRegion(focusedTask); } } @@ -2606,9 +2611,10 @@ public class WindowManagerService extends IWindowManager.Stub final boolean changed = mFocusedApp != newFocus; if (changed) { + AppWindowToken prev = mFocusedApp; mFocusedApp = newFocus; mInputMonitor.setFocusedAppLw(newFocus); - setFocusTaskRegionLocked(); + setFocusTaskRegionLocked(prev); } if (moveFocusNow && changed) { @@ -7439,7 +7445,7 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { getDefaultDisplayContentLocked().getDockedDividerController() .setTouchRegion(touchRegion); - setFocusTaskRegionLocked(); + setFocusTaskRegionLocked(null); } }