From 46b0d8e29193206ca24a0589d01932294ee8478a Mon Sep 17 00:00:00 2001 From: Steven Ng Date: Wed, 3 Mar 2021 18:23:01 +0000 Subject: [PATCH] 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 --- .../dragndrop/LivePreviewWidgetCell.java | 58 ++++++++++++++----- .../android/launcher3/widget/WidgetCell.java | 4 +- .../WidgetsListTableViewHolderBinder.java | 2 +- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java b/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java index fa062f572e..826ddb0b4e 100644 --- a/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java +++ b/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java @@ -2,6 +2,7 @@ package com.android.launcher3.dragndrop; 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 @@ public class LivePreviewWidgetCell extends WidgetCell { private RemoteViews mPreview; + private AppWidgetHostView mPreviewAppWidgetHostView; + public LivePreviewWidgetCell(Context context) { this(context, null); } @@ -46,8 +49,11 @@ public class LivePreviewWidgetCell extends WidgetCell { } /** 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 @@ public class LivePreviewWidgetCell extends WidgetCell { 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 @@ public class LivePreviewWidgetCell extends WidgetCell { && 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 class LivePreviewWidgetCell extends WidgetCell { */ 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 8c315fd604..ea6f0c35c1 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -61,8 +61,8 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { /** 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 9c8684a0bc..28ffd5473a 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java @@ -153,7 +153,7 @@ public final class WidgetsListTableViewHolderBinder } 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);