Loading services/core/java/com/android/server/wm/DisplayContent.java +55 −48 Original line number Diff line number Diff line Loading @@ -291,27 +291,29 @@ class DisplayContent { final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks(); for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { final Task task = tasks.get(taskNdx); // We need to use the visible frame on the window for any touch-related tests. // Can't use the task's bounds because the original task bounds might be adjusted // to fit the content frame. For example, the presence of the IME adjusting the final WindowState win = task.getTopVisibleAppMainWindow(); if (win == null) { continue; } // We need to use the task's dim bounds (which is derived from the visible // bounds of its apps windows) for any touch-related tests. Can't use // the task's original bounds because it might be adjusted to fit the // content frame. For example, the presence of the IME adjusting the // windows frames when the app window is the IME target. final WindowState win = task.getTopAppMainWindow(); if (win != null) { win.getVisibleBounds(mTmpRect); task.getDimBounds(mTmpRect); if (mTmpRect.contains(x, y)) { return task.mTaskId; } } } } return -1; } /** * Find the window whose outside touch area (for resizing) (x, y) falls within. * Find the task whose outside touch area (for resizing) (x, y) falls within. * Returns null if the touch doesn't fall into a resizing area. */ WindowState findWindowForControlPoint(int x, int y) { Task findTaskForControlPoint(int x, int y) { final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics); for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { TaskStack stack = mStacks.get(stackNdx); Loading @@ -325,19 +327,18 @@ class DisplayContent { return null; } // We need to use the visible frame on the window for any touch-related // tests. Can't use the task's bounds because the original task bounds // might be adjusted to fit the content frame. (One example is when the // task is put to top-left quadrant, the actual visible frame would not // start at (0,0) after it's adjusted for the status bar.) final WindowState win = task.getTopAppMainWindow(); if (win != null) { win.getVisibleBounds(mTmpRect); // We need to use the task's dim bounds (which is derived from the visible // bounds of its apps windows) for any touch-related tests. Can't use // the task's original bounds because it might be adjusted to fit the // content frame. One example is when the task is put to top-left quadrant, // the actual visible area would not start at (0,0) after it's adjusted // for the status bar. task.getDimBounds(mTmpRect); mTmpRect.inset(-delta, -delta); if (mTmpRect.contains(x, y)) { mTmpRect.inset(delta, delta); if (!mTmpRect.contains(x, y)) { return win; return task; } // User touched inside the task. No need to look further, // focus transfer will be handled in ACTION_UP. Loading @@ -345,18 +346,23 @@ class DisplayContent { } } } } return null; } void setTouchExcludeRegion(Task focusedTask) { mTouchExcludeRegion.set(mBaseDisplayRect); WindowList windows = getWindowList(); final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics); for (int i = windows.size() - 1; i >= 0; --i) { final WindowState win = windows.get(i); final Task task = win.getTask(); if (win.isVisibleLw() && task != null) { boolean addBackFocusedTask = false; for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { TaskStack stack = mStacks.get(stackNdx); final ArrayList<Task> tasks = stack.getTasks(); for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { final Task task = tasks.get(taskNdx); final WindowState win = task.getTopVisibleAppMainWindow(); if (win == null) { continue; } /** * Exclusion region is the region that TapDetector doesn't care about. * Here we want to remove all non-focused tasks from the exclusion region. Loading @@ -368,13 +374,17 @@ class DisplayContent { */ final boolean isFreeformed = task.inFreeformWorkspace(); if (task != focusedTask || isFreeformed) { mTmpRect.set(win.mVisibleFrame); mTmpRect.intersect(win.mVisibleInsets); /** * If the task is freeformed, enlarge the area to account for outside * touch area for resize. */ task.getDimBounds(mTmpRect); if (isFreeformed) { // If we're removing a freeform, focused app from the exclusion region, // we need to add back its touchable frame later. Remember the touchable // frame now. if (task == focusedTask) { addBackFocusedTask = true; mTmpRect2.set(mTmpRect); } // If the task is freeformed, enlarge the area to account for outside // touch area for resize. mTmpRect.inset(-delta, -delta); // Intersect with display content rect. If we have system decor (status bar/ // navigation bar), we want to exclude that from the tap detection. Loading @@ -385,16 +395,13 @@ class DisplayContent { } mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE); } /** * 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 (task == focusedTask && isFreeformed) { mTmpRect.inset(delta, delta); mTouchExcludeRegion.op(mTmpRect, Region.Op.UNION); } } // 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 (addBackFocusedTask) { mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION); } if (mTapDetector != null) { mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion); Loading services/core/java/com/android/server/wm/Task.java +18 −7 Original line number Diff line number Diff line Loading @@ -284,7 +284,12 @@ class Task implements DimLayer.DimLayerUser { boolean getMaxVisibleBounds(Rect out) { boolean foundTop = false; for (int i = mAppTokens.size() - 1; i >= 0; i--) { final WindowState win = mAppTokens.get(i).findMainWindow(); final AppWindowToken token = mAppTokens.get(i); // skip hidden (or about to hide) apps if (token.mIsExiting || token.clientHidden || token.hiddenRequested) { continue; } final WindowState win = token.findMainWindow(); if (win == null) { continue; } Loading Loading @@ -413,14 +418,20 @@ class Task implements DimLayer.DimLayerUser { return mStack != null && mStack.mStackId == DOCKED_STACK_ID; } WindowState getTopAppMainWindow() { final int tokensCount = mAppTokens.size(); return tokensCount > 0 ? mAppTokens.get(tokensCount - 1).findMainWindow() : null; WindowState getTopVisibleAppMainWindow() { final AppWindowToken token = getTopVisibleAppToken(); return token != null ? token.findMainWindow() : null; } AppWindowToken getTopAppWindowToken() { final int tokensCount = mAppTokens.size(); return tokensCount > 0 ? mAppTokens.get(tokensCount - 1) : null; AppWindowToken getTopVisibleAppToken() { for (int i = mAppTokens.size() - 1; i >= 0; i--) { final AppWindowToken token = mAppTokens.get(i); // skip hidden (or about to hide) apps if (!token.mIsExiting && !token.clientHidden && !token.hiddenRequested) { return token; } } return null; } @Override Loading services/core/java/com/android/server/wm/TaskPositioner.java +16 −12 Original line number Diff line number Diff line Loading @@ -332,30 +332,34 @@ class TaskPositioner implements DimLayer.DimLayerUser { + ", {" + startX + ", " + startY + "}"); } mCtrlType = CTRL_NONE; mTask = win.getTask(); mStartDragX = startX; mStartDragY = startY; // Use the dim bounds, not the original task bounds. The cursor // movement should be calculated relative to the visible bounds. // Also, use the dim bounds of the task which accounts for // multiple app windows. Don't use any bounds from win itself as it // may not be the same size as the task. mTask.getDimBounds(mTmpRect); if (resize) { final Rect visibleFrame = win.mVisibleFrame; if (startX < visibleFrame.left) { if (startX < mTmpRect.left) { mCtrlType |= CTRL_LEFT; } if (startX > visibleFrame.right) { if (startX > mTmpRect.right) { mCtrlType |= CTRL_RIGHT; } if (startY < visibleFrame.top) { if (startY < mTmpRect.top) { mCtrlType |= CTRL_TOP; } if (startY > visibleFrame.bottom) { if (startY > mTmpRect.bottom) { mCtrlType |= CTRL_BOTTOM; } mResizing = true; } mTask = win.getTask(); mStartDragX = startX; mStartDragY = startY; // Use the visible bounds, not the original task bounds. The cursor // movement should be calculated relative to the visible bounds. mWindowOriginalBounds.set(win.mVisibleFrame); mWindowOriginalBounds.set(mTmpRect); } private void endDragLocked() { Loading services/core/java/com/android/server/wm/TaskTapPointerEventListener.java +3 −3 Original line number Diff line number Diff line Loading @@ -90,11 +90,11 @@ public class TaskTapPointerEventListener implements PointerEventListener { case MotionEvent.ACTION_HOVER_MOVE: { final int x = (int) motionEvent.getX(); final int y = (int) motionEvent.getY(); final WindowState window = mDisplayContent.findWindowForControlPoint(x, y); if (window == null) { final Task task = mDisplayContent.findTaskForControlPoint(x, y); if (task == null) { break; } window.getVisibleBounds(mTmpRect); task.getDimBounds(mTmpRect); if (!mTmpRect.isEmpty() && !mTmpRect.contains(x, y)) { int iconShape = STYLE_DEFAULT; if (x < mTmpRect.left) { Loading services/core/java/com/android/server/wm/WindowManagerService.java +5 −4 Original line number Diff line number Diff line Loading @@ -7069,15 +7069,16 @@ public class WindowManagerService extends IWindowManager.Stub } private void startResizingTask(DisplayContent displayContent, int startX, int startY) { WindowState win = null; Task task = null; synchronized (mWindowMap) { win = displayContent.findWindowForControlPoint(startX, startY); if (win == null || !startPositioningLocked(win, true /*resize*/, startX, startY)) { task = displayContent.findTaskForControlPoint(startX, startY); if (task == null || !startPositioningLocked( task.getTopVisibleAppMainWindow(), true /*resize*/, startX, startY)) { return; } } try { mActivityManager.setFocusedTask(win.getTask().mTaskId); mActivityManager.setFocusedTask(task.mTaskId); } catch(RemoteException e) {} } Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +55 −48 Original line number Diff line number Diff line Loading @@ -291,27 +291,29 @@ class DisplayContent { final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks(); for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { final Task task = tasks.get(taskNdx); // We need to use the visible frame on the window for any touch-related tests. // Can't use the task's bounds because the original task bounds might be adjusted // to fit the content frame. For example, the presence of the IME adjusting the final WindowState win = task.getTopVisibleAppMainWindow(); if (win == null) { continue; } // We need to use the task's dim bounds (which is derived from the visible // bounds of its apps windows) for any touch-related tests. Can't use // the task's original bounds because it might be adjusted to fit the // content frame. For example, the presence of the IME adjusting the // windows frames when the app window is the IME target. final WindowState win = task.getTopAppMainWindow(); if (win != null) { win.getVisibleBounds(mTmpRect); task.getDimBounds(mTmpRect); if (mTmpRect.contains(x, y)) { return task.mTaskId; } } } } return -1; } /** * Find the window whose outside touch area (for resizing) (x, y) falls within. * Find the task whose outside touch area (for resizing) (x, y) falls within. * Returns null if the touch doesn't fall into a resizing area. */ WindowState findWindowForControlPoint(int x, int y) { Task findTaskForControlPoint(int x, int y) { final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics); for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { TaskStack stack = mStacks.get(stackNdx); Loading @@ -325,19 +327,18 @@ class DisplayContent { return null; } // We need to use the visible frame on the window for any touch-related // tests. Can't use the task's bounds because the original task bounds // might be adjusted to fit the content frame. (One example is when the // task is put to top-left quadrant, the actual visible frame would not // start at (0,0) after it's adjusted for the status bar.) final WindowState win = task.getTopAppMainWindow(); if (win != null) { win.getVisibleBounds(mTmpRect); // We need to use the task's dim bounds (which is derived from the visible // bounds of its apps windows) for any touch-related tests. Can't use // the task's original bounds because it might be adjusted to fit the // content frame. One example is when the task is put to top-left quadrant, // the actual visible area would not start at (0,0) after it's adjusted // for the status bar. task.getDimBounds(mTmpRect); mTmpRect.inset(-delta, -delta); if (mTmpRect.contains(x, y)) { mTmpRect.inset(delta, delta); if (!mTmpRect.contains(x, y)) { return win; return task; } // User touched inside the task. No need to look further, // focus transfer will be handled in ACTION_UP. Loading @@ -345,18 +346,23 @@ class DisplayContent { } } } } return null; } void setTouchExcludeRegion(Task focusedTask) { mTouchExcludeRegion.set(mBaseDisplayRect); WindowList windows = getWindowList(); final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics); for (int i = windows.size() - 1; i >= 0; --i) { final WindowState win = windows.get(i); final Task task = win.getTask(); if (win.isVisibleLw() && task != null) { boolean addBackFocusedTask = false; for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { TaskStack stack = mStacks.get(stackNdx); final ArrayList<Task> tasks = stack.getTasks(); for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { final Task task = tasks.get(taskNdx); final WindowState win = task.getTopVisibleAppMainWindow(); if (win == null) { continue; } /** * Exclusion region is the region that TapDetector doesn't care about. * Here we want to remove all non-focused tasks from the exclusion region. Loading @@ -368,13 +374,17 @@ class DisplayContent { */ final boolean isFreeformed = task.inFreeformWorkspace(); if (task != focusedTask || isFreeformed) { mTmpRect.set(win.mVisibleFrame); mTmpRect.intersect(win.mVisibleInsets); /** * If the task is freeformed, enlarge the area to account for outside * touch area for resize. */ task.getDimBounds(mTmpRect); if (isFreeformed) { // If we're removing a freeform, focused app from the exclusion region, // we need to add back its touchable frame later. Remember the touchable // frame now. if (task == focusedTask) { addBackFocusedTask = true; mTmpRect2.set(mTmpRect); } // If the task is freeformed, enlarge the area to account for outside // touch area for resize. mTmpRect.inset(-delta, -delta); // Intersect with display content rect. If we have system decor (status bar/ // navigation bar), we want to exclude that from the tap detection. Loading @@ -385,16 +395,13 @@ class DisplayContent { } mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE); } /** * 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 (task == focusedTask && isFreeformed) { mTmpRect.inset(delta, delta); mTouchExcludeRegion.op(mTmpRect, Region.Op.UNION); } } // 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 (addBackFocusedTask) { mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION); } if (mTapDetector != null) { mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion); Loading
services/core/java/com/android/server/wm/Task.java +18 −7 Original line number Diff line number Diff line Loading @@ -284,7 +284,12 @@ class Task implements DimLayer.DimLayerUser { boolean getMaxVisibleBounds(Rect out) { boolean foundTop = false; for (int i = mAppTokens.size() - 1; i >= 0; i--) { final WindowState win = mAppTokens.get(i).findMainWindow(); final AppWindowToken token = mAppTokens.get(i); // skip hidden (or about to hide) apps if (token.mIsExiting || token.clientHidden || token.hiddenRequested) { continue; } final WindowState win = token.findMainWindow(); if (win == null) { continue; } Loading Loading @@ -413,14 +418,20 @@ class Task implements DimLayer.DimLayerUser { return mStack != null && mStack.mStackId == DOCKED_STACK_ID; } WindowState getTopAppMainWindow() { final int tokensCount = mAppTokens.size(); return tokensCount > 0 ? mAppTokens.get(tokensCount - 1).findMainWindow() : null; WindowState getTopVisibleAppMainWindow() { final AppWindowToken token = getTopVisibleAppToken(); return token != null ? token.findMainWindow() : null; } AppWindowToken getTopAppWindowToken() { final int tokensCount = mAppTokens.size(); return tokensCount > 0 ? mAppTokens.get(tokensCount - 1) : null; AppWindowToken getTopVisibleAppToken() { for (int i = mAppTokens.size() - 1; i >= 0; i--) { final AppWindowToken token = mAppTokens.get(i); // skip hidden (or about to hide) apps if (!token.mIsExiting && !token.clientHidden && !token.hiddenRequested) { return token; } } return null; } @Override Loading
services/core/java/com/android/server/wm/TaskPositioner.java +16 −12 Original line number Diff line number Diff line Loading @@ -332,30 +332,34 @@ class TaskPositioner implements DimLayer.DimLayerUser { + ", {" + startX + ", " + startY + "}"); } mCtrlType = CTRL_NONE; mTask = win.getTask(); mStartDragX = startX; mStartDragY = startY; // Use the dim bounds, not the original task bounds. The cursor // movement should be calculated relative to the visible bounds. // Also, use the dim bounds of the task which accounts for // multiple app windows. Don't use any bounds from win itself as it // may not be the same size as the task. mTask.getDimBounds(mTmpRect); if (resize) { final Rect visibleFrame = win.mVisibleFrame; if (startX < visibleFrame.left) { if (startX < mTmpRect.left) { mCtrlType |= CTRL_LEFT; } if (startX > visibleFrame.right) { if (startX > mTmpRect.right) { mCtrlType |= CTRL_RIGHT; } if (startY < visibleFrame.top) { if (startY < mTmpRect.top) { mCtrlType |= CTRL_TOP; } if (startY > visibleFrame.bottom) { if (startY > mTmpRect.bottom) { mCtrlType |= CTRL_BOTTOM; } mResizing = true; } mTask = win.getTask(); mStartDragX = startX; mStartDragY = startY; // Use the visible bounds, not the original task bounds. The cursor // movement should be calculated relative to the visible bounds. mWindowOriginalBounds.set(win.mVisibleFrame); mWindowOriginalBounds.set(mTmpRect); } private void endDragLocked() { Loading
services/core/java/com/android/server/wm/TaskTapPointerEventListener.java +3 −3 Original line number Diff line number Diff line Loading @@ -90,11 +90,11 @@ public class TaskTapPointerEventListener implements PointerEventListener { case MotionEvent.ACTION_HOVER_MOVE: { final int x = (int) motionEvent.getX(); final int y = (int) motionEvent.getY(); final WindowState window = mDisplayContent.findWindowForControlPoint(x, y); if (window == null) { final Task task = mDisplayContent.findTaskForControlPoint(x, y); if (task == null) { break; } window.getVisibleBounds(mTmpRect); task.getDimBounds(mTmpRect); if (!mTmpRect.isEmpty() && !mTmpRect.contains(x, y)) { int iconShape = STYLE_DEFAULT; if (x < mTmpRect.left) { Loading
services/core/java/com/android/server/wm/WindowManagerService.java +5 −4 Original line number Diff line number Diff line Loading @@ -7069,15 +7069,16 @@ public class WindowManagerService extends IWindowManager.Stub } private void startResizingTask(DisplayContent displayContent, int startX, int startY) { WindowState win = null; Task task = null; synchronized (mWindowMap) { win = displayContent.findWindowForControlPoint(startX, startY); if (win == null || !startPositioningLocked(win, true /*resize*/, startX, startY)) { task = displayContent.findTaskForControlPoint(startX, startY); if (task == null || !startPositioningLocked( task.getTopVisibleAppMainWindow(), true /*resize*/, startX, startY)) { return; } } try { mActivityManager.setFocusedTask(win.getTask().mTaskId); mActivityManager.setFocusedTask(task.mTaskId); } catch(RemoteException e) {} } Loading