Inflate layout preview for work profile

Also fix a bug which LivePreviewCells are not used in full widgets
sheet.

Test: Temporarily replace the previewLayout with initialLayout
      from the code. Then, open both the full and bottom widgets
      sheet. Observe initial layout is rendered correctly for both
      personal and work profile.

Screenshot: https://screenshot.googleplex.com/BgJycVjzeoU3PNf.png

Bug: 181061277
Change-Id: Id635ee778008b6f94009f50bf4373d3b0f545417
diff --git a/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java b/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
index fa062f5..826ddb0 100644
--- a/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
+++ b/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
@@ -2,6 +2,7 @@
 
 import static com.android.launcher3.Utilities.ATLEAST_S;
 
+import android.appwidget.AppWidgetHostView;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -25,6 +26,8 @@
 
     private RemoteViews mPreview;
 
+    private AppWidgetHostView mPreviewAppWidgetHostView;
+
     public LivePreviewWidgetCell(Context context) {
         this(context, null);
     }
@@ -46,8 +49,11 @@
     }
 
     /** Resets any resource. This should be called before recycling this view. */
-    public void reset() {
+    @Override
+    public void clear() {
+        super.clear();
         mPreview = null;
+        mPreviewAppWidgetHostView = null;
     }
 
     @Override
@@ -60,6 +66,15 @@
                 return;
             }
         }
+
+        if (mPreviewAppWidgetHostView != null) {
+            Bitmap preview = generateFromView(mActivity, mPreviewAppWidgetHostView,
+                    mItem.widgetInfo, mPreviewWidth, new int[1]);
+            if (preview != null) {
+                applyPreview(preview);
+                return;
+            }
+        }
         super.ensurePreview();
     }
 
@@ -69,8 +84,19 @@
                 && mPreview == null
                 && item.widgetInfo != null
                 && item.widgetInfo.previewLayout != Resources.ID_NULL) {
-            mPreview = new RemoteViews(item.widgetInfo.provider.getPackageName(),
-                    item.widgetInfo.previewLayout);
+            mPreviewAppWidgetHostView = new AppWidgetHostView(getContext());
+            LauncherAppWidgetProviderInfo launcherAppWidgetProviderInfo =
+                    LauncherAppWidgetProviderInfo.fromProviderInfo(getContext(),
+                            item.widgetInfo.clone());
+            // A hack to force the initial layout to be the preview layout since there is no API for
+            // rendering a preview layout for work profile apps yet. For non-work profile layout, a
+            // proper solution is to use RemoteViews(PackageName, LayoutId).
+            launcherAppWidgetProviderInfo.initialLayout = item.widgetInfo.previewLayout;
+            mPreviewAppWidgetHostView.setAppWidget(/* appWidgetId= */ -1,
+                    launcherAppWidgetProviderInfo);
+            mPreviewAppWidgetHostView.setPadding(/* left= */ 0, /* top= */0, /* right= */
+                    0, /* bottom= */ 0);
+            mPreviewAppWidgetHostView.updateAppWidget(/* remoteViews= */ null);
         }
 
         super.applyFromCellItem(item, loader);
@@ -84,23 +110,27 @@
      */
     public static Bitmap generateFromRemoteViews(BaseActivity activity, RemoteViews views,
             LauncherAppWidgetProviderInfo info, int previewSize, int[] preScaledWidthOut) {
+        try {
+            return generateFromView(activity, views.apply(activity, new FrameLayout(activity)),
+                    info, previewSize, preScaledWidthOut);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private static Bitmap generateFromView(BaseActivity activity, View v,
+            LauncherAppWidgetProviderInfo info, int previewSize, int[] preScaledWidthOut) {
 
         DeviceProfile dp = activity.getDeviceProfile();
         int viewWidth = dp.cellWidthPx * info.spanX;
         int viewHeight = dp.cellHeightPx * info.spanY;
 
-        final View v;
-        try {
-            v = views.apply(activity, new FrameLayout(activity));
-            v.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY),
-                    MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY));
+        v.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY));
 
-            viewWidth = v.getMeasuredWidth();
-            viewHeight = v.getMeasuredHeight();
-            v.layout(0, 0, viewWidth, viewHeight);
-        } catch (Exception e) {
-            return null;
-        }
+        viewWidth = v.getMeasuredWidth();
+        viewHeight = v.getMeasuredHeight();
+        v.layout(0, 0, viewWidth, viewHeight);
 
         preScaledWidthOut[0] = viewWidth;
         final int bitmapWidth, bitmapHeight;
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 8c315fd..ea6f0c3 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -61,8 +61,8 @@
     /** Widget preview width is calculated by multiplying this factor to the widget cell width. */
     private static final float PREVIEW_SCALE = 0.8f;
 
-    private int mPreviewWidth;
-    private int mPreviewHeight;
+    protected int mPreviewWidth;
+    protected int mPreviewHeight;
     protected int mPresetPreviewSize;
     private int mCellSize;
 
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
index 9c8684a..28ffd54 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
@@ -153,7 +153,7 @@
             } else {
                 for (int j = tableRow.getChildCount(); j < widgetItems.size(); j++) {
                     WidgetCell widget = (WidgetCell) mLayoutInflater.inflate(
-                            R.layout.widget_cell, tableRow, false);
+                            R.layout.live_preview_widget_cell, tableRow, false);
                     // set up touch.
                     widget.setOnClickListener(mIconClickListener);
                     widget.setOnLongClickListener(mIconLongClickListener);