Fix bug where very large widgets get cropped out

Fix: 268715418
Test: Open widget picker on tablet and verify that very large widgets (eg Youtube music recently played) are not cropped on tablets
Change-Id: I0f4609c8b7af889f39cac304ad4f6a44039f5762
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 80bc1a7..9984991 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.widget;
 
+import static android.view.View.MeasureSpec.getSize;
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
@@ -118,6 +119,8 @@
     private TextView mWidgetName;
     private TextView mWidgetDims;
     private TextView mWidgetDescription;
+    private Consumer<Bitmap> mCallback;
+    private @Nullable Bitmap mCachedPreview;
 
     protected WidgetItem mItem;
 
@@ -429,6 +432,8 @@
      */
     private void ensurePreviewWithCallback(Consumer<Bitmap> callback,
             @Nullable Bitmap cachedPreview) {
+        mCallback = callback;
+        mCachedPreview = cachedPreview;
         if (mAppWidgetHostViewPreview != null) {
             int containerWidth = (int) (mTargetPreviewWidth * mPreviewContainerScale);
             int containerHeight = (int) (mTargetPreviewHeight * mPreviewContainerScale);
@@ -469,6 +474,7 @@
                     INDEX_WIDGET_CENTERING,
                     -(params.width - (params.width * mPreviewContainerScale)) / 2.0f,
                     -(params.height - (params.height * mPreviewContainerScale)) / 2.0f);
+            mWidgetImageContainer.removeAllViews();
             mWidgetImageContainer.addView(mAppWidgetHostViewPreview, /* index= */ 0);
             mWidgetImage.setVisibility(View.GONE);
             applyPreview(null);
@@ -579,4 +585,19 @@
                 (mTargetPreviewHeight - verticalPadding) * mPreviewContainerScale
                         / appWidgetContentHeight);
     }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int padding = getPaddingLeft() + getPaddingRight();
+        int allowedWidth = getSize(widthMeasureSpec) - padding;
+
+        // Here we prevent having clipped widgets when they're too large as the preview width is
+        // larger than the max allowed width. We then re-do the preview with the new preview width
+        if (allowedWidth > 0 && mCachedPreview == null && allowedWidth < mTargetPreviewWidth) {
+            mTargetPreviewWidth = allowedWidth;
+            ensurePreviewWithCallback(mCallback, null);
+        }
+
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
 }