merge in jb-mr2-release history after reset to jb-mr2-dev
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index 2eace41..78afe57 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -488,6 +488,23 @@
         DropTarget dropTarget = findDropTarget(x, y, coordinates);
         mDragObject.x = coordinates[0];
         mDragObject.y = coordinates[1];
+        checkTouchMove(dropTarget);
+
+        // Check if we are hovering over the scroll areas
+        mDistanceSinceScroll +=
+            Math.sqrt(Math.pow(mLastTouch[0] - x, 2) + Math.pow(mLastTouch[1] - y, 2));
+        mLastTouch[0] = x;
+        mLastTouch[1] = y;
+        checkScrollState(x, y);
+    }
+
+    public void forceTouchMove() {
+        int[] dummyCoordinates = mCoordinatesTemp;
+        DropTarget dropTarget = findDropTarget(mLastTouch[0], mLastTouch[1], dummyCoordinates);
+        checkTouchMove(dropTarget);
+    }
+
+    private void checkTouchMove(DropTarget dropTarget) {
         if (dropTarget != null) {
             DropTarget delegate = dropTarget.getDropTargetDelegate(mDragObject);
             if (delegate != null) {
@@ -507,14 +524,10 @@
             }
         }
         mLastDropTarget = dropTarget;
+    }
 
-        // After a scroll, the touch point will still be in the scroll region.
-        // Rather than scrolling immediately, require a bit of twiddling to scroll again
+    private void checkScrollState(int x, int y) {
         final int slop = ViewConfiguration.get(mLauncher).getScaledWindowTouchSlop();
-        mDistanceSinceScroll +=
-            Math.sqrt(Math.pow(mLastTouch[0] - x, 2) + Math.pow(mLastTouch[1] - y, 2));
-        mLastTouch[0] = x;
-        mLastTouch[1] = y;
         final int delay = mDistanceSinceScroll < slop ? RESCROLL_DELAY : SCROLL_DELAY;
         final DragLayer dragLayer = mLauncher.getDragLayer();
         final boolean isRtl = (dragLayer.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
@@ -544,12 +557,6 @@
         }
     }
 
-    public void forceMoveEvent() {
-        if (mDragging) {
-            handleMoveEvent(mDragObject.x, mDragObject.y);
-        }
-    }
-
     /**
      * Call this from a drag source view.
      */
@@ -800,8 +807,8 @@
                 mLauncher.getDragLayer().onExitScrollArea();
 
                 if (isDragging()) {
-                    // Force an update so that we can requeue the scroller if necessary
-                    forceMoveEvent();
+                    // Check the scroll again so that we can requeue the scroller if necessary
+                    checkScrollState(mLastTouch[0], mLastTouch[1]);
                 }
             }
         }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 56a854c..2c0f6b0 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -250,6 +250,8 @@
     private boolean mWaitingForResult;
     private boolean mOnResumeNeedsLoad;
 
+    private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();
+
     // Keep track of whether the user has left launcher
     private static boolean sPausedFromUserAction = false;
 
@@ -741,6 +743,12 @@
             mRestoring = false;
             mOnResumeNeedsLoad = false;
         }
+        // We might have postponed some bind calls until onResume (see waitUntilResume) --
+        // execute them here
+        for (int i = 0; i < mOnResumeCallbacks.size(); i++) {
+            mOnResumeCallbacks.get(i).run();
+        }
+        mOnResumeCallbacks.clear();
 
         // Reset the pressed state of icons that were locked in the press state while activities
         // were launching
@@ -3241,6 +3249,30 @@
     }
 
     /**
+     * If the activity is currently paused, signal that we need to run the passed Runnable
+     * in onResume.
+     *
+     * This needs to be called from incoming places where resources might have been loaded
+     * while we are paused.  That is becaues the Configuration might be wrong
+     * when we're not running, and if it comes back to what it was when we
+     * were paused, we are not restarted.
+     *
+     * Implementation of the method from LauncherModel.Callbacks.
+     *
+     * @return true if we are currently paused.  The caller might be able to
+     * skip some work in that case since we will come back again.
+     */
+    private boolean waitUntilResume(Runnable run) {
+        if (mPaused) {
+            Log.i(TAG, "Deferring update until onResume");
+            mOnResumeCallbacks.add(run);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
      * If the activity is currently paused, signal that we need to re-run the loader
      * in onResume.
      *
@@ -3281,8 +3313,12 @@
      * Implementation of the method from LauncherModel.Callbacks.
      */
     public void startBinding() {
-        final Workspace workspace = mWorkspace;
+        // If we're starting binding all over again, clear any bind calls we'd postponed in
+        // the past (see waitUntilResume) -- we don't need them since we're starting binding
+        // from scratch again
+        mOnResumeCallbacks.clear();
 
+        final Workspace workspace = mWorkspace;
         mNewShortcutAnimatePage = -1;
         mNewShortcutAnimateViews.clear();
         mWorkspace.clearDropTargets();
@@ -3303,8 +3339,14 @@
      *
      * Implementation of the method from LauncherModel.Callbacks.
      */
-    public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end) {
-        setLoadOnResume();
+    public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end) {
+        if (waitUntilResume(new Runnable() {
+                public void run() {
+                    bindItems(shortcuts, start, end);
+                }
+            })) {
+            return;
+        }
 
         // Get the list of added shortcuts and intersect them with the set of shortcuts here
         Set<String> newApps = new HashSet<String>();
@@ -3361,8 +3403,14 @@
     /**
      * Implementation of the method from LauncherModel.Callbacks.
      */
-    public void bindFolders(HashMap<Long, FolderInfo> folders) {
-        setLoadOnResume();
+    public void bindFolders(final HashMap<Long, FolderInfo> folders) {
+        if (waitUntilResume(new Runnable() {
+                public void run() {
+                    bindFolders(folders);
+                }
+            })) {
+            return;
+        }
         sFolders.clear();
         sFolders.putAll(folders);
     }
@@ -3372,8 +3420,14 @@
      *
      * Implementation of the method from LauncherModel.Callbacks.
      */
-    public void bindAppWidget(LauncherAppWidgetInfo item) {
-        setLoadOnResume();
+    public void bindAppWidget(final LauncherAppWidgetInfo item) {
+        if (waitUntilResume(new Runnable() {
+                public void run() {
+                    bindAppWidget(item);
+                }
+            })) {
+            return;
+        }
 
         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;
         if (DEBUG_WIDGETS) {
@@ -3414,8 +3468,13 @@
      * Implementation of the method from LauncherModel.Callbacks.
      */
     public void finishBindingItems() {
-        setLoadOnResume();
-
+        if (waitUntilResume(new Runnable() {
+                public void run() {
+                    finishBindingItems();
+                }
+            })) {
+            return;
+        }
         if (mSavedState != null) {
             if (!mWorkspace.hasFocus()) {
                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();
@@ -3581,8 +3640,15 @@
      *
      * Implementation of the method from LauncherModel.Callbacks.
      */
-    public void bindAppsAdded(ArrayList<ApplicationInfo> apps) {
-        setLoadOnResume();
+    public void bindAppsAdded(final ArrayList<ApplicationInfo> apps) {
+        if (waitUntilResume(new Runnable() {
+                public void run() {
+                    bindAppsAdded(apps);
+                }
+            })) {
+            return;
+        }
+
 
         if (mAppsCustomizeContent != null) {
             mAppsCustomizeContent.addApps(apps);
@@ -3594,8 +3660,15 @@
      *
      * Implementation of the method from LauncherModel.Callbacks.
      */
-    public void bindAppsUpdated(ArrayList<ApplicationInfo> apps) {
-        setLoadOnResume();
+    public void bindAppsUpdated(final ArrayList<ApplicationInfo> apps) {
+        if (waitUntilResume(new Runnable() {
+                public void run() {
+                    bindAppsUpdated(apps);
+                }
+            })) {
+            return;
+        }
+
         if (mWorkspace != null) {
             mWorkspace.updateShortcuts(apps);
         }
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 7d7ca86..d4488db 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -773,7 +773,7 @@
             if (isSmall()) {
                 // If we are in springloaded mode, then force an event to check if the current touch
                 // is under a new page (to scroll to)
-                mDragController.forceMoveEvent();
+                mDragController.forceTouchMove();
             }
         } else {
             // If we are not mid-dragging, hide the page outlines if we are on a large screen