Cancel exit spring loaded runnable when launcher state is set to APPS or WIDGETS
b/29645452

By cancelling the runnable, we are enabling transition:
state1 -> state3 instead of state1-> state2-> state3.
Transition state1->state3 is a viable transition that is
supported by our model.

        Launcher           Workspace
--------------------------------------------
state1  APPS_SPRING_LOADED SPRING_LOADED
state2  WORKSPACE          NORMAL
state3  APPS               NORMAL_HIDDEN


Change-Id: If27905567efe439324494e0091a4b42fcbf01448
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 78e0aa0..6911360 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -348,6 +348,11 @@
         }
     }
 
+    // Exiting spring loaded mode happens with a delay. This runnable object triggers the
+    // state transition. If another state transition happened during this delay,
+    // simply unregister this runnable.
+    private Runnable mExitSpringLoadedModeRunnable;
+
     @Thunk Runnable mBuildLayersRunnable = new Runnable() {
         public void run() {
             if (mWorkspace != null) {
@@ -3413,6 +3418,12 @@
             return false;
         }
 
+        // This is a safe and supported transition to bypass spring_loaded mode.
+        if (mExitSpringLoadedModeRunnable != null) {
+            mHandler.removeCallbacks(mExitSpringLoadedModeRunnable);
+            mExitSpringLoadedModeRunnable = null;
+        }
+
         if (toState == State.APPS) {
             mStateTransitionAnimation.startAnimationToAllApps(mWorkspace.getState(), animated,
                     focusSearchBar);
@@ -3472,7 +3483,10 @@
             final Runnable onCompleteRunnable) {
         if (!isStateSpringLoaded()) return;
 
-        mHandler.postDelayed(new Runnable() {
+        if (mExitSpringLoadedModeRunnable != null) {
+            mHandler.removeCallbacks(mExitSpringLoadedModeRunnable);
+        }
+        mExitSpringLoadedModeRunnable = new Runnable() {
             @Override
             public void run() {
                 if (successfulDrop) {
@@ -3486,8 +3500,10 @@
                 } else {
                     exitSpringLoadedDragMode();
                 }
+                mExitSpringLoadedModeRunnable = null;
             }
-        }, delay);
+        };
+        mHandler.postDelayed(mExitSpringLoadedModeRunnable, delay);
     }
 
     boolean isStateSpringLoaded() {