Merge "Hooks for subclasses to react to home presses." into jb-ub-now-jolly-elf
diff --git a/src/com/android/launcher3/CropView.java b/src/com/android/launcher3/CropView.java
index 9224e3b..578b8ea 100644
--- a/src/com/android/launcher3/CropView.java
+++ b/src/com/android/launcher3/CropView.java
@@ -165,7 +165,8 @@
                 final float imageWidth = imageDims[0];
                 final float imageHeight = imageDims[1];
                 mMinScale = Math.max(w / imageWidth, h / imageHeight);
-                mRenderer.scale = Math.max(mMinScale, mRenderer.scale);
+                mRenderer.scale =
+                        Math.max(mMinScale, resetScale ? Float.MIN_VALUE : mRenderer.scale);
             }
         }
     }
diff --git a/src/com/android/launcher3/DragController.java b/src/com/android/launcher3/DragController.java
index 5e733f0..ab48233 100644
--- a/src/com/android/launcher3/DragController.java
+++ b/src/com/android/launcher3/DragController.java
@@ -327,7 +327,7 @@
                 for (AppInfo info : appInfos) {
                     // Added null checks to prevent NPE we've seen in the wild
                     if (dragInfo != null &&
-                        dragInfo.intent != null) {
+                            dragInfo.intent != null && info != null) {
                         ComponentName cn = dragInfo.intent.getComponent();
                         boolean isSameComponent = cn.equals(info.componentName) ||
                                 packageNames.contains(cn.getPackageName());
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index bd61010..0514615 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -119,6 +119,11 @@
     private int DRAG_MODE_REORDER = 1;
     private int mDragMode = DRAG_MODE_NONE;
 
+    // We avoid measuring the scroll view with a 0 width or height, as this
+    // results in CellLayout being measured as UNSPECIFIED, which it does
+    // not support.
+    private static final int MIN_CONTENT_DIMEN = 5;
+
     private boolean mDestroyed;
 
     private AutoScrollHelper mAutoScrollHelper;
@@ -758,6 +763,8 @@
                 }
                 completeDragExit();
             }
+        } else {
+            mLauncher.getWorkspace().removeExtraEmptyScreen(true, null);
         }
 
         mDeleteFolderOnDropCompleted = false;
@@ -959,8 +966,13 @@
         int maxContentAreaHeight = grid.availableHeightPx -
                 workspacePadding.top - workspacePadding.bottom -
                 mFolderNameHeight;
-        return Math.min(maxContentAreaHeight,
+        int height = Math.min(maxContentAreaHeight,
                 mContent.getDesiredHeight());
+        return Math.max(height, MIN_CONTENT_DIMEN);
+    }
+
+    private int getContentAreaWidth() {
+        return Math.max(mContent.getDesiredWidth(), MIN_CONTENT_DIMEN);
     }
 
     private int getFolderHeight() {
@@ -972,11 +984,12 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
         int height = getFolderHeight();
-        int contentAreaWidthSpec = MeasureSpec.makeMeasureSpec(mContent.getDesiredWidth(),
+        int contentAreaWidthSpec = MeasureSpec.makeMeasureSpec(getContentAreaWidth(),
                 MeasureSpec.EXACTLY);
         int contentAreaHeightSpec = MeasureSpec.makeMeasureSpec(getContentAreaHeight(),
                 MeasureSpec.EXACTLY);
-        mContent.setFixedSize(mContent.getDesiredWidth(), mContent.getDesiredHeight());
+
+        mContent.setFixedSize(getContentAreaWidth(), getContentAreaHeight());
         mScrollView.measure(contentAreaWidthSpec, contentAreaHeightSpec);
         mFolderName.measure(contentAreaWidthSpec,
                 MeasureSpec.makeMeasureSpec(mFolderNameHeight, MeasureSpec.EXACTLY));
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 84173b0..c26975c 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1191,7 +1191,9 @@
         widgetButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View arg0) {
-                showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+                if (!mWorkspace.isSwitchingState()) {
+                    showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+                }
             }
         });
         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());
@@ -1200,7 +1202,9 @@
         wallpaperButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View arg0) {
-                startWallpaper();
+                if (!mWorkspace.isSwitchingState()) {
+                    startWallpaper();
+                }
             }
         });
         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());
@@ -1209,7 +1213,9 @@
         settingsButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View arg0) {
-                startSettings();
+                if (!mWorkspace.isSwitchingState()) {
+                    startSettings();
+                }
             }
         });
         settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
@@ -3970,6 +3976,11 @@
         return bounceAnim;
     }
 
+    public boolean useVerticalBarLayout() {
+        return LauncherAppState.getInstance().getDynamicGrid().
+                getDeviceProfile().isVerticalBarLayout();
+    }
+
     @Override
     public void bindSearchablesChanged() {
         boolean searchVisible = updateGlobalSearchIcon();
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 7b56625..3eecedb 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -902,6 +902,7 @@
         int verticalPadding = getPaddingTop() + getPaddingBottom();
 
         LayoutParams lp = (LayoutParams) getChildAt(startIndex).getLayoutParams();
+        LayoutParams nextLp;
 
         int childLeft = offsetX + (lp.isFullScreenPage ? 0 : getPaddingLeft());
         if (mPageScrolls == null || getChildCount() != mChildCountOnLastLayout) {
@@ -931,7 +932,24 @@
 
                 int scrollOffsetLeft = lp.isFullScreenPage ? 0 : getPaddingLeft();
                 mPageScrolls[i] = childLeft - scrollOffsetLeft - offsetX;
-                childLeft += childWidth + mPageSpacing;
+
+                int pageGap = mPageSpacing;
+                int next = i + delta;
+                if (next != endIndex) {
+                    nextLp = (LayoutParams) getPageAt(next).getLayoutParams();
+                } else {
+                    nextLp = null;
+                }
+
+                // Prevent full screen pages from showing in the viewport
+                // when they are not the current page.
+                if (lp.isFullScreenPage) {
+                    pageGap = getPaddingLeft();
+                } else if (nextLp != null && nextLp.isFullScreenPage) {
+                    pageGap = getPaddingRight();
+                }
+
+                childLeft += childWidth + pageGap;
             }
         }
 
diff --git a/src/com/android/launcher3/WallpaperCropActivity.java b/src/com/android/launcher3/WallpaperCropActivity.java
index 276aba3..65223ad 100644
--- a/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/src/com/android/launcher3/WallpaperCropActivity.java
@@ -550,6 +550,8 @@
                 Rect roundedTrueCrop = new Rect();
                 Matrix rotateMatrix = new Matrix();
                 Matrix inverseRotateMatrix = new Matrix();
+
+                Point bounds = getImageBounds();
                 if (mRotation > 0) {
                     rotateMatrix.setRotate(mRotation);
                     inverseRotateMatrix.setRotate(-mRotation);
@@ -557,7 +559,6 @@
                     mCropBounds.roundOut(roundedTrueCrop);
                     mCropBounds = new RectF(roundedTrueCrop);
 
-                    Point bounds = getImageBounds();
                     if (bounds == null) {
                         Log.w(LOGTAG, "cannot get bounds for image");
                         failure = true;
@@ -629,12 +630,38 @@
                         Utils.closeSilently(is);
                     }
                     if (fullSize != null) {
+                        // Find out the true sample size that was used by the decoder
+                        scaleDownSampleSize = bounds.x / fullSize.getWidth();
                         mCropBounds.left /= scaleDownSampleSize;
                         mCropBounds.top /= scaleDownSampleSize;
                         mCropBounds.bottom /= scaleDownSampleSize;
                         mCropBounds.right /= scaleDownSampleSize;
                         mCropBounds.roundOut(roundedTrueCrop);
 
+                        // Adjust values to account for issues related to rounding
+                        if (roundedTrueCrop.width() > fullSize.getWidth()) {
+                            // Adjust the width
+                            roundedTrueCrop.right = roundedTrueCrop.left + fullSize.getWidth();
+                        }
+                        if (roundedTrueCrop.right > fullSize.getWidth()) {
+                            // Adjust the left value
+                            int adjustment = roundedTrueCrop.left -
+                                    Math.max(0, roundedTrueCrop.right - roundedTrueCrop.width());
+                            roundedTrueCrop.left -= adjustment;
+                            roundedTrueCrop.right -= adjustment;
+                        }
+                        if (roundedTrueCrop.height() > fullSize.getHeight()) {
+                            // Adjust the height
+                            roundedTrueCrop.bottom = roundedTrueCrop.top + fullSize.getHeight();
+                        }
+                        if (roundedTrueCrop.bottom > fullSize.getHeight()) {
+                            // Adjust the top value
+                            int adjustment = roundedTrueCrop.top -
+                                    Math.max(0, roundedTrueCrop.bottom - roundedTrueCrop.height());
+                            roundedTrueCrop.top -= adjustment;
+                            roundedTrueCrop.bottom -= adjustment;
+                        }
+
                         crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
                                 roundedTrueCrop.top, roundedTrueCrop.width(),
                                 roundedTrueCrop.height());
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 7692ae6..6c346c4 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1481,7 +1481,7 @@
                 mState == State.NORMAL &&
                 !mIsSwitchingState &&
                 !isInOverscroll) {
-            for (int i = 0; i < getChildCount(); i++) {
+            for (int i = numCustomPages(); i < getChildCount(); i++) {
                 CellLayout child = (CellLayout) getChildAt(i);
                 if (child != null) {
                     float scrollProgress = getScrollProgress(screenCenter, child, i);
@@ -2536,6 +2536,13 @@
             icon.clearPressedOrFocusedBackground();
         }
 
+        if (child.getTag() == null || !(child.getTag() instanceof ItemInfo)) {
+            String msg = "Drag started with a view that has no tag set. This "
+                    + "will cause a crash (issue 11627249) down the line. "
+                    + "View: " + child + "  tag: " + child.getTag();
+            throw new IllegalStateException(msg);
+        }
+
         mDragController.startDrag(b, dragLayerX, dragLayerY, source, child.getTag(),
                 DragController.DRAG_ACTION_MOVE, dragVisualizeOffset, dragRect, scale);