Merge "resolve merge conflicts of 46378eb881ab96b90a7a2922775ecceb184456c7 to sc-v2-dev" into sc-v2-dev
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 357d407..076f28a 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1821,7 +1821,7 @@
 
     // Scaling of RecentsView during quick switch based on amount of recents scroll
     private float getScaleProgressDueToScroll() {
-        if (!mActivity.getDeviceProfile().isTablet || mRecentsView == null
+        if (mActivity == null || !mActivity.getDeviceProfile().isTablet || mRecentsView == null
                 || !mRecentsViewScrollLinked) {
             return 0;
         }
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 20f5f9b..74b0d9c 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -709,6 +709,7 @@
         final int scrollOffsetStart = mOrientationHandler.getScrollOffsetStart(this, mInsets);
         final int scrollOffsetEnd = mOrientationHandler.getScrollOffsetEnd(this, mInsets);
         boolean pageScrollChanged = false;
+        int panelCount = getPanelCount();
 
         for (int i = startIndex, childStart = scrollOffsetStart; i != endIndex; i += delta) {
             final View child = getPageAt(i);
@@ -726,11 +727,15 @@
                     pageScrollChanged = true;
                     outPageScrolls[i] = pageScroll;
                 }
-                childStart += primaryDimension + mPageSpacing + getChildGap();
+                childStart += primaryDimension + getChildGap();
+
+                // This makes sure that the space is added after the page, not after each panel
+                if (i % panelCount == panelCount - 1) {
+                    childStart += mPageSpacing;
+                }
             }
         }
 
-        int panelCount = getPanelCount();
         if (panelCount > 1) {
             for (int i = 0; i < childCount; i++) {
                 // In case we have multiple panels, always use left panel's page scroll for all
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index a585be6..6c0e893 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -315,9 +315,19 @@
         // Increase our bottom insets so we don't overlap with the taskbar.
         mInsets.bottom += grid.nonOverlappingTaskbarInset;
 
-        if (grid.isTwoPanels) {
-            setPageSpacing(0); // we have two pages and we don't want any spacing
+        if (mWorkspaceFadeInAdjacentScreens) {
+            // In landscape mode the page spacing is set to the default.
+            setPageSpacing(grid.edgeMarginPx);
+        } else {
+            // In portrait, we want the pages spaced such that there is no
+            // overhang of the previous / next page into the current page viewport.
+            // We assume symmetrical padding in portrait mode.
+            int maxInsets = Math.max(insets.left, insets.right);
+            int maxPadding = Math.max(grid.edgeMarginPx, padding.left + 1);
+            setPageSpacing(Math.max(maxInsets, maxPadding));
+        }
 
+        if (grid.isTwoPanels) {
             // Add left widget panel if it isn't already there
             if (!mWorkspaceScreens.containsKey(LEFT_PANEL_ID)) {
                 int newCurrentPage = mCurrentPage + 1;
@@ -325,18 +335,6 @@
                 setCurrentPage(newCurrentPage);
             }
         } else {
-            if (mWorkspaceFadeInAdjacentScreens) {
-                // In landscape mode the page spacing is set to the default.
-                setPageSpacing(grid.edgeMarginPx);
-            } else {
-                // In portrait, we want the pages spaced such that there is no
-                // overhang of the previous / next page into the current page viewport.
-                // We assume symmetrical padding in portrait mode.
-                int maxInsets = Math.max(insets.left, insets.right);
-                int maxPadding = Math.max(grid.edgeMarginPx, padding.left + 1);
-                setPageSpacing(Math.max(maxInsets, maxPadding));
-            }
-
             // Remove left widget panel if it is present
             if (mWorkspaceScreens.containsKey(LEFT_PANEL_ID)) {
                 int newCurrentPage = mCurrentPage - 1;
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 6bd6261..92ed18a 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -192,15 +192,15 @@
             float appWidgetHostViewScale = mWidgetCell.getAppWidgetHostViewScale();
             int xOffset =
                     appWidgetHostView.getLeft() - (int) (mLastTouchPos.x * appWidgetHostViewScale);
-            int yOffset = appWidgetHostView.getTop()
-                    - (int) (mLastTouchPos.y * mWidgetCell.getAppWidgetHostViewScale());
+            int yOffset =
+                    appWidgetHostView.getTop() - (int) (mLastTouchPos.y * appWidgetHostViewScale);
             bounds.offset(xOffset, yOffset);
             listener = new PinItemDragListener(
                     mRequest,
                     bounds,
                     appWidgetHostView.getMeasuredWidth(),
                     appWidgetHostView.getMeasuredWidth(),
-                    appWidgetHostView.getScaleX());
+                    appWidgetHostViewScale);
         } else {
             bounds = img.getBitmapBounds();
             bounds.offset(img.getLeft() - (int) mLastTouchPos.x,
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index ee44174..8e9769c 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -188,11 +188,11 @@
             dragHelper.startDrag(image.getBitmapBounds(), image.getDrawable().getIntrinsicWidth(),
                     image.getWidth(), new Point(loc[0], loc[1]), this, new DragOptions());
         } else {
-            View preview = v.getAppWidgetHostViewPreview();
+            NavigableAppWidgetHostView preview = v.getAppWidgetHostViewPreview();
             int[] loc = new int[2];
             getPopupContainer().getLocationInDragLayer(preview, loc);
-
-            Rect r = new Rect(0, 0, preview.getWidth(), preview.getHeight());
+            Rect r = new Rect();
+            preview.getWorkspaceVisualDragBounds(r);
             dragHelper.startDrag(r, preview.getMeasuredWidth(), preview.getMeasuredWidth(),
                     new Point(loc[0], loc[1]), this, new DragOptions());
         }
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index fb6de9f..0313e68 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -84,10 +84,8 @@
     private boolean mIsScrollable;
     private boolean mIsAttachedToWindow;
     private boolean mIsAutoAdvanceRegistered;
-    private boolean mIsInDragMode = false;
     private Runnable mAutoAdvanceRunnable;
     private RectF mLastLocationRegistered = null;
-    @Nullable private AppWidgetHostViewDragListener mDragListener;
 
     // Used to store the widget sizes in drag layer coordinates.
     private final Rect mCurrentWidgetSize = new Rect();
@@ -102,6 +100,14 @@
     private @Nullable SparseIntArray mDeferredColorChange = null;
     private boolean mEnableColorExtraction = true;
 
+    // The following member variables are only used during drag-n-drop.
+    private boolean mIsInDragMode = false;
+    @Nullable private AppWidgetHostViewDragListener mDragListener;
+    /** The drag content width which is only set when the drag content scale is not 1f. */
+    private int mDragContentWidth = 0;
+    /** The drag content height which is only set when the drag content scale is not 1f. */
+    private int mDragContentHeight = 0;
+
     public LauncherAppWidgetHostView(Context context) {
         super(context);
         mLauncher = Launcher.getLauncher(context);
@@ -310,10 +316,28 @@
         updateColorExtraction();
     }
 
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        if (mIsInDragMode && mDragContentWidth > 0 && mDragContentHeight > 0
+                && getChildCount() == 1) {
+            measureChild(getChildAt(0), MeasureSpec.getSize(mDragContentWidth),
+                    MeasureSpec.getSize(mDragContentHeight));
+        }
+    }
+
     /** Starts the drag mode. */
     public void startDrag(AppWidgetHostViewDragListener dragListener) {
         mIsInDragMode = true;
         mDragListener = dragListener;
+        // In the case of dragging a scaled preview from widgets picker, we should reuse the
+        // previously measured dimension from WidgetCell#measureAndComputeWidgetPreviewScale, which
+        // measures the dimension of a widget preview without its parent's bound before scaling
+        // down.
+        if ((getScaleX() != 1f || getScaleY() != 1f) && getChildCount() == 1) {
+            mDragContentWidth = getChildAt(0).getMeasuredWidth();
+            mDragContentHeight = getChildAt(0).getMeasuredHeight();
+        }
     }
 
     /** Handles a drag event occurred on a workspace page, {@code pageId}. */
@@ -326,6 +350,8 @@
     public void endDrag() {
         mIsInDragMode = false;
         mDragListener = null;
+        mDragContentWidth = 0;
+        mDragContentHeight = 0;
         mWidgetSizeAtDrag.setEmpty();
     }
 
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index d3f4528..167eb09 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -18,6 +18,7 @@
 
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY;
 import static com.android.launcher3.Utilities.ATLEAST_S;
@@ -372,7 +373,7 @@
                 if (shouldScale) {
                     setNoClip(mWidgetImageContainer);
                     setNoClip(mAppWidgetHostViewPreview);
-                    mAppWidgetHostViewScale = computeWidgetPreviewScale();
+                    mAppWidgetHostViewScale = measureAndComputeWidgetPreviewScale();
                     mAppWidgetHostViewPreview.setScaleToFit(mAppWidgetHostViewScale);
                 }
             }
@@ -473,7 +474,7 @@
         view.setClipToPadding(false);
     }
 
-    private float computeWidgetPreviewScale() {
+    private float measureAndComputeWidgetPreviewScale() {
         if (mAppWidgetHostViewPreview.getChildCount() != 1) {
             return 1f;
         }
@@ -482,12 +483,25 @@
         mAppWidgetHostViewPreview.measure(
                 makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED),
                 makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED));
-        int appWidgetContentWidth = mAppWidgetHostViewPreview.getChildAt(0).getMeasuredWidth();
-        int appWidgetContentHeight = mAppWidgetHostViewPreview.getChildAt(0).getMeasuredHeight();
+        View widgetContent = mAppWidgetHostViewPreview.getChildAt(0);
+        int appWidgetContentWidth = widgetContent.getMeasuredWidth();
+        int appWidgetContentHeight = widgetContent.getMeasuredHeight();
         if (appWidgetContentWidth == 0 || appWidgetContentHeight == 0) {
             return 1f;
         }
 
+        // If the width / height of the widget content is set to wrap content, overrides the width /
+        // height with the measured dimension. This avoids incorrect measurement after scaling.
+        FrameLayout.LayoutParams layoutParam =
+                (FrameLayout.LayoutParams) widgetContent.getLayoutParams();
+        if (layoutParam.width == WRAP_CONTENT) {
+            layoutParam.width = widgetContent.getMeasuredWidth();
+        }
+        if (layoutParam.height == WRAP_CONTENT) {
+            layoutParam.height = widgetContent.getMeasuredHeight();
+        }
+        widgetContent.setLayoutParams(layoutParam);
+
         int horizontalPadding = mAppWidgetHostViewPreview.getPaddingStart()
                 + mAppWidgetHostViewPreview.getPaddingEnd();
         int verticalPadding = mAppWidgetHostViewPreview.getPaddingTop()