Touching outside the task in overview goes home

There is also a deadzone area around the clear all button to tap easier.

Test: start overview click anywhere that is not the shelf or task
Change-Id: I187ff264444da542aca111b57d94c8199f5a0384
Fixes: 110232233
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index afaad38..49c4492 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -21,6 +21,7 @@
     <dimen name="task_thumbnail_icon_size">48dp</dimen>
     <dimen name="task_corner_radius">2dp</dimen>
     <dimen name="recents_page_spacing">10dp</dimen>
+    <dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen>
     <dimen name="quickscrub_adjacent_visible_width">20dp</dimen>
 
     <!-- The speed in dp/s at which the user needs to be scrolling in recents such that we start
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 9e2de33..261f45d 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -39,7 +39,7 @@
     }
 
     @Override
-    protected void onAllTasksRemoved() {
+    protected void startHome() {
         mActivity.startHome();
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 5aca4f3..7c5828b 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -79,7 +79,7 @@
     }
 
     @Override
-    protected void onAllTasksRemoved() {
+    protected void startHome() {
         mActivity.getStateManager().goToState(NORMAL);
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 92852d2..e18708b 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -55,6 +55,7 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewConfiguration;
 import android.view.ViewDebug;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -127,6 +128,8 @@
     private final RecentsModel mModel;
     private final int mTaskTopMargin;
     private final ClearAllButton mClearAllButton;
+    private final Rect mClearAllButtonDeadZoneRect = new Rect();
+    private final Rect mTaskViewDeadZoneRect = new Rect();
 
     private final ScrollState mScrollState = new ScrollState();
     // Keeps track of the previously known visible tasks for purposes of loading/unloading task data
@@ -230,6 +233,10 @@
     private boolean mHandleTaskStackChanges;
     private Runnable mNextPageSwitchRunnable;
     private boolean mSwipeDownShouldLaunchApp;
+    private boolean mTouchDownToStartHome;
+    private final int mTouchSlop;
+    private int mDownX;
+    private int mDownY;
 
     private PendingAnimation mPendingAnimation;
 
@@ -275,6 +282,7 @@
         setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
         mTaskTopMargin = getResources()
                 .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
+        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
 
         mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
         mEmptyIcon.setCallback(this);
@@ -378,9 +386,45 @@
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         super.onTouchEvent(ev);
-        if (ev.getAction() == MotionEvent.ACTION_UP && mShowEmptyMessage) {
-            onAllTasksRemoved();
+        final int x = (int) ev.getX();
+        final int y = (int) ev.getY();
+        switch (ev.getAction()) {
+            case MotionEvent.ACTION_UP:
+                if (mShowEmptyMessage) {
+                    onAllTasksRemoved();
+                }
+                if (mTouchDownToStartHome) {
+                    startHome();
+                }
+                mTouchDownToStartHome = false;
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                mTouchDownToStartHome = false;
+                break;
+            case MotionEvent.ACTION_MOVE:
+                // Passing the touch slop will not allow dismiss to home
+                if (mTouchDownToStartHome && Math.hypot(mDownX - x, mDownY - y) > mTouchSlop) {
+                    mTouchDownToStartHome = false;
+                }
+                break;
+            case MotionEvent.ACTION_DOWN:
+                // Touch down anywhere but the deadzone around the visible clear all button and
+                // between the task views will start home on touch up
+                if (mTouchState == TOUCH_STATE_REST) {
+                    updateDeadZoneRects();
+                    final boolean clearAllButtonDeadZoneConsumed = mClearAllButton.getAlpha() == 1
+                            && mClearAllButtonDeadZoneRect.contains(x, y);
+                    if (!clearAllButtonDeadZoneConsumed
+                            && !mTaskViewDeadZoneRect.contains(x + getScrollX(), y)) {
+                        mTouchDownToStartHome = true;
+                    }
+                }
+                mDownX = x;
+                mDownY = y;
+                break;
         }
+
+
         // Do not let touch escape to siblings below this view.
         return true;
     }
@@ -599,7 +643,11 @@
         mHasVisibleTaskData.clear();
     }
 
-    protected abstract void onAllTasksRemoved();
+    protected void onAllTasksRemoved() {
+        startHome();
+    }
+
+    protected abstract void startHome();
 
     public void reset() {
         mRunningTaskId = -1;
@@ -1058,6 +1106,27 @@
                 + (getWidth() - mInsets.right - getPaddingRight())) / 2);
     }
 
+    private void updateDeadZoneRects() {
+        // Get the deadzone rect surrounding the clear all button to not dismiss overview to home
+        mClearAllButtonDeadZoneRect.setEmpty();
+        if (mClearAllButton.getWidth() > 0) {
+            int verticalMargin = getResources()
+                    .getDimensionPixelSize(R.dimen.recents_clear_all_deadzone_vertical_margin);
+            mClearAllButton.getHitRect(mClearAllButtonDeadZoneRect);
+            mClearAllButtonDeadZoneRect.inset(-getPaddingRight() / 2, -verticalMargin);
+        }
+
+        // Get the deadzone rect between the task views
+        mTaskViewDeadZoneRect.setEmpty();
+        int count = getTaskViewCount();
+        if (count > 0) {
+            final View taskView = getTaskViewAt(0);
+            getTaskViewAt(count - 1).getHitRect(mTaskViewDeadZoneRect);
+            mTaskViewDeadZoneRect.union(taskView.getLeft(), taskView.getTop(), taskView.getRight(),
+                    taskView.getBottom());
+        }
+    }
+
     private void updateEmptyStateUi(boolean sizeChanged) {
         boolean hasValidSize = getWidth() > 0 && getHeight() > 0;
         if (sizeChanged && hasValidSize) {