Merge "Using paged view for all-apps tabs" into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 0c5d961..d5fa723 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -21,7 +21,6 @@
 import static android.view.MotionEvent.ACTION_POINTER_DOWN;
 import static android.view.MotionEvent.ACTION_POINTER_UP;
 import static android.view.MotionEvent.ACTION_UP;
-
 import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
 import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SWITCH;
 
@@ -41,13 +40,15 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.view.ViewTreeObserver;
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.MainThreadExecutor;
-import com.android.launcher3.model.ModelPreload;
 import com.android.launcher3.R;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.model.ModelPreload;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -216,9 +217,6 @@
         }
 
         View target = launcher.getDragLayer();
-        if (!target.getWindowId().isFocused()) {
-            return mNoOpTouchConsumer;
-        }
         return new LauncherTouchConsumer(launcher, target);
     }
 
@@ -244,6 +242,9 @@
 
         @Override
         public void accept(MotionEvent ev) {
+            if (!mTarget.getWindowId().isFocused()) {
+                return;
+            }
             int action = ev.getActionMasked();
             if (action == ACTION_DOWN) {
                 mTrackingStarted = false;
@@ -294,6 +295,12 @@
         public void updateTouchTracking(int interactionType) {
             mMainThreadExecutor.execute(() -> {
                 if (TouchConsumer.isInteractionQuick(interactionType)) {
+                    if (mLauncher.getWorkspace().runOnOverlayHidden(
+                            () -> updateTouchTracking(interactionType))) {
+                        // Hide the minus one overlay so launcher can get window focus.
+                        mLauncher.onQuickstepGestureStarted(true);
+                        return;
+                    }
                     Runnable onComplete = null;
                     if (interactionType == INTERACTION_QUICK_SCRUB) {
                         mQuickScrubController.onQuickScrubStart(true);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 26b91f2..a4ca68a 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -52,6 +52,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 import android.widget.Toast;
 
 import com.android.launcher3.Launcher.LauncherOverlay;
@@ -235,6 +236,7 @@
     boolean mStartedSendingScrollEvents;
     float mLastOverlayScroll = 0;
     boolean mOverlayShown = false;
+    private Runnable mOnOverlayHiddenCallback;
 
     private boolean mForceDrawAdjacentPages = false;
     private boolean mPageRearrangeEnabled = false;
@@ -1161,6 +1163,10 @@
             if (mOverlayShown) {
                 mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
                         Action.Direction.RIGHT, ContainerType.WORKSPACE, -1);
+                if (mOnOverlayHiddenCallback != null) {
+                    mOnOverlayHiddenCallback.run();
+                    mOnOverlayHiddenCallback = null;
+                }
             }
             mOverlayShown = false;
         }
@@ -1186,6 +1192,59 @@
         mLauncher.getDragLayer().setAlpha(alpha);
     }
 
+    /**
+     * Runs the given callback when the minus one overlay is hidden. Specifically, it is run
+     * when launcher's window has focus and the overlay is no longer being shown. If a callback
+     * is already present, the new callback will chain off it so both are run.
+     *
+     * @return Whether the callback was deferred.
+     */
+    public boolean runOnOverlayHidden(Runnable callback) {
+        View rootView = getRootView();
+        if (rootView.hasWindowFocus()) {
+            if (mOverlayShown) {
+                chainOverlayHiddenCallback(callback);
+                return true;
+            } else {
+                callback.run();
+                return false;
+            }
+        }
+        ViewTreeObserver observer = rootView.getViewTreeObserver();
+        if (observer != null && observer.isAlive()) {
+            observer.addOnWindowFocusChangeListener(
+                    new ViewTreeObserver.OnWindowFocusChangeListener() {
+                        @Override
+                        public void onWindowFocusChanged(boolean hasFocus) {
+                            if (hasFocus) {
+                                // Defer further if the minus one overlay is still showing.
+                                if (mOverlayShown) {
+                                    chainOverlayHiddenCallback(callback);
+                                } else {
+                                    callback.run();
+                                }
+                                observer.removeOnWindowFocusChangeListener(this);
+                            }
+                        }
+                    });
+            return true;
+        }
+        return false;
+    }
+
+    private void chainOverlayHiddenCallback(Runnable callback) {
+        if (mOnOverlayHiddenCallback == null) {
+            mOnOverlayHiddenCallback = callback;
+        } else {
+            // Chain the new callback onto the previous callback(s).
+            Runnable oldCallback = mOnOverlayHiddenCallback;
+            mOnOverlayHiddenCallback = () -> {
+                oldCallback.run();
+                callback.run();
+            };
+        }
+    }
+
     @Override
     protected void notifyPageSwitchListener(int prevPage) {
         super.notifyPageSwitchListener(prevPage);