Use visible frame instead of task bounds for detecting resize start

Initial task bounds might be adjusted (for status bar, etc.). Touch
should be set up using visible frames instead of task bounds.

bug: 24336351
Change-Id: I944e3185a06c39b451432bdda5ad87880a0482f3
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4392ab4..ede377d 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -22,6 +22,7 @@
 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerService.TAG;
 import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
+import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
 
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -255,10 +256,10 @@
     }
 
     /**
-     * Find the id of the task whose outside touch area (for resizing) (x, y)
-     * falls within. Returns -1 if the touch doesn't fall into a resizing area.
+     * Find the window whose outside touch area (for resizing) (x, y) falls within.
+     * Returns null if the touch doesn't fall into a resizing area.
      */
-    int taskIdForControlPoint(int x, int y) {
+    WindowState findWindowForControlPoint(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);
@@ -269,22 +270,31 @@
             for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
                 final Task task = tasks.get(taskNdx);
                 if (task.isFullscreen()) {
-                    return -1;
+                    return null;
                 }
-                task.getBounds(mTmpRect);
-                mTmpRect.inset(-delta, -delta);
-                if (mTmpRect.contains(x, y)) {
-                    mTmpRect.inset(delta, delta);
-                    if (!mTmpRect.contains(x, y)) {
-                        return task.mTaskId;
+
+                // 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.)
+                WindowState win = task.getTopAppMainWindow();
+                if (win != null) {
+                    win.getVisibleBounds(mTmpRect, !BOUNDS_FOR_TOUCH);
+                    mTmpRect.inset(-delta, -delta);
+                    if (mTmpRect.contains(x, y)) {
+                        mTmpRect.inset(delta, delta);
+                        if (!mTmpRect.contains(x, y)) {
+                            return win;
+                        }
+                        // User touched inside the task. No need to look further,
+                        // focus transfer will be handled in ACTION_UP.
+                        return null;
                     }
-                    // User touched inside the task. No need to look further,
-                    // focus transfer will be handled in ACTION_UP.
-                    return -1;
                 }
             }
         }
-        return -1;
+        return null;
     }
 
     void setTouchExcludeRegion(Task focusedTask) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 6ebff42..d1111f7 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -437,6 +437,11 @@
         return mStack != null && mStack.mStackId == DOCKED_STACK_ID;
     }
 
+    WindowState getTopAppMainWindow() {
+        final int tokensCount = mAppTokens.size();
+        return tokensCount > 0 ? mAppTokens.get(tokensCount - 1).findMainWindow() : null;
+    }
+
     @Override
     public boolean isFullscreen() {
         return mFullscreen;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d510c4a..22f9f50 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6885,37 +6885,29 @@
     }
 
     boolean startMovingTask(IWindow window, float startX, float startY) {
-        WindowState callingWin = null;
+        WindowState win = null;
         synchronized (mWindowMap) {
-            callingWin = windowForClientLocked(null, window, false);
-            if (!startPositioningLocked(callingWin, false /*resize*/, startX, startY)) {
+            win = windowForClientLocked(null, window, false);
+            if (!startPositioningLocked(win, false /*resize*/, startX, startY)) {
                 return false;
             }
         }
         try {
-            mActivityManager.setFocusedTask(callingWin.getTask().mTaskId);
+            mActivityManager.setFocusedTask(win.getTask().mTaskId);
         } catch(RemoteException e) {}
         return true;
     }
 
     private void startResizingTask(DisplayContent displayContent, int startX, int startY) {
-        int taskId = -1;
-        AppWindowToken atoken = null;
+        WindowState win = null;
         synchronized (mWindowMap) {
-            taskId = displayContent.taskIdForControlPoint(startX, startY);
-            Task task = mTaskIdToTask.get(taskId);
-            if (task == null || task.mAppTokens == null) {
-                return;
-            }
-            AppTokenList tokens = task.mAppTokens;
-            atoken = tokens.get(tokens.size() - 1);
-            WindowState win = atoken.findMainWindow();
+            win = displayContent.findWindowForControlPoint(startX, startY);
             if (!startPositioningLocked(win, true /*resize*/, startX, startY)) {
                 return;
             }
         }
         try {
-            mActivityManager.setFocusedTask(taskId);
+            mActivityManager.setFocusedTask(win.getTask().mTaskId);
         } catch(RemoteException e) {}
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 64440d3..c73dbaf 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -943,7 +943,6 @@
      */
     void getVisibleBounds(Rect bounds, boolean forTouch) {
         boolean intersectWithStackBounds = mAppToken != null && mAppToken.mCropWindowsToStack;
-        boolean isFreeform = false;
         bounds.setEmpty();
         mTmpRect.setEmpty();
         if (intersectWithStackBounds) {
@@ -955,13 +954,9 @@
             }
         }
 
-        final Task task = getTask();
-        if (task != null) {
-            task.getBounds(bounds);
-            isFreeform = task.inFreeformWorkspace();
-            if (intersectWithStackBounds) {
-                bounds.intersect(mTmpRect);
-            }
+        bounds.set(mVisibleFrame);
+        if (intersectWithStackBounds) {
+            bounds.intersect(mTmpRect);
         }
 
         if (bounds.isEmpty()) {
@@ -971,7 +966,7 @@
             }
             return;
         }
-        if (forTouch && isFreeform) {
+        if (forTouch && inFreeformWorkspace()) {
             final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
             final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics);
             bounds.inset(-delta, -delta);