merge in jb-release history after reset to jb-dev
diff --git a/res/drawable-hdpi/search_frame.9.png b/res/drawable-hdpi/search_frame.9.png
index 98b430c..d0c78c4 100644
--- a/res/drawable-hdpi/search_frame.9.png
+++ b/res/drawable-hdpi/search_frame.9.png
Binary files differ
diff --git a/res/drawable-mdpi/search_frame.9.png b/res/drawable-mdpi/search_frame.9.png
index 92ef3e7..7a0e46c 100644
--- a/res/drawable-mdpi/search_frame.9.png
+++ b/res/drawable-mdpi/search_frame.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/search_frame.9.png b/res/drawable-xhdpi/search_frame.9.png
index f00d8f8..cb6f294 100644
--- a/res/drawable-xhdpi/search_frame.9.png
+++ b/res/drawable-xhdpi/search_frame.9.png
Binary files differ
diff --git a/res/layout-port/search_bar.xml b/res/layout-port/search_bar.xml
index 09c6e09..0ccbe02 100644
--- a/res/layout-port/search_bar.xml
+++ b/res/layout-port/search_bar.xml
@@ -28,6 +28,7 @@
         android:id="@+id/search_button_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
+        android:layout_gravity="center_vertical"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
         android:layout_toLeftOf="@+id/voice_button_container"
@@ -50,6 +51,7 @@
         android:id="@+id/voice_button_container"
         android:layout_width="@dimen/search_bar_height"
         android:layout_height="match_parent"
+        android:layout_gravity="center_vertical"
         android:layout_alignParentRight="true"
         android:layout_alignParentTop="true"
         android:gravity="right"
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 61397f7..0e42cdd 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -89,7 +89,7 @@
     <string name="folder_hint_text" msgid="8633351560105748141">"이름이 없는 폴더"</string>
     <string name="workspace_description_format" msgid="2968608205939373034">"홈 화면 %1$d"</string>
     <string name="default_scroll_format" msgid="4057140866420001240">"페이지 %2$d 중 %1$d"</string>
-    <string name="workspace_scroll_format" msgid="1704767047951143301">"홈 화면 %2$d 중 %1$d"</string>
+    <string name="workspace_scroll_format" msgid="1704767047951143301">"홈 화면 %1$d/%2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="5494241912377704885">"앱 페이지 %2$d 중 %1$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="5383009742241717437">"위젯 페이지 %2$d 중 %1$d"</string>
     <string name="workspace_cling_title" msgid="738396473989890567">"나만의 홈 화면 만들기"</string>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index e94d780..eeeed61 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -18,6 +18,8 @@
 <!-- QSB -->
     <dimen name="toolbar_button_vertical_padding">12dip</dimen>
     <dimen name="toolbar_button_horizontal_padding">4dip</dimen>
+    <dimen name="search_bar_padding_left">0dp</dimen>
+    <dimen name="search_bar_padding_right">0dp</dimen>
 
 <!-- Workspace -->
     <dimen name="hotseat_cell_width">64dp</dimen>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index efb7753..1ab495f 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -52,7 +52,7 @@
     <dimen name="apps_customize_pageLayoutPaddingRight">12dp</dimen>
     <dimen name="apps_customize_tab_bar_height">60dp</dimen>
     <dimen name="apps_customize_tab_bar_margin_top">8dp</dimen>
-    <dimen name="apps_customize_widget_cell_width_gap">0dp</dimen>
+    <dimen name="apps_customize_widget_cell_width_gap">20dp</dimen>
     <dimen name="apps_customize_widget_cell_height_gap">24dp</dimen>
 
 <!-- Workspace cell size -->
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d5bcb66..d468762 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -29,6 +29,8 @@
     <dimen name="qsb_bar_height">40dp</dimen>
     <dimen name="qsb_padding_left">0dp</dimen>
     <dimen name="qsb_padding_right">0dp</dimen>
+    <dimen name="search_bar_padding_left">8dp</dimen>
+    <dimen name="search_bar_padding_right">8dp</dimen>
     <dimen name="search_bar_height">40dp</dimen>
     <dimen name="workspace_max_gap">16dp</dimen>
     <dimen name="folder_cell_width">74dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 65b0f31..3d935a1 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -123,6 +123,8 @@
         <item name="android:orientation">horizontal</item>
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">match_parent</item>
+        <item name="android:paddingLeft">@dimen/search_bar_padding_left</item>
+        <item name="android:paddingRight">@dimen/search_bar_padding_right</item>
     </style>
     <style name="SearchButton">
         <item name="android:layout_gravity">center_vertical</item>
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 54af080..f2c50a4 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -49,7 +49,6 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
@@ -171,7 +170,7 @@
         AllAppsView, View.OnClickListener, View.OnKeyListener, DragSource,
         PagedViewIcon.PressedCallback, PagedViewWidget.ShortPressListener,
         LauncherTransitionable {
-    static final String LOG_TAG = "AppsCustomizePagedView";
+    static final String TAG = "AppsCustomizePagedView";
 
     /**
      * The different content types that this paged view can show.
@@ -490,7 +489,7 @@
                     mWidgets.add(widget);
                 }
             } else {
-                Log.e(LOG_TAG, "Widget " + widget.provider + " has invalid dimensions (" +
+                Log.e(TAG, "Widget " + widget.provider + " has invalid dimensions (" +
                         widget.minWidth + ", " + widget.minHeight + ")");
             }
         }
@@ -566,7 +565,7 @@
         mLauncher.getWorkspace().beginDragShared(v, this);
     }
 
-    private void loadWidgetInBackground(final PendingAddWidgetInfo info) {
+    private void preloadWidget(final PendingAddWidgetInfo info) {
         final AppWidgetProviderInfo pInfo = info.info;
         if (pInfo.configure != null) {
             return;
@@ -612,41 +611,59 @@
     public void 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) {
+            // Just in case the cleanup process wasn't properly executed. This shouldn't happen.
+            cleanupWidgetPreloading(false);
+        }
         mCreateWidgetInfo = new PendingAddWidgetInfo((PendingAddWidgetInfo) v.getTag());
-        loadWidgetInBackground(mCreateWidgetInfo);
+        preloadWidget(mCreateWidgetInfo);
     }
 
-    private void cleanupWidgetPreloading() {
-        PendingAddWidgetInfo info = mCreateWidgetInfo;
-        mCreateWidgetInfo = null;
-        if (mWidgetCleanupState >= 0 && mWidgetLoadingId != -1) {
-            mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId);
-        }
-        if (mWidgetCleanupState == WIDGET_BOUND) {
-            removeCallbacks(mInflateWidgetRunnable);
-        } else if (mWidgetCleanupState == WIDGET_INFLATED) {
-            AppWidgetHostView widget = info.boundWidget;
-            int widgetId = widget.getAppWidgetId();
-            mLauncher.getAppWidgetHost().deleteAppWidgetId(widgetId);
-            mLauncher.getDragLayer().removeView(widget);
+    private void cleanupWidgetPreloading(boolean widgetWasAdded) {
+        if (!widgetWasAdded) {
+            // If the widget was not added, we may need to do further cleanup.
+            PendingAddWidgetInfo info = mCreateWidgetInfo;
+            mCreateWidgetInfo = null;
+            // First step was to allocate a widget id, revert that.
+            if ((mWidgetCleanupState == WIDGET_BOUND || mWidgetCleanupState == WIDGET_INFLATED) &&
+                    mWidgetLoadingId != -1) {
+                mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId);
+            }
+            if (mWidgetCleanupState == WIDGET_BOUND) {
+                // We never actually inflated the widget, so remove the callback to do so.
+                removeCallbacks(mInflateWidgetRunnable);
+            } else if (mWidgetCleanupState == WIDGET_INFLATED) {
+                // The widget was inflated and added to the DragLayer -- remove it.
+                AppWidgetHostView widget = info.boundWidget;
+                mLauncher.getDragLayer().removeView(widget);
+            }
         }
         mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED;
         mWidgetLoadingId = -1;
+        mCreateWidgetInfo = null;
+        PagedViewWidget.resetShortPressTarget();
     }
 
     @Override
     public void cleanUpShortPress(View v) {
         if (!mDraggingWidget) {
-            cleanupWidgetPreloading();
+            cleanupWidgetPreloading(false);
         }
     }
 
-    private void beginDraggingWidget(View v) {
+    private boolean beginDraggingWidget(View v) {
         mDraggingWidget = true;
         // Get the widget preview as the drag representation
         ImageView image = (ImageView) v.findViewById(R.id.widget_preview);
         PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag();
 
+        // 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) {
+            mDraggingWidget = false;
+            return false;
+        }
+
         // Compose the drag image
         Bitmap preview;
         Bitmap outline;
@@ -712,6 +729,7 @@
                 DragController.DRAG_ACTION_COPY, null, scale);
         outline.recycle();
         preview.recycle();
+        return true;
     }
 
     @Override
@@ -721,7 +739,9 @@
         if (v instanceof PagedViewIcon) {
             beginDraggingApplication(v);
         } else if (v instanceof PagedViewWidget) {
-            beginDraggingWidget(v);
+            if (!beginDraggingWidget(v)) {
+                return false;
+            }
         }
 
         // We delay entering spring-loaded mode slightly to make sure the UI
@@ -819,8 +839,8 @@
             }
 
             d.deferDragViewCleanupPostAnimation = false;
-            cleanupWidgetPreloading();
         }
+        cleanupWidgetPreloading(success);
         mDraggingWidget = false;
     }
 
@@ -828,7 +848,7 @@
     public void onFlingToDeleteCompleted() {
         // We just dismiss the drag when we fling, so cleanup here
         endDragging(null, true, true);
-        cleanupWidgetPreloading();
+        cleanupWidgetPreloading(false);
         mDraggingWidget = false;
     }
 
@@ -1120,7 +1140,7 @@
         if (previewImage != 0) {
             drawable = mPackageManager.getDrawable(packageName, previewImage, null);
             if (drawable == null) {
-                Log.w(LOG_TAG, "Can't load widget preview drawable 0x" +
+                Log.w(TAG, "Can't load widget preview drawable 0x" +
                         Integer.toHexString(previewImage) + " for provider: " + provider);
             }
         }
@@ -1610,8 +1630,8 @@
     @Override
     public void dumpState() {
         // TODO: Dump information related to current list of Applications, Widgets, etc.
-        ApplicationInfo.dumpApplicationInfoList(LOG_TAG, "mApps", mApps);
-        dumpAppWidgetProviderInfoList(LOG_TAG, "mWidgets", mWidgets);
+        ApplicationInfo.dumpApplicationInfoList(TAG, "mApps", mApps);
+        dumpAppWidgetProviderInfoList(TAG, "mWidgets", mWidgets);
     }
 
     private void dumpAppWidgetProviderInfoList(String tag, String label,
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index ece1870..e4b5af3 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -2010,7 +2010,7 @@
                 ObjectAnimator.ofFloat(child, "scaleX", 1f),
                 ObjectAnimator.ofFloat(child, "scaleY", 1f),
                 ObjectAnimator.ofFloat(child, "translationX", 0f),
-                ObjectAnimator.ofFloat(child, "translationX", 0f)
+                ObjectAnimator.ofFloat(child, "translationY", 0f)
             );
             s.setDuration(REORDER_ANIMATION_DURATION);
             s.setInterpolator(new android.view.animation.DecelerateInterpolator(1.5f));
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 774bf1f..f78aa4c 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -42,6 +42,7 @@
     CheckForShortPress mPendingCheckForShortPress = null;
     ShortPressListener mShortPressListener = null;
     boolean mShortPressTriggered = false;
+    static PagedViewWidget sShortpressTarget = null;
 
     public PagedViewWidget(Context context) {
         this(context, null);
@@ -141,13 +142,16 @@
     class CheckForShortPress implements Runnable {
         public void run() {
             if (mShortPressListener != null) {
+                if (sShortpressTarget != null) return;
                 mShortPressListener.onShortPress(PagedViewWidget.this);
             }
+            sShortpressTarget = PagedViewWidget.this;
             mShortPressTriggered = true;
         }
     }
 
     private void checkForShortPress() {
+        if (sShortpressTarget != null) return;
         if (mPendingCheckForShortPress == null) {
             mPendingCheckForShortPress = new CheckForShortPress();
         }
@@ -173,6 +177,10 @@
         }
     }
 
+    static void resetShortPressTarget() {
+        sShortpressTarget = null;
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         super.onTouchEvent(event);
@@ -190,6 +198,7 @@
             case MotionEvent.ACTION_MOVE:
                 break;
         }
+
         // We eat up the touch events here, since the PagedView (which uses the same swiping
         // touch code as Workspace previously) uses onInterceptTouchEvent() to determine when
         // the user is scrolling between pages.  This means that if the pages themselves don't
diff --git a/src/com/android/launcher2/SearchDropTargetBar.java b/src/com/android/launcher2/SearchDropTargetBar.java
index 30978a8..5a1ba69 100644
--- a/src/com/android/launcher2/SearchDropTargetBar.java
+++ b/src/com/android/launcher2/SearchDropTargetBar.java
@@ -40,8 +40,8 @@
     private static final int sTransitionInDuration = 200;
     private static final int sTransitionOutDuration = 175;
 
-    private AnimatorSet mDropTargetBarFadeInAnim;
-    private AnimatorSet mDropTargetBarFadeOutAnim;
+    private ObjectAnimator mDropTargetBarFadeInAnim;
+    private ObjectAnimator mDropTargetBarFadeOutAnim;
     private ObjectAnimator mQSBSearchBarFadeInAnim;
     private ObjectAnimator mQSBSearchBarFadeOutAnim;
 
@@ -74,6 +74,26 @@
         mDeleteDropTarget.setLauncher(launcher);
     }
 
+    private void prepareAnimation(ObjectAnimator in, ObjectAnimator out, final View v) {
+        in.setInterpolator(new AccelerateInterpolator());
+        in.setDuration(sTransitionInDuration);
+        in.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                v.setVisibility(View.VISIBLE);
+            }
+        });
+        out.setInterpolator(new DecelerateInterpolator());
+        out.setDuration(sTransitionOutDuration);
+        out.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                v.setVisibility(View.INVISIBLE);
+                v.setLayerType(View.LAYER_TYPE_NONE, null);
+            }
+        });
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -92,66 +112,23 @@
             getResources().getBoolean(R.bool.config_useDropTargetDownTransition);
 
         // Create the various fade animations
-        mDropTargetBar.setAlpha(0f);
-        ObjectAnimator fadeInAlphaAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 1f);
-        fadeInAlphaAnim.setInterpolator(new DecelerateInterpolator());
-        mDropTargetBarFadeInAnim = new AnimatorSet();
-        AnimatorSet.Builder fadeInAnimators = mDropTargetBarFadeInAnim.play(fadeInAlphaAnim);
         if (enableDropDownDropTargets) {
             mDropTargetBar.setTranslationY(-mBarHeight);
-            fadeInAnimators.with(ObjectAnimator.ofFloat(mDropTargetBar, "translationY", 0f));
+            mDropTargetBarFadeInAnim = ObjectAnimator.ofFloat(mDropTargetBar, "translationY", 0f);
+            mDropTargetBarFadeOutAnim = ObjectAnimator.ofFloat(mDropTargetBar, "translationY",
+                    -mBarHeight);
+            mQSBSearchBarFadeInAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "translationY", 0);
+            mQSBSearchBarFadeOutAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "translationY",
+                    -mBarHeight);
+        } else {
+            mDropTargetBar.setAlpha(0f);
+            mDropTargetBarFadeInAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 1f);
+            mDropTargetBarFadeOutAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 0f);
+            mQSBSearchBarFadeInAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 1f);
+            mQSBSearchBarFadeOutAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 0f);
         }
-        mDropTargetBarFadeInAnim.setDuration(sTransitionInDuration);
-        mDropTargetBarFadeInAnim.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-                mDropTargetBar.setVisibility(View.VISIBLE);
-            }
-        });
-        ObjectAnimator fadeOutAlphaAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 0f);
-        fadeOutAlphaAnim.setInterpolator(new AccelerateInterpolator());
-        mDropTargetBarFadeOutAnim = new AnimatorSet();
-        AnimatorSet.Builder fadeOutAnimators = mDropTargetBarFadeOutAnim.play(fadeOutAlphaAnim);
-        if (enableDropDownDropTargets) {
-            fadeOutAnimators.with(ObjectAnimator.ofFloat(mDropTargetBar, "translationY",
-                    -mBarHeight));
-        }
-        mDropTargetBarFadeOutAnim.setDuration(sTransitionOutDuration);
-        mDropTargetBarFadeOutAnim.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mDropTargetBar.setVisibility(View.INVISIBLE);
-                mDropTargetBar.setLayerType(View.LAYER_TYPE_NONE, null);
-            }
-        });
-        mQSBSearchBarFadeInAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 1f);
-        mQSBSearchBarFadeInAnim.setDuration(sTransitionInDuration);
-        mQSBSearchBarFadeInAnim.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-                mQSBSearchBar.setVisibility(View.VISIBLE);
-                mQSBSearchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mQSBSearchBar.setLayerType(View.LAYER_TYPE_NONE, null);
-            }
-        });
-        mQSBSearchBarFadeOutAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 0f);
-        mQSBSearchBarFadeOutAnim.setDuration(sTransitionOutDuration);
-        mQSBSearchBarFadeOutAnim.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-                mQSBSearchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mQSBSearchBar.setVisibility(View.INVISIBLE);
-                mQSBSearchBar.setLayerType(View.LAYER_TYPE_NONE, null);
-            }
-        });
+        prepareAnimation(mDropTargetBarFadeInAnim, mDropTargetBarFadeOutAnim, mDropTargetBar);
+        prepareAnimation(mQSBSearchBarFadeInAnim, mQSBSearchBarFadeOutAnim, mQSBSearchBar);
     }
 
     public void finishAnimations() {
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index fd9cc57..3910c45 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -2244,6 +2244,8 @@
                     CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
                     mTargetCell[0] = lp.cellX;
                     mTargetCell[1] = lp.cellY;
+                    CellLayout layout = (CellLayout) cell.getParent().getParent();
+                    layout.markCellsAsOccupiedForView(cell);
                 }
             }