Merge "Changing order of binding to prevent errant flashing while loading workspace."
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index af0f205..0199d01 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -255,8 +255,8 @@
                     PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(true);
                     mAnimationBuffer.setAlpha(1f);
                     mAnimationBuffer.setVisibility(View.VISIBLE);
-                    LayoutParams p = new FrameLayout.LayoutParams(child.getWidth(),
-                            child.getHeight());
+                    LayoutParams p = new FrameLayout.LayoutParams(child.getMeasuredWidth(),
+                            child.getMeasuredHeight());
                     p.setMargins((int) child.getLeft(), (int) child.getTop(), 0, 0);
                     mAnimationBuffer.addView(child, p);
                 }
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index eba89e5..2a1d65a 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -377,7 +377,11 @@
             if (rawDragInfo instanceof ShortcutInfo) {
                 ShortcutInfo dragInfo = (ShortcutInfo) rawDragInfo;
                 for (ApplicationInfo info : apps) {
-                    if (dragInfo.intent.getComponent().equals(info.intent.getComponent())) {
+                    // Added null checks to prevent NPE we've seen in the wild
+                    if (dragInfo != null &&
+                        dragInfo.intent != null &&
+                        info.intent != null &&
+                        dragInfo.intent.getComponent().equals(info.intent.getComponent())) {
                         cancelDrag();
                         return;
                     }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index ee540f8..b3ce968 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -524,6 +524,10 @@
                 // We just wanted the activity result here so we can clear mWaitingForResult
                 break;
         }
+        // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,
+        // if you turned the screen off and then back while in All Apps, Launcher would not
+        // return to the workspace. Clearing mAddInfo.container here fixes this issue
+        resetAddInfo();
         return result;
     }
 
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index cc6e23e..a9c4970 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -1383,6 +1383,7 @@
             }
 
             // shallow copy
+            @SuppressWarnings("unchecked")
             final ArrayList<ApplicationInfo> list
                     = (ArrayList<ApplicationInfo>) mAllAppsList.data.clone();
             mHandler.post(new Runnable() {
@@ -1686,7 +1687,26 @@
         // but don't worry about that.  All we're doing with usingFallbackIcon is
         // to avoid saving lots of copies of that in the database, and most apps
         // have icons anyway.
-        final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0);
+
+        // Attempt to use queryIntentActivities to get the ResolveInfo (with IntentFilter info) and
+        // if that fails, or is ambiguious, fallback to the standard way of getting the resolve info
+        // via resolveActivity().
+        ResolveInfo resolveInfo = null;
+        ComponentName oldComponent = intent.getComponent();
+        Intent newIntent = new Intent(intent.getAction(), null);
+        newIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+        newIntent.setPackage(oldComponent.getPackageName());
+        List<ResolveInfo> infos = manager.queryIntentActivities(newIntent, 0);
+        for (ResolveInfo i : infos) {
+            ComponentName cn = new ComponentName(i.activityInfo.packageName,
+                    i.activityInfo.name);
+            if (cn.equals(oldComponent)) {
+                resolveInfo = i;
+            }
+        }
+        if (resolveInfo == null) {
+            resolveInfo = manager.resolveActivity(intent, 0);
+        }
         if (resolveInfo != null) {
             icon = mIconCache.getIcon(componentName, resolveInfo, labelCache);
         }
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 5434704..604e73c 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -396,7 +396,9 @@
     protected boolean computeScrollHelper() {
         if (mScroller.computeScrollOffset()) {
             // Don't bother scrolling if the page does not need to be moved
-            if (mScrollX != mScroller.getCurrX() || mScrollY != mScroller.getCurrY()) {
+            if (mScrollX != mScroller.getCurrX()
+                || mScrollY != mScroller.getCurrY()
+                || mOverScrollX != mScroller.getCurrX()) {
                 scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
             }
             invalidate();
@@ -721,20 +723,21 @@
 
     protected void getVisiblePages(int[] range) {
         final int pageCount = getChildCount();
+
         if (pageCount > 0) {
             final int screenWidth = getMeasuredWidth();
             int leftScreen = 0;
             int rightScreen = 0;
             View currPage = getPageAt(leftScreen);
             while (leftScreen < pageCount - 1 &&
-                    currPage.getRight() - currPage.getPaddingRight() < mScrollX) {
+                    currPage.getX() + currPage.getWidth() - currPage.getPaddingRight() < mScrollX) {
                 leftScreen++;
                 currPage = getPageAt(leftScreen);
             }
             rightScreen = leftScreen;
             currPage = getPageAt(rightScreen + 1);
             while (rightScreen < pageCount - 1 &&
-                    currPage.getLeft() + currPage.getPaddingLeft() < mScrollX + screenWidth) {
+                    currPage.getX() - currPage.getPaddingLeft() < mScrollX + screenWidth) {
                 rightScreen++;
                 currPage = getPageAt(rightScreen + 1);
             }
@@ -754,9 +757,11 @@
         int screenCenter = mOverScrollX + halfScreenSize;
 
         if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
+            // set mForceScreenScrolled before calling screenScrolled so that screenScrolled can
+            // set it for the next frame
+            mForceScreenScrolled = false;
             screenScrolled(screenCenter);
             mLastScreenCenter = screenCenter;
-            mForceScreenScrolled = false;
         }
 
         // Find out which screens are visible; as an optimization we only call draw on them
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 06e0185..fd3cc1f 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -171,6 +171,7 @@
     private final Rect mTempRect = new Rect();
     private final int[] mTempXY = new int[2];
     private float mOverscrollFade = 0;
+    private boolean mOverscrollTransformsSet;
     public static final int DRAG_BITMAP_PADDING = 0;
 
     // Camera and Matrix used to determine the final position of a neighboring CellLayout
@@ -1196,9 +1197,12 @@
                                 overScrollBackgroundAlphaInterpolator(Math.abs(scrollProgress)));
                         mOverScrollPageIndex = i;
                         cl.setOverScrollAmount(Math.abs(scrollProgress), i == 0);
-                        cl.setPivotX(cl.getMeasuredWidth() * (i == 0 ? 0.75f : 0.25f));
-                        cl.setPivotY(cl.getMeasuredHeight() * 0.5f);
-                        cl.setOverscrollTransformsDirty(true);
+                        if (!mOverscrollTransformsSet) {
+                            mOverscrollTransformsSet = true;
+                            cl.setPivotX(cl.getMeasuredWidth() * (i == 0 ? 0.75f : 0.25f));
+                            cl.setPivotY(cl.getMeasuredHeight() * 0.5f);
+                            cl.setOverscrollTransformsDirty(true);
+                        }
                     } else if (mOverScrollPageIndex != i) {
                         cl.setBackgroundAlphaMultiplier(
                                 backgroundAlphaInterpolator(Math.abs(scrollProgress)));
@@ -1212,7 +1216,8 @@
                 }
             }
         }
-        if (!isSwitchingState() && !isInOverscroll) {
+        if (mOverscrollTransformsSet && !isInOverscroll) {
+            mOverscrollTransformsSet = false;
             ((CellLayout) getChildAt(0)).resetOverscrollTransforms();
             ((CellLayout) getChildAt(getChildCount() - 1)).resetOverscrollTransforms();
         }
@@ -1226,18 +1231,21 @@
             float scrollProgress = getScrollProgress(screenCenter, cl, index);
             cl.setOverScrollAmount(Math.abs(scrollProgress), index == 0);
             float rotation = - WORKSPACE_OVERSCROLL_ROTATION * scrollProgress;
-            cl.setCameraDistance(mDensity * CAMERA_DISTANCE);
-            cl.setPivotX(cl.getMeasuredWidth() * (index == 0 ? 0.75f : 0.25f));
-            cl.setPivotY(cl.getMeasuredHeight() * 0.5f);
             cl.setRotationY(rotation);
-            cl.setOverscrollTransformsDirty(true);
             setFadeForOverScroll(Math.abs(scrollProgress));
+            if (!mOverscrollTransformsSet) {
+                mOverscrollTransformsSet = true;
+                cl.setCameraDistance(mDensity * CAMERA_DISTANCE);
+                cl.setPivotX(cl.getMeasuredWidth() * (index == 0 ? 0.75f : 0.25f));
+                cl.setPivotY(cl.getMeasuredHeight() * 0.5f);
+                cl.setOverscrollTransformsDirty(true);
+            }
         } else {
             if (mOverscrollFade != 0) {
                 setFadeForOverScroll(0);
             }
-            // We don't want to mess with the translations during transitions
-            if (!isSwitchingState()) {
+            if (mOverscrollTransformsSet) {
+                mOverscrollTransformsSet = false;
                 ((CellLayout) getChildAt(0)).resetOverscrollTransforms();
                 ((CellLayout) getChildAt(getChildCount() - 1)).resetOverscrollTransforms();
             }
@@ -1568,6 +1576,7 @@
 
         final State oldState = mState;
         final boolean oldStateIsNormal = (oldState == State.NORMAL);
+        final boolean oldStateIsSpringLoaded = (oldState == State.SPRING_LOADED);
         final boolean oldStateIsSmall = (oldState == State.SMALL);
         mState = state;
         final boolean stateIsNormal = (state == State.NORMAL);
@@ -1608,8 +1617,9 @@
             if ((oldStateIsSmall && stateIsNormal) ||
                 (oldStateIsNormal && stateIsSmall)) {
                 // To/from workspace - only show the current page unless the transition is not
-                //                     animated and the animation end callback below doesn't run
-                if (i == mCurrentPage || !animated) {
+                //                     animated and the animation end callback below doesn't run;
+                //                     or, if we're in spring-loaded mode
+                if (i == mCurrentPage || !animated || oldStateIsSpringLoaded) {
                     finalAlpha = 1f;
                     finalAlphaMultiplierValue = 0f;
                 } else {
@@ -2295,7 +2305,8 @@
 
                         final LauncherAppWidgetHostView hostView = (LauncherAppWidgetHostView) cell;
                         AppWidgetProviderInfo pinfo = hostView.getAppWidgetInfo();
-                        if (pinfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE) {
+                        if (pinfo != null &&
+                                pinfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE) {
                             final Runnable addResizeFrame = new Runnable() {
                                 public void run() {
                                     DragLayer dragLayer = mLauncher.getDragLayer();