Merge "Revert "Converting even more tests to TAPL"" into ub-launcher3-qt-dev
diff --git a/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
index 4582243..cbc77d2 100644
--- a/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
+++ b/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
@@ -89,4 +89,6 @@
     public static RotationMode getRotationMode(DeviceProfile dp) {
         return RotationMode.NORMAL;
     }
+
+    public static void clearSwipeSharedState(boolean finishAnimation) {}
 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
index 8d5ac50..6ecf1c1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
@@ -46,6 +46,7 @@
 import com.android.launcher3.util.UiThreadHelper.AsyncCommand;
 import com.android.quickstep.SysUINavigationMode;
 import com.android.quickstep.SysUINavigationMode.Mode;
+import com.android.quickstep.TouchInteractionService;
 import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
@@ -184,6 +185,13 @@
     }
 
     /**
+     * Clears the swipe shared state for the current swipe gesture.
+     */
+    public static void clearSwipeSharedState(boolean finishAnimation) {
+        TouchInteractionService.getSwipeSharedState().clearAllState(finishAnimation);
+    }
+
+    /**
      * Recents logic that triggers when launcher state changes or launcher activity stops/resumes.
      *
      * @param launcher the launcher activity
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
index 6689ce3..c55f656 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
@@ -72,13 +72,15 @@
         mLastAnimationRunning = false;
     }
 
-    private void clearListenerState() {
+    private void clearListenerState(boolean finishAnimation) {
         if (mRecentsAnimationListener != null) {
             mRecentsAnimationListener.removeListener(this);
             mRecentsAnimationListener.cancelListener();
             if (mLastAnimationRunning && mLastAnimationTarget != null) {
                 Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(),
-                        mLastAnimationTarget::cancelAnimation);
+                        finishAnimation
+                                ? mLastAnimationTarget::finishAnimation
+                                : mLastAnimationTarget::cancelAnimation);
                 mLastAnimationTarget = null;
             }
         }
@@ -106,7 +108,7 @@
             }
         }
 
-        clearListenerState();
+        clearListenerState(false /* finishAnimation */);
         boolean shouldMinimiseSplitScreen = mOverviewComponentObserver == null ? false
                 : mOverviewComponentObserver.getActivityControlHelper().shouldMinimizeSplitScreen();
         mRecentsAnimationListener = new RecentsAnimationListenerSet(
@@ -138,8 +140,8 @@
         mLastAnimationTarget = mLastAnimationTarget.cloneWithoutTargets();
     }
 
-    public void clearAllState() {
-        clearListenerState();
+    public void clearAllState(boolean finishAnimation) {
+        clearListenerState(finishAnimation);
         canGestureBeContinued = false;
         recentsAnimationFinishInterrupted = false;
         nextRunningTaskId = -1;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 8f08f0d..53da0f9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -225,14 +225,18 @@
     };
 
     private static boolean sConnected = false;
+    private static final SwipeSharedState sSwipeSharedState = new SwipeSharedState();
 
     public static boolean isConnected() {
         return sConnected;
     }
 
-    private final SwipeSharedState mSwipeSharedState = new SwipeSharedState();
+    public static SwipeSharedState getSwipeSharedState() {
+        return sSwipeSharedState;
+    }
+
     private final InputConsumer mResetGestureInputConsumer =
-            new ResetGestureInputConsumer(mSwipeSharedState);
+            new ResetGestureInputConsumer(sSwipeSharedState);
 
     private ActivityManagerWrapper mAM;
     private RecentsModel mRecentsModel;
@@ -436,7 +440,7 @@
         mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
         mIsUserUnlocked = true;
 
-        mSwipeSharedState.setOverviewComponentObserver(mOverviewComponentObserver);
+        sSwipeSharedState.setOverviewComponentObserver(mOverviewComponentObserver);
         mInputConsumer.registerInputConsumer();
         onSystemUiProxySet();
         onSystemUiFlagsChanged();
@@ -589,7 +593,7 @@
     private InputConsumer newBaseConsumer(boolean useSharedState, MotionEvent event) {
         final RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
         if (!useSharedState) {
-            mSwipeSharedState.clearAllState();
+            sSwipeSharedState.clearAllState(false /* finishAnimation */);
         }
         if ((mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0) {
             // This handles apps showing over the lockscreen (e.g. camera)
@@ -599,16 +603,16 @@
         final ActivityControlHelper activityControl =
                 mOverviewComponentObserver.getActivityControlHelper();
 
-        if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher
-                && !mSwipeSharedState.recentsAnimationFinishInterrupted) {
+        if (runningTaskInfo == null && !sSwipeSharedState.goingToLauncher
+                && !sSwipeSharedState.recentsAnimationFinishInterrupted) {
             return mResetGestureInputConsumer;
-        } else if (mSwipeSharedState.recentsAnimationFinishInterrupted) {
+        } else if (sSwipeSharedState.recentsAnimationFinishInterrupted) {
             // If the finish animation was interrupted, then continue using the other activity input
             // consumer but with the next task as the running task
             RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
-            info.id = mSwipeSharedState.nextRunningTaskId;
+            info.id = sSwipeSharedState.nextRunningTaskId;
             return createOtherActivityInputConsumer(event, info);
-        } else if (mSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
+        } else if (sSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
             return createOverviewInputConsumer(event);
         } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) {
             return createOverviewInputConsumer(event);
@@ -617,7 +621,7 @@
             return mResetGestureInputConsumer;
         } else if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) {
             return new FallbackNoButtonInputConsumer(this, activityControl,
-                    mInputMonitorCompat, mSwipeSharedState, mSwipeTouchRegion,
+                    mInputMonitorCompat, sSwipeSharedState, mSwipeTouchRegion,
                     mOverviewComponentObserver, disableHorizontalSwipe(event), runningTaskInfo);
         } else {
             return createOtherActivityInputConsumer(event, runningTaskInfo);
@@ -640,13 +644,13 @@
         return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel,
                 mOverviewComponentObserver.getOverviewIntent(), activityControl,
                 shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive,
-                mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
+                sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
                 disableHorizontalSwipe(event));
     }
 
     private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
         if (mMode == Mode.NO_BUTTON && taskInfo != null) {
-            return new DeviceLockedInputConsumer(this, mSwipeSharedState, mInputMonitorCompat,
+            return new DeviceLockedInputConsumer(this, sSwipeSharedState, mInputMonitorCompat,
                     mSwipeTouchRegion, taskInfo.taskId);
         } else {
             return mResetGestureInputConsumer;
@@ -661,7 +665,7 @@
             return mResetGestureInputConsumer;
         }
 
-        if (activity.getRootView().hasWindowFocus() || mSwipeSharedState.goingToLauncher) {
+        if (activity.getRootView().hasWindowFocus() || sSwipeSharedState.goingToLauncher) {
             return new OverviewInputConsumer(activity, mInputMonitorCompat,
                     false /* startingInActivityBounds */);
         } else {
@@ -708,7 +712,7 @@
                     + mOverviewComponentObserver.getActivityControlHelper().isResumed());
             pw.println("  useSharedState=" + mConsumer.useSharedSwipeState());
             if (mConsumer.useSharedSwipeState()) {
-                mSwipeSharedState.dump("    ", pw);
+                sSwipeSharedState.dump("    ", pw);
             }
             pw.println("  mConsumer=" + mConsumer.getName());
             pw.println("FeatureFlags:");
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java
index 56cba21..8eede81 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java
@@ -39,7 +39,7 @@
     public void onMotionEvent(MotionEvent ev) {
         if (ev.getAction() == MotionEvent.ACTION_DOWN
                 && mSwipeSharedState.getActiveListener() != null) {
-            mSwipeSharedState.clearAllState();
+            mSwipeSharedState.clearAllState(false /* finishAnimation */);
         }
     }
 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
index df9efa2..381c27a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
@@ -106,6 +106,10 @@
         finishController(false /* toRecents */, null, false /* sendUserLeaveHint */);
     }
 
+    public void finishAnimation() {
+        finishController(true /* toRecents */, null, false /* sendUserLeaveHint */);
+    }
+
     public interface SwipeAnimationListener {
 
         void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet);
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 8643160..44324cb 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -765,7 +765,7 @@
                 LauncherAnimationRunner.AnimationResult result) {
             if (!mLauncher.hasBeenResumed()) {
                 // If launcher is not resumed, wait until new async-frame after resume
-                mLauncher.setOnResumeCallback(() ->
+                mLauncher.addOnResumeCallback(() ->
                         postAsyncCallback(mHandler, () ->
                                 onCreateAnimation(targetCompats, result)));
                 return;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
index fee1820..f5ba372 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
@@ -17,17 +17,22 @@
 
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_UP;
+import static android.view.MotionEvent.ACTION_CANCEL;
 
+import android.graphics.PointF;
 import android.os.RemoteException;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.MotionEvent;
 import android.view.ViewConfiguration;
+import android.view.Window;
+import android.view.WindowManager;
 
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.touch.TouchEventTranslator;
 import com.android.launcher3.util.TouchController;
 import com.android.quickstep.RecentsModel;
 import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -36,18 +41,29 @@
 
 /**
  * TouchController for handling touch events that get sent to the StatusBar. Once the
- * Once the event delta y passes the touch slop, the events start getting forwarded.
+ * Once the event delta mDownY passes the touch slop, the events start getting forwarded.
  * All events are offset by initial Y value of the pointer.
  */
 public class StatusBarTouchController implements TouchController {
 
     private static final String TAG = "StatusBarController";
 
+    /**
+     * Window flag: Enable touches to slide out of a window into neighboring
+     * windows in mid-gesture instead of being captured for the duration of
+     * the gesture.
+     *
+     * This flag changes the behavior of touch focus for this window only.
+     * Touches can slide out of the window but they cannot necessarily slide
+     * back in (unless the other window with touch focus permits it).
+     */
+    private static final int FLAG_SLIPPERY = 0x20000000;
+
     protected final Launcher mLauncher;
-    protected final TouchEventTranslator mTranslator;
     private final float mTouchSlop;
     private ISystemUiProxy mSysUiProxy;
     private int mLastAction;
+    private final SparseArray<PointF> mDownEvents;
 
     /* If {@code false}, this controller should not handle the input {@link MotionEvent}.*/
     private boolean mCanIntercept;
@@ -56,7 +72,7 @@
         mLauncher = l;
         // Guard against TAPs by increasing the touch slop.
         mTouchSlop = 2 * ViewConfiguration.get(l).getScaledTouchSlop();
-        mTranslator = new TouchEventTranslator((MotionEvent ev)-> dispatchTouchEvent(ev));
+        mDownEvents = new SparseArray<>();
     }
 
     @Override
@@ -64,7 +80,6 @@
         writer.println(prefix + "mCanIntercept:" + mCanIntercept);
         writer.println(prefix + "mLastAction:" + MotionEvent.actionToString(mLastAction));
         writer.println(prefix + "mSysUiProxy available:" + (mSysUiProxy != null));
-
     }
 
     private void dispatchTouchEvent(MotionEvent ev) {
@@ -81,26 +96,31 @@
     @Override
     public final boolean onControllerInterceptTouchEvent(MotionEvent ev) {
         int action = ev.getActionMasked();
+        int idx = ev.getActionIndex();
+        int pid = ev.getPointerId(idx);
         if (action == ACTION_DOWN) {
             mCanIntercept = canInterceptTouch(ev);
             if (!mCanIntercept) {
                 return false;
             }
-            mTranslator.reset();
-            mTranslator.setDownParameters(0, ev);
+            mDownEvents.put(pid, new PointF(ev.getX(), ev.getY()));
         } else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
-            // Check!! should only set it only when threshold is not entered.
-            mTranslator.setDownParameters(ev.getActionIndex(), ev);
+           // Check!! should only set it only when threshold is not entered.
+           mDownEvents.put(pid, new PointF(ev.getX(idx), ev.getY(idx)));
         }
         if (!mCanIntercept) {
             return false;
         }
         if (action == ACTION_MOVE) {
-            float dy = ev.getY() - mTranslator.getDownY();
-            float dx = ev.getX() - mTranslator.getDownX();
-            if (dy > mTouchSlop && dy > Math.abs(dx)) {
-                mTranslator.dispatchDownEvents(ev);
-                mTranslator.processMotionEvent(ev);
+            float dy = ev.getY(idx) - mDownEvents.get(pid).y;
+            float dx = ev.getX(idx) - mDownEvents.get(pid).x;
+            // Currently input dispatcher will not do touch transfer if there are more than
+            // one touch pointer. Hence, even if slope passed, only set the slippery flag
+            // when there is single touch event. (context: InputDispatcher.cpp line 1445)
+            if (dy > mTouchSlop && dy > Math.abs(dx) && ev.getPointerCount() == 1) {
+                ev.setAction(ACTION_DOWN);
+                dispatchTouchEvent(ev);
+                setWindowSlippery(true);
                 return true;
             }
             if (Math.abs(dx) > mTouchSlop) {
@@ -110,13 +130,27 @@
         return false;
     }
 
-
     @Override
     public final boolean onControllerTouchEvent(MotionEvent ev) {
-        mTranslator.processMotionEvent(ev);
+        if (ev.getAction() == ACTION_UP || ev.getAction() == ACTION_CANCEL) {
+            dispatchTouchEvent(ev);
+            setWindowSlippery(false);
+            return true;
+        }
         return true;
     }
 
+    private void setWindowSlippery(boolean enable) {
+        Window w = mLauncher.getWindow();
+        WindowManager.LayoutParams wlp = w.getAttributes();
+        if (enable) {
+            wlp.flags |= FLAG_SLIPPERY;
+        } else {
+            wlp.flags &= ~FLAG_SLIPPERY;
+        }
+        w.setAttributes(wlp);
+    }
+
     private boolean canInterceptTouch(MotionEvent ev) {
         if (!mLauncher.isInState(LauncherState.NORMAL) ||
                 AbstractFloatingView.getTopOpenViewWithType(mLauncher,
@@ -132,4 +166,4 @@
         mSysUiProxy = RecentsModel.INSTANCE.get(mLauncher).getSystemUiProxy();
         return mSysUiProxy != null;
     }
-}
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ad2783e..d9af4da 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -244,7 +244,7 @@
 
     @Thunk boolean mWorkspaceLoading = true;
 
-    private OnResumeCallback mOnResumeCallback;
+    private ArrayList<OnResumeCallback> mOnResumeCallbacks = new ArrayList<>();
 
     private ViewOnDrawExecutor mPendingExecutor;
 
@@ -869,6 +869,7 @@
     @Override
     protected void onStop() {
         super.onStop();
+
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onStop();
         }
@@ -951,7 +952,10 @@
         mHandler.removeCallbacks(mHandleDeferredResume);
         Utilities.postAsyncCallback(mHandler, mHandleDeferredResume);
 
-        setOnResumeCallback(null);
+        for (OnResumeCallback cb : mOnResumeCallbacks) {
+            cb.onLauncherResume();
+        }
+        mOnResumeCallbacks.clear();
 
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onResume();
@@ -1805,6 +1809,16 @@
             android.util.Log.d(TestProtocol.NO_START_TAG,
                     "startActivitySafely outer");
         }
+
+        if (!hasBeenResumed()) {
+            // Workaround an issue where the WM launch animation is clobbered when finishing the
+            // recents animation into launcher. Defer launching the activity until Launcher is
+            // next resumed.
+            addOnResumeCallback(() -> startActivitySafely(v, intent, item, sourceContainer));
+            UiFactory.clearSwipeSharedState(true /* finishAnimation */);
+            return true;
+        }
+
         boolean success = super.startActivitySafely(v, intent, item, sourceContainer);
         if (success && v instanceof BubbleTextView) {
             // This is set to the view that launched the activity that navigated the user away
@@ -1813,7 +1827,7 @@
             // state when we return to launcher.
             BubbleTextView btv = (BubbleTextView) v;
             btv.setStayPressed(true);
-            setOnResumeCallback(btv);
+            addOnResumeCallback(btv);
         }
         return success;
     }
@@ -1861,11 +1875,8 @@
         return result;
     }
 
-    public void setOnResumeCallback(OnResumeCallback callback) {
-        if (mOnResumeCallback != null) {
-            mOnResumeCallback.onLauncherResume();
-        }
-        mOnResumeCallback = callback;
+    public void addOnResumeCallback(OnResumeCallback callback) {
+        mOnResumeCallbacks.add(callback);
     }
 
     /**
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index 0cf6e44..55cb6f2 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -179,7 +179,7 @@
             DeferredOnComplete deferred = (DeferredOnComplete) d.dragSource;
             if (target != null) {
                 deferred.mPackageName = target.getPackageName();
-                mLauncher.setOnResumeCallback(deferred);
+                mLauncher.addOnResumeCallback(deferred);
             } else {
                 deferred.sendFailure();
             }
diff --git a/src/com/android/launcher3/touch/TouchEventTranslator.java b/src/com/android/launcher3/touch/TouchEventTranslator.java
deleted file mode 100644
index 3fcda90..0000000
--- a/src/com/android/launcher3/touch/TouchEventTranslator.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.touch;
-
-import android.graphics.PointF;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-import android.view.MotionEvent;
-import android.view.MotionEvent.PointerCoords;
-import android.view.MotionEvent.PointerProperties;
-
-import java.util.function.Consumer;
-
-/**
- * To minimize the size of the MotionEvent, historic events are not copied and passed via the
- * listener.
- */
-public class TouchEventTranslator {
-
-    private static final String TAG = "TouchEventTranslator";
-    private static final boolean DEBUG = false;
-
-    private class DownState {
-        long timeStamp;
-        float downX;
-        float downY;
-        public DownState(long timeStamp, float downX, float downY) {
-            this.timeStamp = timeStamp;
-            this.downX = downX;
-            this.downY = downY;
-        }
-    };
-    private final DownState ZERO = new DownState(0, 0f, 0f);
-
-    private final Consumer<MotionEvent> mListener;
-
-    private final SparseArray<DownState> mDownEvents;
-    private final SparseArray<PointF> mFingers;
-
-    private final SparseArray<Pair<PointerProperties[], PointerCoords[]>> mCache;
-
-    public TouchEventTranslator(Consumer<MotionEvent> listener) {
-        mDownEvents = new SparseArray<>();
-        mFingers = new SparseArray<>();
-        mCache = new SparseArray<>();
-
-        mListener = listener;
-    }
-
-    public void reset() {
-        mDownEvents.clear();
-        mFingers.clear();
-    }
-
-    public float getDownX() {
-        return mDownEvents.get(0).downX;
-    }
-
-    public float getDownY() {
-        return mDownEvents.get(0).downY;
-    }
-
-    public void setDownParameters(int idx, MotionEvent e) {
-        DownState ev = new DownState(e.getEventTime(), e.getX(idx), e.getY(idx));
-        mDownEvents.append(idx, ev);
-    }
-
-    public void dispatchDownEvents(MotionEvent ev) {
-        for(int i = 0; i < ev.getPointerCount() && i < mDownEvents.size(); i++) {
-            int pid = ev.getPointerId(i);
-            put(pid, i, ev.getX(i), 0, mDownEvents.get(i).timeStamp, ev);
-        }
-    }
-
-    public void processMotionEvent(MotionEvent ev) {
-        if (DEBUG) {
-            printSamples(TAG + " processMotionEvent", ev);
-        }
-        int index = ev.getActionIndex();
-        float x = ev.getX(index);
-        float y = ev.getY(index) - mDownEvents.get(index, ZERO).downY;
-        switch (ev.getActionMasked()) {
-            case MotionEvent.ACTION_POINTER_DOWN:
-                int pid = ev.getPointerId(index);
-                if(mFingers.get(pid, null) != null) {
-                    for(int i=0; i < ev.getPointerCount(); i++) {
-                        pid = ev.getPointerId(i);
-                        position(pid, x, y);
-                    }
-                    generateEvent(ev.getAction(), ev);
-                } else {
-                    put(pid, index, x, y, ev);
-                }
-                break;
-            case MotionEvent.ACTION_MOVE:
-                for(int i=0; i < ev.getPointerCount(); i++) {
-                    pid = ev.getPointerId(i);
-                    position(pid, x, y);
-                }
-                generateEvent(ev.getAction(), ev);
-                break;
-            case MotionEvent.ACTION_POINTER_UP:
-            case MotionEvent.ACTION_UP:
-                pid = ev.getPointerId(index);
-                lift(pid, index, x, y, ev);
-                break;
-            case MotionEvent.ACTION_CANCEL:
-                cancel(ev);
-                break;
-            default:
-                Log.v(TAG, "Didn't process ");
-                printSamples(TAG, ev);
-
-        }
-    }
-
-    private TouchEventTranslator put(int id, int index, float x, float y, MotionEvent ev) {
-        return put(id, index, x, y, ev.getEventTime(), ev);
-    }
-
-    private TouchEventTranslator put(int id, int index, float x, float y, long ms, MotionEvent ev) {
-        checkFingerExistence(id, false);
-        boolean isInitialDown = (mFingers.size() == 0);
-
-        mFingers.put(id, new PointF(x, y));
-        int n = mFingers.size();
-
-        if (mCache.get(n) == null) {
-            PointerProperties[] properties = new PointerProperties[n];
-            PointerCoords[] coords = new PointerCoords[n];
-            for (int i = 0; i < n; i++) {
-                properties[i] = new PointerProperties();
-                coords[i] = new PointerCoords();
-            }
-            mCache.put(n, new Pair(properties, coords));
-        }
-
-        int action;
-        if (isInitialDown) {
-            action = MotionEvent.ACTION_DOWN;
-        } else {
-            action = MotionEvent.ACTION_POINTER_DOWN;
-            // Set the id of the changed pointer.
-            action |= index << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
-        }
-        generateEvent(action, ms, ev);
-        return this;
-    }
-
-    public TouchEventTranslator position(int id, float x, float y) {
-        checkFingerExistence(id, true);
-        mFingers.get(id).set(x, y);
-        return this;
-    }
-
-    private TouchEventTranslator lift(int id, int index, MotionEvent ev) {
-        checkFingerExistence(id, true);
-        boolean isFinalUp = (mFingers.size() == 1);
-        int action;
-        if (isFinalUp) {
-            action = MotionEvent.ACTION_UP;
-        } else {
-            action = MotionEvent.ACTION_POINTER_UP;
-            // Set the id of the changed pointer.
-            action |= index << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
-        }
-        generateEvent(action, ev);
-        mFingers.remove(id);
-        return this;
-    }
-
-    private TouchEventTranslator lift(int id, int index, float x, float y, MotionEvent ev) {
-        checkFingerExistence(id, true);
-        mFingers.get(id).set(x, y);
-        return lift(id, index, ev);
-    }
-
-    public TouchEventTranslator cancel(MotionEvent ev) {
-        generateEvent(MotionEvent.ACTION_CANCEL, ev);
-        mFingers.clear();
-        return this;
-    }
-
-    private void checkFingerExistence(int id, boolean shouldExist) {
-        if (shouldExist != (mFingers.get(id, null) != null)) {
-            throw new IllegalArgumentException(
-                    shouldExist ? "Finger does not exist" : "Finger already exists");
-        }
-    }
-
-
-    /**
-     * Used to debug MotionEvents being sent/received.
-     */
-    public void printSamples(String msg, MotionEvent ev) {
-        System.out.printf("%s %s", msg, MotionEvent.actionToString(ev.getActionMasked()));
-        final int pointerCount = ev.getPointerCount();
-        System.out.printf("#%d/%d", ev.getActionIndex(), pointerCount);
-        System.out.printf(" t=%d:", ev.getEventTime());
-        for (int p = 0; p < pointerCount; p++) {
-            System.out.printf("  id=%d: (%f,%f)",
-                    ev.getPointerId(p), ev.getX(p), ev.getY(p));
-        }
-        System.out.println();
-    }
-
-    private void generateEvent(int action, MotionEvent ev) {
-        generateEvent(action, ev.getEventTime(), ev);
-    }
-
-    private void generateEvent(int action, long ms, MotionEvent ev) {
-        Pair<PointerProperties[], PointerCoords[]> state = getFingerState();
-        MotionEvent event = MotionEvent.obtain(
-                mDownEvents.get(0).timeStamp,
-                ms,
-                action,
-                state.first.length,
-                state.first,
-                state.second,
-                ev.getMetaState(),
-                ev.getButtonState() /* buttonState */,
-                ev.getXPrecision() /* xPrecision */,
-                ev.getYPrecision() /* yPrecision */,
-                ev.getDeviceId(),
-                ev.getEdgeFlags(),
-                ev.getSource(),
-                ev.getFlags() /* flags */);
-        if (DEBUG) {
-            printSamples(TAG + " generateEvent", event);
-        }
-        if (event.getPointerId(event.getActionIndex()) < 0) {
-            printSamples(TAG + "generateEvent", event);
-            throw new IllegalStateException(event.getActionIndex() + " not found in MotionEvent");
-        }
-        mListener.accept(event);
-        event.recycle();
-    }
-
-    /**
-     * Returns the description of the fingers' state expected by MotionEvent.
-     */
-    private Pair<PointerProperties[], PointerCoords[]> getFingerState() {
-        int nFingers = mFingers.size();
-
-        Pair<PointerProperties[], PointerCoords[]> result = mCache.get(nFingers);
-        PointerProperties[] properties = result.first;
-        PointerCoords[] coordinates = result.second;
-
-        int index = 0;
-        for (int i = 0; i < mFingers.size(); i++) {
-            int id = mFingers.keyAt(i);
-            PointF location = mFingers.get(id);
-
-            PointerProperties property = properties[i];
-            property.id = id;
-            property.toolType = MotionEvent.TOOL_TYPE_FINGER;
-            properties[index] = property;
-
-            PointerCoords coordinate = coordinates[i];
-            coordinate.x = location.x;
-            coordinate.y = location.y;
-            coordinate.pressure = 1.0f;
-            coordinates[index] = coordinate;
-
-            index++;
-        }
-        return mCache.get(nFingers);
-    }
-}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index 17ff66e..5cc64dc 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -93,4 +93,6 @@
 
     public static void resetPendingActivityResults(Launcher launcher, int requestCode) { }
 
+    public static void clearSwipeSharedState(boolean finishAnimation) {}
+
 }
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 06c56f2..c3168f8 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -275,8 +275,6 @@
     @Test
     @PortraitLandscape
     public void testLaunchMenuItem() throws Exception {
-        if (!TestHelpers.isInLauncherProcess()) return;
-
         final AllApps allApps = mLauncher.
                 getWorkspace().
                 switchToAllApps();
@@ -323,8 +321,6 @@
     @Test
     @PortraitLandscape
     public void testDragShortcut() throws Throwable {
-        if (!TestHelpers.isInLauncherProcess()) return;
-
         // 1. Open all apps and wait for load complete.
         // 2. Find the app and long press it to show shortcuts.
         // 3. Press icon center until shortcuts appear