Merge "Invoking splitscreen takes snapshot of task without scrim" into ub-launcher3-edmonton-polish
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 0af2b28..17d5c60 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/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index 1e10319..7f956f8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -29,6 +29,7 @@
 import com.android.launcher3.Workspace;
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.quickstep.RecentsModel;
 import com.android.quickstep.views.RecentsView;
 
 /**
@@ -76,6 +77,7 @@
     public void onStateDisabled(Launcher launcher) {
         RecentsView rv = launcher.getOverviewPanel();
         rv.setOverviewStateEnabled(false);
+        RecentsModel.getInstance(launcher).resetAssistCache();
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index c856282..0e811f7 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -78,6 +78,7 @@
     private final MainThreadExecutor mMainThreadExecutor;
     private final Choreographer mBackgroundThreadChoreographer;
     private final OverviewCallbacks mOverviewCallbacks;
+    private final TaskOverlayFactory mTaskOverlayFactory;
 
     private final boolean mIsDeferredDownTarget;
     private final PointF mDownPos = new PointF();
@@ -99,7 +100,7 @@
             RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
             MainThreadExecutor mainThreadExecutor, Choreographer backgroundThreadChoreographer,
             @HitTarget int downHitTarget, OverviewCallbacks overviewCallbacks,
-            VelocityTracker velocityTracker) {
+            TaskOverlayFactory taskOverlayFactory, VelocityTracker velocityTracker) {
         super(base);
 
         mRunningTask = runningTaskInfo;
@@ -111,6 +112,7 @@
         mBackgroundThreadChoreographer = backgroundThreadChoreographer;
         mIsDeferredDownTarget = activityControl.deferStartingActivity(downHitTarget);
         mOverviewCallbacks = overviewCallbacks;
+        mTaskOverlayFactory = taskOverlayFactory;
     }
 
     @Override
@@ -233,14 +235,22 @@
         handler.initWhenReady();
 
         TraceHelper.beginSection("RecentsController");
-        Runnable startActivity = () -> ActivityManagerWrapper.getInstance().startRecentsActivity(
-                mHomeIntent,
+
+        AssistDataReceiver assistDataReceiver = !mTaskOverlayFactory.needAssist() ? null :
                 new AssistDataReceiver() {
                     @Override
                     public void onHandleAssistData(Bundle bundle) {
-                        mRecentsModel.preloadAssistData(mRunningTask.id, bundle);
+                        if (mInteractionHandler == null) {
+                            // Interaction is probably complete
+                            mRecentsModel.preloadAssistData(mRunningTask.id, bundle);
+                        } else if (handler == mInteractionHandler) {
+                            handler.onAssistDataReceived(bundle);
+                        }
                     }
-                }, animationState, null, null);
+                };
+
+        Runnable startActivity = () -> ActivityManagerWrapper.getInstance().startRecentsActivity(
+                mHomeIntent, assistDataReceiver, animationState, null, null);
 
         if (Looper.myLooper() != Looper.getMainLooper()) {
             startActivity.run();
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 9c2c8b3..0c8e47f 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -256,6 +256,10 @@
         }
     }
 
+    public void resetAssistCache() {
+        mCachedAssistData.clear();
+    }
+
     @WorkerThread
     public void preloadAssistData(int taskId, Bundle data) {
         mMainThreadExecutor.execute(() -> {
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index 66969c6..9d3ac6a 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.graphics.Matrix;
+import android.support.annotation.AnyThread;
 import android.view.View;
 
 import com.android.launcher3.R;
@@ -42,6 +43,11 @@
         return sInstance;
     }
 
+    @AnyThread
+    public boolean needAssist() {
+        return false;
+    }
+
     public TaskOverlay createOverlay(View thumbnailView) {
         return new TaskOverlay();
     }
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 49a4ac8..6c54262 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -171,6 +171,7 @@
     private OverviewCommandHelper mOverviewCommandHelper;
     private OverviewInteractionState mOverviewInteractionState;
     private OverviewCallbacks mOverviewCallbacks;
+    private TaskOverlayFactory mTaskOverlayFactory;
 
     private Choreographer mMainThreadChoreographer;
     private Choreographer mBackgroundThreadChoreographer;
@@ -187,6 +188,7 @@
         mEventQueue = new MotionEventQueue(mMainThreadChoreographer, mNoOpTouchConsumer);
         mOverviewInteractionState = OverviewInteractionState.getInstance(this);
         mOverviewCallbacks = OverviewCallbacks.get(this);
+        mTaskOverlayFactory = TaskOverlayFactory.get(this);
 
         sConnected = true;
 
@@ -239,7 +241,7 @@
                             mOverviewCommandHelper.overviewIntent,
                             mOverviewCommandHelper.getActivityControlHelper(), mMainThreadExecutor,
                             mBackgroundThreadChoreographer, downHitTarget, mOverviewCallbacks,
-                            tracker);
+                            mTaskOverlayFactory, tracker);
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 703ea2e..ff3137d 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -37,6 +37,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.SystemClock;
@@ -109,19 +110,21 @@
     private static final int STATE_SCALED_CONTROLLER_APP = 1 << 6;
 
     private static final int STATE_HANDLER_INVALIDATED = 1 << 7;
-    private static final int STATE_GESTURE_STARTED = 1 << 8;
-    private static final int STATE_GESTURE_CANCELLED = 1 << 9;
-    private static final int STATE_GESTURE_COMPLETED = 1 << 10;
+    private static final int STATE_GESTURE_STARTED_QUICKSTEP = 1 << 8;
+    private static final int STATE_GESTURE_STARTED_QUICKSCRUB = 1 << 9;
+    private static final int STATE_GESTURE_CANCELLED = 1 << 10;
+    private static final int STATE_GESTURE_COMPLETED = 1 << 11;
 
     // States for quick switch/scrub
-    private static final int STATE_CURRENT_TASK_FINISHED = 1 << 11;
-    private static final int STATE_QUICK_SCRUB_START = 1 << 12;
-    private static final int STATE_QUICK_SCRUB_END = 1 << 13;
+    private static final int STATE_CURRENT_TASK_FINISHED = 1 << 12;
+    private static final int STATE_QUICK_SCRUB_START = 1 << 13;
+    private static final int STATE_QUICK_SCRUB_END = 1 << 14;
 
-    private static final int STATE_CAPTURE_SCREENSHOT = 1 << 14;
-    private static final int STATE_SCREENSHOT_CAPTURED = 1 << 15;
+    private static final int STATE_CAPTURE_SCREENSHOT = 1 << 15;
+    private static final int STATE_SCREENSHOT_CAPTURED = 1 << 16;
 
-    private static final int STATE_RESUME_LAST_TASK = 1 << 16;
+    private static final int STATE_RESUME_LAST_TASK = 1 << 17;
+    private static final int STATE_ASSIST_DATA_RECEIVED = 1 << 18;
 
     private static final int LAUNCHER_UI_STATES =
             STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE
@@ -145,7 +148,8 @@
             "STATE_SCALED_CONTROLLER_RECENTS",
             "STATE_SCALED_CONTROLLER_APP",
             "STATE_HANDLER_INVALIDATED",
-            "STATE_GESTURE_STARTED",
+            "STATE_GESTURE_STARTED_QUICKSTEP",
+            "STATE_GESTURE_STARTED_QUICKSCRUB",
             "STATE_GESTURE_CANCELLED",
             "STATE_GESTURE_COMPLETED",
             "STATE_CURRENT_TASK_FINISHED",
@@ -154,6 +158,7 @@
             "STATE_CAPTURE_SCREENSHOT",
             "STATE_SCREENSHOT_CAPTURED",
             "STATE_RESUME_LAST_TASK",
+            "STATE_ASSIST_DATA_RECEIVED",
     };
 
     public static final long MAX_SWIPE_DURATION = 350;
@@ -227,6 +232,8 @@
     private float mLongSwipeDisplacement = 0;
     private LongSwipeHelper mLongSwipeController;
 
+    private Bundle mAssistData;
+
     WindowTransformSwipeHandler(int id, RunningTaskInfo runningTaskInfo, Context context,
             long touchTimeMs, ActivityControlHelper<T> controller) {
         this.id = id;
@@ -253,12 +260,19 @@
             }
         };
 
-        mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED,
+        mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED_QUICKSCRUB,
                 this::initializeLauncherAnimationController);
+        mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED_QUICKSTEP,
+                this::initializeLauncherAnimationController);
+
         mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN,
                 this::launcherFrameDrawn);
-        mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_STARTED,
+
+        mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_STARTED_QUICKSTEP,
                 this::notifyGestureStartedAsync);
+        mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_STARTED_QUICKSCRUB,
+                this::notifyGestureStartedAsync);
+
         mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_STARTED
                         | STATE_GESTURE_CANCELLED,
                 this::resetStateForAnimationCancel);
@@ -281,11 +295,15 @@
                 this::finishCurrentTransitionToHome);
 
         mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
-                        | STATE_ACTIVITY_MULTIPLIER_COMPLETE
-                        | STATE_SCALED_CONTROLLER_RECENTS
-                        | STATE_CURRENT_TASK_FINISHED
-                        | STATE_GESTURE_COMPLETED,
+                        | STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_SCALED_CONTROLLER_RECENTS
+                        | STATE_CURRENT_TASK_FINISHED | STATE_GESTURE_COMPLETED
+                        | STATE_GESTURE_STARTED_QUICKSTEP,
                 this::setupLauncherUiAfterSwipeUpAnimation);
+        mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
+                        | STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_SCALED_CONTROLLER_RECENTS
+                        | STATE_CURRENT_TASK_FINISHED | STATE_GESTURE_COMPLETED
+                        | STATE_GESTURE_STARTED_QUICKSTEP | STATE_ASSIST_DATA_RECEIVED,
+                this::preloadAssistData);
 
         mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
         mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
@@ -641,7 +659,8 @@
 
     public void onGestureStarted() {
         notifyGestureStartedAsync();
-        setStateOnUiThread(STATE_GESTURE_STARTED);
+        setStateOnUiThread(mInteractionType == INTERACTION_NORMAL
+                ? STATE_GESTURE_STARTED_QUICKSTEP : STATE_GESTURE_STARTED_QUICKSCRUB);
         mGestureStarted = true;
         mRecentsAnimationWrapper.hideCurrentInputMethod();
         mRecentsAnimationWrapper.enableInputConsumer();
@@ -910,6 +929,9 @@
             return;
         }
         mQuickScrubController.onFinishedTransitionToQuickScrub();
+
+        mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */, true /* animate */);
+        RecentsModel.getInstance(mContext).onOverviewShown(false, TAG);
     }
 
     public void onQuickScrubProgress(float progress) {
@@ -1036,4 +1058,13 @@
         mClipAnimationHelper.setTaskAlphaCallback(provider);
         updateFinalShift();
     }
+
+    public void onAssistDataReceived(Bundle assistData) {
+        mAssistData = assistData;
+        setStateOnUiThread(STATE_ASSIST_DATA_RECEIVED);
+    }
+
+    private void preloadAssistData() {
+        RecentsModel.getInstance(mContext).preloadAssistData(mRunningTaskId, mAssistData);
+    }
 }
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) {
diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
index dba6db3..dcb564a 100644
--- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
@@ -45,6 +45,7 @@
 import com.android.launcher3.widget.WidgetCell;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -81,6 +82,7 @@
     @Test
     public void testEmpty() throws Throwable { /* needed while the broken tests are being fixed */ }
 
+    @Test @Ignore
     public void testPinWidgetNoConfig() throws Throwable {
         runTest("pinWidgetNoConfig", true, new ItemOperator() {
             @Override
@@ -93,6 +95,7 @@
         });
     }
 
+    @Test @Ignore
     public void testPinWidgetNoConfig_customPreview() throws Throwable {
         // Command to set custom preview
         Intent command =  RequestPinItemActivity.getCommandIntent(
@@ -110,6 +113,7 @@
         }, command);
     }
 
+    @Test @Ignore
     public void testPinWidgetWithConfig() throws Throwable {
         runTest("pinWidgetWithConfig", true, new ItemOperator() {
             @Override
@@ -122,6 +126,7 @@
         });
     }
 
+    @Test @Ignore
     public void testPinShortcut() throws Throwable {
         // Command to set the shortcut id
         Intent command = RequestPinItemActivity.getCommandIntent(