Merge "Enables searching when using work tabs together with fallback search." into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java
index ba88f99..34ed7f1 100644
--- a/quickstep/src/com/android/quickstep/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/RecentsView.java
@@ -48,6 +48,11 @@
     /** A circular curve of x from 0 to 1, where 0 is the center of the screen and 1 is the edge. */
     private static final TimeInterpolator CURVE_INTERPOLATOR
         = x -> (float) (1 - Math.sqrt(1 - Math.pow(x, 2)));
+    /**
+     * The alpha of a black scrim on a page in the carousel as it leaves the screen.
+     * In the resting position of the carousel, the adjacent pages have about half this scrim.
+     */
+    private static final float MAX_PAGE_SCRIM_ALPHA = 0.8f;
 
     private boolean mOverviewStateEnabled;
     private boolean mTaskStackListenerRegistered;
@@ -181,8 +186,8 @@
     }
 
     @Override
-    public void scrollTo(int x, int y) {
-        super.scrollTo(x, y);
+    public void computeScroll() {
+        super.computeScroll();
         updateCurveProperties();
     }
 
@@ -212,6 +217,10 @@
             // Make sure the biggest card (i.e. the one in front) shows on top of the adjacent ones.
             page.setTranslationZ(scale);
             page.setTranslationX((screenCenter - pageCenter) * curveInterpolation * CURVE_FACTOR);
+            if (page instanceof TaskView) {
+                TaskThumbnailView thumbnail = ((TaskView) page).getThumbnail();
+                thumbnail.setDimAlpha(1 - curveInterpolation * MAX_PAGE_SCRIM_ALPHA);
+            }
         }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/TaskView.java b/quickstep/src/com/android/quickstep/TaskView.java
index 029afd6..ac9a778 100644
--- a/quickstep/src/com/android/quickstep/TaskView.java
+++ b/quickstep/src/com/android/quickstep/TaskView.java
@@ -62,6 +62,7 @@
 
     @Override
     protected void onFinishInflate() {
+        super.onFinishInflate();
         mSnapshotView = findViewById(R.id.snapshot);
         mIconView = findViewById(R.id.icon);
     }
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index eacc393..7b220d8 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -15,8 +15,15 @@
  */
 package com.android.quickstep;
 
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+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 android.view.MotionEvent.INVALID_POINTER_ID;
 
+import android.annotation.TargetApi;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityOptions;
 import android.app.Service;
@@ -29,6 +36,7 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -37,9 +45,12 @@
 import android.view.Display;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
+import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
 
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.R;
 import com.android.launcher3.util.TraceHelper;
@@ -51,9 +62,12 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.BackgroundExecutor;
 
+import java.util.function.Consumer;
+
 /**
  * Service connected by system-UI for handling touch interaction.
  */
+@TargetApi(Build.VERSION_CODES.O)
 public class TouchInteractionService extends Service {
 
     private static final String TAG = "TouchInteractionService";
@@ -73,6 +87,10 @@
         }
     };
 
+    private final Consumer<MotionEvent> mOtherActivityTouchConsumer
+            = this::handleTouchDownOnOtherActivity;
+    private final Consumer<MotionEvent> mNoOpTouchConsumer = (ev) -> {};
+
     private ActivityManagerWrapper mAM;
     private RunningTaskInfo mRunningTask;
     private Intent mHomeIntent;
@@ -80,8 +98,6 @@
     private MotionEventQueue mEventQueue;
     private MainThreadExecutor mMainThreadExecutor;
 
-    private int mDisplayRotation;
-    private final Point mDisplaySize = new Point();
     private final PointF mDownPos = new PointF();
     private final PointF mLastPos = new PointF();
     private int mActivePointerId = INVALID_POINTER_ID;
@@ -91,6 +107,7 @@
     private NavBarSwipeInteractionHandler mInteractionHandler;
 
     private ISystemUiProxy mISystemUiProxy;
+    private Consumer<MotionEvent> mCurrentConsumer = mNoOpTouchConsumer;
 
     @Override
     public void onCreate() {
@@ -128,25 +145,31 @@
     }
 
     private void handleMotionEvent(MotionEvent ev) {
-        if (ev.getActionMasked() != MotionEvent.ACTION_DOWN && mVelocityTracker == null) {
+        if (ev.getActionMasked() == ACTION_DOWN) {
+            mRunningTask = mAM.getRunningTask();
+
+            if (mRunningTask == null) {
+                mCurrentConsumer = mNoOpTouchConsumer;
+            } else if (mRunningTask.topActivity.equals(mLauncher)) {
+                mCurrentConsumer = getLauncherConsumer();
+            } else {
+                mCurrentConsumer = mOtherActivityTouchConsumer;
+            }
+        }
+        mCurrentConsumer.accept(ev);
+    }
+
+    private void handleTouchDownOnOtherActivity(MotionEvent ev) {
+        if (ev.getActionMasked() != ACTION_DOWN && mVelocityTracker == null) {
             return;
         }
         switch (ev.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN: {
+            case ACTION_DOWN: {
                 TraceHelper.beginSection("TouchInt");
                 mActivePointerId = ev.getPointerId(0);
                 mDownPos.set(ev.getX(), ev.getY());
                 mLastPos.set(mDownPos);
                 mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
-                Display display = getSystemService(WindowManager.class).getDefaultDisplay();
-                display.getRealSize(mDisplaySize);
-                mDisplayRotation = display.getRotation();
-
-                mRunningTask = mAM.getRunningTask();
-                if (mRunningTask == null || mRunningTask.topActivity.equals(mLauncher)) {
-                    // TODO: We could drive all-apps in this case. For now just ignore swipe.
-                    break;
-                }
 
                 if (mVelocityTracker == null) {
                     mVelocityTracker = VelocityTracker.obtain();
@@ -160,7 +183,7 @@
                 }
                 break;
             }
-            case MotionEvent.ACTION_POINTER_UP: {
+            case ACTION_POINTER_UP: {
                 int ptrIdx = ev.getActionIndex();
                 int ptrId = ev.getPointerId(ptrIdx);
                 if (ptrId == mActivePointerId) {
@@ -174,7 +197,7 @@
                 }
                 break;
             }
-            case MotionEvent.ACTION_MOVE: {
+            case ACTION_MOVE: {
                 int pointerIndex = ev.findPointerIndex(mActivePointerId);
                 if (pointerIndex == INVALID_POINTER_ID) {
                     break;
@@ -194,17 +217,19 @@
                 }
                 break;
             }
-            case MotionEvent.ACTION_CANCEL:
+            case ACTION_CANCEL:
                 // TODO: Should be different than ACTION_UP
-            case MotionEvent.ACTION_UP: {
+            case ACTION_UP: {
                 TraceHelper.endSection("TouchInt");
 
                 endInteraction();
+                mCurrentConsumer = mNoOpTouchConsumer;
                 break;
             }
         }
     }
 
+
     private void startTouchTracking() {
         // Create the shared handler
         final NavBarSwipeInteractionHandler handler =
@@ -262,9 +287,12 @@
 
         TraceHelper.beginSection("TaskSnapshot");
         // TODO: We are using some hardcoded layers for now, to best approximate the activity layers
+        Point displaySize = new Point();
+        Display display = getSystemService(WindowManager.class).getDefaultDisplay();
+        display.getRealSize(displaySize);
         try {
-            return mISystemUiProxy.screenshot(new Rect(), mDisplaySize.x, mDisplaySize.y, 0, 100000,
-                    false, mDisplayRotation).toBitmap();
+            return mISystemUiProxy.screenshot(new Rect(), displaySize.x, displaySize.y, 0, 100000,
+                    false, display.getRotation()).toBitmap();
         } catch (RemoteException e) {
             Log.e(TAG, "Error capturing snapshot", e);
             return null;
@@ -272,4 +300,76 @@
             TraceHelper.endSection("TaskSnapshot");
         }
     }
+
+    private Consumer<MotionEvent> getLauncherConsumer() {
+
+        Launcher launcher = (Launcher) LauncherAppState.getInstance(this).getModel().getCallback();
+        if (launcher == null) {
+            return mNoOpTouchConsumer;
+        }
+
+        View target = launcher.getDragLayer();
+        if (!target.getWindowId().isFocused()) {
+            return mNoOpTouchConsumer;
+        }
+        return new LauncherTouchConsumer(target);
+    }
+
+    private class LauncherTouchConsumer implements Consumer<MotionEvent> {
+
+        private final View mTarget;
+        private final int[] mLocationOnScreen = new int[2];
+
+        private boolean mTrackingStarted = false;
+
+        LauncherTouchConsumer(View target) {
+            mTarget = target;
+        }
+
+        @Override
+        public void accept(MotionEvent ev) {
+            int action = ev.getActionMasked();
+            if (action == ACTION_DOWN) {
+                mTrackingStarted = false;
+                mDownPos.set(ev.getX(), ev.getY());
+                mTouchSlop = ViewConfiguration.get(mTarget.getContext()).getScaledTouchSlop();
+            } else if (!mTrackingStarted) {
+                switch (action) {
+                    case ACTION_POINTER_UP:
+                    case ACTION_POINTER_DOWN:
+                        if (!mTrackingStarted) {
+                            mCurrentConsumer = mNoOpTouchConsumer;
+                        }
+                        break;
+                    case ACTION_MOVE: {
+                        float displacement = ev.getY() - mDownPos.y;
+                        if (Math.abs(displacement) >= mTouchSlop) {
+                            mTrackingStarted = true;
+                            mTarget.getLocationOnScreen(mLocationOnScreen);
+
+                            // Send a down event only when mTouchSlop is crossed.
+                            MotionEvent down = MotionEvent.obtain(ev);
+                            down.setAction(ACTION_DOWN);
+                            sendEvent(down);
+                            down.recycle();
+                        }
+                    }
+                }
+            }
+
+            if (mTrackingStarted) {
+                sendEvent(ev);
+            }
+
+            if (action == ACTION_UP || action == ACTION_CANCEL) {
+                mCurrentConsumer = mNoOpTouchConsumer;
+            }
+        }
+
+        private void sendEvent(MotionEvent ev) {
+            ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
+            mTarget.dispatchTouchEvent(ev);
+            ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
+        }
+    }
 }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index b7986da..44b64d9 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1969,7 +1969,8 @@
         final ShortcutInfo shortcut = (ShortcutInfo) tag;
 
         if (shortcut.isDisabled()) {
-            if ((shortcut.runtimeStatusFlags &
+            final int disabledFlags = shortcut.runtimeStatusFlags & ShortcutInfo.FLAG_DISABLED_MASK;
+            if ((disabledFlags &
                     ~FLAG_DISABLED_SUSPENDED &
                     ~FLAG_DISABLED_QUIET_USER) == 0) {
                 // If the app is only disabled because of the above flags, launch activity anyway.