merge in jb-release history after reset to jb-dev
diff --git a/res/values-sw600dp-port/dimens.xml b/res/values-sw600dp-port/dimens.xml
index 1a25409..8ad6d2e 100644
--- a/res/values-sw600dp-port/dimens.xml
+++ b/res/values-sw600dp-port/dimens.xml
@@ -17,9 +17,9 @@
 <resources>
 <!-- AppsCustomize -->
     <dimen name="apps_customize_cell_width">96dp</dimen>
-    <dimen name="apps_customize_cell_height">96dp</dimen>
+    <dimen name="apps_customize_cell_height">108dp</dimen>
     <dimen name="apps_customize_pageLayoutWidthGap">24dp</dimen>
-    <dimen name="apps_customize_pageLayoutHeightGap">36dp</dimen>
+    <dimen name="apps_customize_pageLayoutHeightGap">24dp</dimen>
     <dimen name="apps_customize_pageLayoutPaddingTop">25dp</dimen>
     <dimen name="apps_customize_pageLayoutPaddingBottom">10dp</dimen>
 
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index fbd743b..99e8909 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -54,7 +54,7 @@
 
 <!-- AppsCustomize -->
     <dimen name="apps_customize_cell_width">96dp</dimen>
-    <dimen name="apps_customize_cell_height">98dp</dimen>
+    <dimen name="apps_customize_cell_height">96dp</dimen>
     <dimen name="apps_customize_pageLayoutPaddingLeft">12dp</dimen>
     <dimen name="apps_customize_pageLayoutPaddingRight">12dp</dimen>
     <dimen name="apps_customize_tab_bar_height">60dp</dimen>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index d06f0aa..cfd76dc 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -36,6 +36,8 @@
     <dimen name="folder_preview_size">75dp</dimen>
 
 <!-- AppsCustomize -->
+    <dimen name="apps_customize_cell_width">96dp</dimen>
+    <dimen name="apps_customize_cell_height">96dp</dimen>
     <integer name="apps_customize_maxCellCountX">-1</integer>
     <integer name="apps_customize_maxCellCountY">-1</integer>
     <dimen name="app_widget_preview_padding_left">0dp</dimen>
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index a3d8f8d..4712a37 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -614,18 +614,24 @@
 
     @Override
     public void onShortPress(View v) {
+        Log.d(TAG, "onShortPress, view: " + v);
         // We are anticipating a long press, and we use this time to load bind and instantiate
         // the widget. This will need to be cleaned up if it turns out no long press occurs.
         if (mCreateWidgetInfo != null) {
+            Log.d(TAG, "onShortPress --> cleanup previous, view: " + v + ", create info: " + mCreateWidgetInfo);
             // Just in case the cleanup process wasn't properly executed. This shouldn't happen.
             cleanupWidgetPreloading(false);
         }
         mCreateWidgetInfo = new PendingAddWidgetInfo((PendingAddWidgetInfo) v.getTag());
+        Log.d(TAG, "onShortPress --> create widget info: " + mCreateWidgetInfo);
         preloadWidget(mCreateWidgetInfo);
     }
 
     private void cleanupWidgetPreloading(boolean widgetWasAdded) {
+        Log.d(TAG, "cleanup widget preloading");
+
         if (!widgetWasAdded) {
+            Log.d(TAG, "cleanup widget preloading --> widget wasn't added");
             // If the widget was not added, we may need to do further cleanup.
             PendingAddWidgetInfo info = mCreateWidgetInfo;
             mCreateWidgetInfo = null;
@@ -651,12 +657,16 @@
 
     @Override
     public void cleanUpShortPress(View v) {
+        Log.d(TAG, "cleanup shortpress, view: " + v);
         if (!mDraggingWidget) {
+            Log.d(TAG, "cleanup shortpress --> cleanup preloading");
             cleanupWidgetPreloading(false);
         }
     }
 
     private boolean beginDraggingWidget(View v) {
+        Log.d(TAG, "begin dragging widget, view: " + v);
+
         mDraggingWidget = true;
         // Get the widget preview as the drag representation
         ImageView image = (ImageView) v.findViewById(R.id.widget_preview);
@@ -665,10 +675,18 @@
         // If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and
         // we abort the drag.
         if (image.getDrawable() == null) {
+            Log.d(TAG, "begin dragging widget, no drawable");
             mDraggingWidget = false;
             return false;
         }
 
+        // This can happen in some weird cases involving multi-touch. We can't start dragging the
+        // widget if this is null, so we break out.
+        if (mCreateWidgetInfo == null) {
+            Log.d(TAG, "begin dragging widget, create widget info null");
+            return false;
+        }
+
         // Compose the drag image
         Bitmap preview;
         Bitmap outline;
@@ -707,9 +725,11 @@
                     mWidgetPreviewIconPaddedDimension, Bitmap.Config.ARGB_8888);
             Drawable d = image.getDrawable();
             mCanvas.setBitmap(preview);
+            mCanvas.save();
             mCanvas.translate((mWidgetPreviewIconPaddedDimension - d.getIntrinsicWidth()) / 2,
                     (mWidgetPreviewIconPaddedDimension - d.getIntrinsicHeight()) / 2);
             d.draw(mCanvas);
+            mCanvas.restore();
             mCanvas.setBitmap(null);
             createItemInfo.spanX = createItemInfo.spanY = 1;
         }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 2e7caff..e6c25cb 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1129,8 +1129,7 @@
 
             launcherInfo.hostView.setTag(launcherInfo);
             launcherInfo.hostView.setVisibility(View.VISIBLE);
-            AppWidgetResizeFrame.updateWidgetSizeRanges(launcherInfo.hostView,
-                    this, launcherInfo.spanX, launcherInfo.spanY);
+            launcherInfo.notifyWidgetSizeChanged(this);
             mWorkspace.addInScreen(launcherInfo.hostView, container, screen, cellXY[0], cellXY[1],
                     launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());
 
@@ -2368,6 +2367,9 @@
                     if (!animationCancelled) {
                         updateWallpaperVisibility(false);
                     }
+
+                    // Hide the search bar
+                    mSearchDropTargetBar.hideSearchBar(false);
                 }
 
                 @Override
@@ -2436,6 +2438,9 @@
                 // Hide the workspace scrollbar
                 mWorkspace.hideScrollingIndicator(true);
                 hideDockDivider();
+
+                // Hide the search bar
+                mSearchDropTargetBar.hideSearchBar(false);
             }
             dispatchOnLauncherTransitionPrepare(fromView, animated, false);
             dispatchOnLauncherTransitionStart(fromView, animated, false);
@@ -2569,13 +2574,16 @@
 
     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {
         if (mState != State.WORKSPACE) {
+            boolean wasInSpringLoadedMode = (mState == State.APPS_CUSTOMIZE_SPRING_LOADED);
             mWorkspace.setVisibility(View.VISIBLE);
             hideAppsCustomizeHelper(State.WORKSPACE, animated, false, onCompleteRunnable);
 
-            // Show the search bar and hotseat
-            mSearchDropTargetBar.showSearchBar(animated);
+            // Show the search bar (only animate if we were showing the drop target bar in spring
+            // loaded mode)
+            mSearchDropTargetBar.showSearchBar(wasInSpringLoadedMode);
+
             // We only need to animate in the dock divider if we're going from spring loaded mode
-            showDockDivider(animated && mState == State.APPS_CUSTOMIZE_SPRING_LOADED);
+            showDockDivider(animated && wasInSpringLoadedMode);
 
             // Set focus to the AppsCustomize button
             if (mAllAppsButton != null) {
@@ -2602,9 +2610,6 @@
         showAppsCustomizeHelper(animated, false);
         mAppsCustomizeTabHost.requestFocus();
 
-        // Hide the search bar and hotseat
-        mSearchDropTargetBar.hideSearchBar(animated);
-
         // Change the state *after* we've called all the transition code
         mState = State.APPS_CUSTOMIZE;
 
@@ -2637,7 +2642,6 @@
                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should
                     // clean up our state transition functions
                     mAppsCustomizeTabHost.setVisibility(View.GONE);
-                    mSearchDropTargetBar.showSearchBar(true);
                     showWorkspace(true, onCompleteRunnable);
                 } else {
                     exitSpringLoadedDragMode();
@@ -3160,17 +3164,14 @@
 
         item.hostView.setAppWidget(appWidgetId, appWidgetInfo);
         item.hostView.setTag(item);
+        item.onBindAppWidget(this);
 
         workspace.addInScreen(item.hostView, item.container, item.screen, item.cellX,
                 item.cellY, item.spanX, item.spanY, false);
-
         addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);
 
         workspace.requestLayout();
 
-        AppWidgetResizeFrame.updateWidgetSizeRanges(item.hostView,
-                this, item.spanX, item.spanY);
-
         if (DEBUG_WIDGETS) {
             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "
                     + (SystemClock.uptimeMillis()-start) + "ms");
diff --git a/src/com/android/launcher2/LauncherAppWidgetInfo.java b/src/com/android/launcher2/LauncherAppWidgetInfo.java
index e5b9473..f001b2b 100644
--- a/src/com/android/launcher2/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher2/LauncherAppWidgetInfo.java
@@ -42,6 +42,8 @@
     int minWidth = -1;
     int minHeight = -1;
 
+    private boolean mHasNotifiedInitialWidgetSizeChanged;
+
     /**
      * View that holds this widget after it's been created.  This view isn't created
      * until Launcher knows it's needed.
@@ -65,6 +67,24 @@
         values.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId);
     }
 
+    /**
+     * When we bind the widget, we should notify the widget that the size has changed if we have not
+     * done so already (only really for default workspace widgets).
+     */
+    void onBindAppWidget(Launcher launcher) {
+        if (!mHasNotifiedInitialWidgetSizeChanged) {
+            notifyWidgetSizeChanged(launcher);
+        }
+    }
+
+    /**
+     * Trigger an update callback to the widget to notify it that its size has changed.
+     */
+    void notifyWidgetSizeChanged(Launcher launcher) {
+        AppWidgetResizeFrame.updateWidgetSizeRanges(hostView, launcher, spanX, spanY);
+        mHasNotifiedInitialWidgetSizeChanged = true;
+    }
+
     @Override
     public String toString() {
         return "AppWidget(id=" + Integer.toString(appWidgetId) + ")";
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index f78aa4c..a6ea78f 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -141,8 +141,8 @@
 
     class CheckForShortPress implements Runnable {
         public void run() {
+            if (sShortpressTarget != null) return;
             if (mShortPressListener != null) {
-                if (sShortpressTarget != null) return;
                 mShortPressListener.onShortPress(PagedViewWidget.this);
             }
             sShortpressTarget = PagedViewWidget.this;
diff --git a/src/com/android/launcher2/SearchDropTargetBar.java b/src/com/android/launcher2/SearchDropTargetBar.java
index 03512b2..a01fd3a 100644
--- a/src/com/android/launcher2/SearchDropTargetBar.java
+++ b/src/com/android/launcher2/SearchDropTargetBar.java
@@ -75,6 +75,13 @@
         mDeleteDropTarget.setLauncher(launcher);
     }
 
+    // This sets up the view for the animation
+    private void prepareStartAnimation(View v) {
+        // Enable the hw layers (which will be disabled in the onAnimationEnd callback below
+        v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        v.buildLayer();
+    }
+
     private void prepareAnimation(ObjectAnimator in, ObjectAnimator out, final View v) {
         in.setInterpolator(new AccelerateInterpolator());
         in.setDuration(sTransitionInDuration);
@@ -84,7 +91,7 @@
                 v.setVisibility(View.VISIBLE);
             }
         });
-        out.setInterpolator(new DecelerateInterpolator());
+        out.setInterpolator(new AccelerateInterpolator());
         out.setDuration(sTransitionOutDuration);
         out.addListener(new AnimatorListenerAdapter() {
             @Override
@@ -139,9 +146,7 @@
         mQSBSearchBarFadeOutAnim.end();
     }
 
-    private void cancelAnimations() {
-        mDropTargetBarFadeInAnim.cancel();
-        mDropTargetBarFadeOutAnim.cancel();
+    private void cancelSearchBarAnimations() {
         mQSBSearchBarFadeInAnim.cancel();
         mQSBSearchBarFadeOutAnim.cancel();
     }
@@ -150,8 +155,9 @@
      * Shows and hides the search bar.
      */
     public void showSearchBar(boolean animated) {
-        cancelAnimations();
+        cancelSearchBarAnimations();
         if (animated) {
+            prepareStartAnimation(mQSBSearchBar);
             mQSBSearchBarFadeInAnim.start();
         } else {
             mQSBSearchBar.setVisibility(View.VISIBLE);
@@ -164,8 +170,9 @@
         mIsSearchBarHidden = false;
     }
     public void hideSearchBar(boolean animated) {
-        cancelAnimations();
+        cancelSearchBarAnimations();
         if (animated) {
+            prepareStartAnimation(mQSBSearchBar);
             mQSBSearchBarFadeOutAnim.start();
         } else {
             mQSBSearchBar.setVisibility(View.INVISIBLE);
@@ -194,11 +201,11 @@
     @Override
     public void onDragStart(DragSource source, Object info, int dragAction) {
         // Animate out the QSB search bar, and animate in the drop target bar
-        mDropTargetBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-        mDropTargetBar.buildLayer();
+        prepareStartAnimation(mDropTargetBar);
         mDropTargetBarFadeOutAnim.cancel();
         mDropTargetBarFadeInAnim.start();
         if (!mIsSearchBarHidden) {
+            prepareStartAnimation(mQSBSearchBar);
             mQSBSearchBarFadeInAnim.cancel();
             mQSBSearchBarFadeOutAnim.start();
         }
@@ -212,9 +219,11 @@
     public void onDragEnd() {
         if (!mDeferOnDragEnd) {
             // Restore the QSB search bar, and animate out the drop target bar
+            prepareStartAnimation(mDropTargetBar);
             mDropTargetBarFadeInAnim.cancel();
             mDropTargetBarFadeOutAnim.start();
             if (!mIsSearchBarHidden) {
+                prepareStartAnimation(mQSBSearchBar);
                 mQSBSearchBarFadeOutAnim.cancel();
                 mQSBSearchBarFadeInAnim.start();
             }
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 00684bd..905ad8a 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -76,7 +76,6 @@
     private static final String TAG = "Launcher.Workspace";
 
     // Y rotation to apply to the workspace screens
-    private static final float WORKSPACE_ROTATION = 12.5f;
     private static final float WORKSPACE_OVERSCROLL_ROTATION = 24f;
     private static float CAMERA_DISTANCE = 6500;
 
@@ -88,8 +87,6 @@
     private static final int ADJACENT_SCREEN_DROP_DURATION = 300;
     private static final int FLING_THRESHOLD_VELOCITY = 500;
 
-    private float mMaxDistanceForFolderCreation;
-
     // These animators are used to fade the children's outlines
     private ObjectAnimator mChildrenOutlineFadeInAnimation;
     private ObjectAnimator mChildrenOutlineFadeOutAnimation;
@@ -102,7 +99,6 @@
     boolean mDrawBackground = true;
     private float mBackgroundAlpha = 0;
     private float mOverScrollMaxBackgroundAlpha = 0.0f;
-    private int mOverScrollPageIndex = -1;
 
     private float mWallpaperScrollRatio = 1.0f;
 
@@ -211,6 +207,7 @@
     private boolean mCreateUserFolderOnDrop = false;
     private boolean mAddToExistingFolderOnDrop = false;
     private DropTarget.DragEnforcer mDragEnforcer;
+    private float mMaxDistanceForFolderCreation;
 
     // Variables relating to touch disambiguation (scrolling workspace vs. scrolling a widget)
     private float mXDown;
@@ -250,7 +247,6 @@
     private float[] mOldScaleYs;
     private float[] mOldBackgroundAlphas;
     private float[] mOldAlphas;
-    private float[] mOldRotationYs;
     private float[] mNewTranslationXs;
     private float[] mNewTranslationYs;
     private float[] mNewScaleXs;
@@ -432,7 +428,7 @@
         mWallpaperTravelWidth = (int) (mDisplaySize.x *
                 wallpaperTravelToScreenWidthRatio(mDisplaySize.x, mDisplaySize.y));
 
-        mMaxDistanceForFolderCreation = (0.6f * res.getDimensionPixelSize(R.dimen.app_icon_size));
+        mMaxDistanceForFolderCreation = (0.55f * res.getDimensionPixelSize(R.dimen.app_icon_size));
         mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
     }
 
@@ -776,7 +772,6 @@
             }
         }
         mOverScrollMaxBackgroundAlpha = 0.0f;
-        mOverScrollPageIndex = -1;
 
         if (mDelayedResizeRunnable != null) {
             mDelayedResizeRunnable.run();
@@ -1508,7 +1503,6 @@
         mOldScaleYs = new float[childCount];
         mOldBackgroundAlphas = new float[childCount];
         mOldAlphas = new float[childCount];
-        mOldRotationYs = new float[childCount];
         mNewTranslationXs = new float[childCount];
         mNewTranslationYs = new float[childCount];
         mNewScaleXs = new float[childCount];