diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java index fc635a91db..d5a04a647d 100644 --- a/src/com/android/launcher3/dragndrop/AddItemActivity.java +++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java @@ -59,6 +59,7 @@ import com.android.launcher3.pm.PinRequestHelper; import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.widget.LauncherAppWidgetHost; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; +import com.android.launcher3.widget.NavigableAppWidgetHostView; import com.android.launcher3.widget.PendingAddShortcutInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; import com.android.launcher3.widget.WidgetCell; @@ -147,20 +148,31 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener public boolean onLongClick(View view) { // Find the position of the preview relative to the touch location. WidgetImageView img = mWidgetCell.getWidgetView(); + NavigableAppWidgetHostView appWidgetHostView = mWidgetCell.getAppWidgetHostViewPreview(); // If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and // we abort the drag. - if (img.getDrawable() == null) { + if (img.getDrawable() == null && appWidgetHostView == null) { return false; } - Rect bounds = img.getBitmapBounds(); - bounds.offset(img.getLeft() - (int) mLastTouchPos.x, img.getTop() - (int) mLastTouchPos.y); - + final Rect bounds; // Start home and pass the draw request params - PinItemDragListener listener = new PinItemDragListener(mRequest, bounds, - img.getDrawable().getIntrinsicWidth(), img.getWidth()); - + final PinItemDragListener listener; + if (appWidgetHostView != null) { + bounds = new Rect(); + appWidgetHostView.getSourceVisualDragBounds(bounds); + bounds.offset(appWidgetHostView.getLeft() - (int) mLastTouchPos.x, + appWidgetHostView.getTop() - (int) mLastTouchPos.y); + listener = new PinItemDragListener(mRequest, bounds, + appWidgetHostView.getMeasuredWidth(), appWidgetHostView.getMeasuredWidth()); + } else { + bounds = img.getBitmapBounds(); + bounds.offset(img.getLeft() - (int) mLastTouchPos.x, + img.getTop() - (int) mLastTouchPos.y); + listener = new PinItemDragListener(mRequest, bounds, + img.getDrawable().getIntrinsicWidth(), img.getWidth()); + } // Start a system drag and drop. We use a transparent bitmap as preview for system drag // as the preview is handled internally by launcher. @@ -214,7 +226,7 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener // Cannot add widget return false; } - mWidgetCell.setPreview(PinItemDragListener.getPreview(mRequest)); + mWidgetCell.setRemoteViewsPreview(PinItemDragListener.getPreview(mRequest)); mAppWidgetManager = new WidgetManagerHelper(this); mAppWidgetHost = new LauncherAppWidgetHost(this); @@ -238,6 +250,7 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener @Override protected void onPostExecute(WidgetItem item) { + mWidgetCell.setPreviewSize(item.spanX, item.spanY); mWidgetCell.applyFromCellItem(item, mApp.getWidgetCache()); mWidgetCell.ensurePreview(); } diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java index 95b887c4c6..415f48d30f 100644 --- a/src/com/android/launcher3/widget/BaseWidgetSheet.java +++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java @@ -114,7 +114,7 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView } PendingItemDragHelper dragHelper = new PendingItemDragHelper(v); - dragHelper.setRemoteViewsPreview(v.getPreview()); + dragHelper.setRemoteViewsPreview(v.getRemoteViewsPreview()); dragHelper.setAppWidgetHostViewPreview(v.getAppWidgetHostViewPreview()); if (image.getDrawable() != null) { diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java index df368cd3e5..cea4de7b37 100644 --- a/src/com/android/launcher3/widget/PendingItemDragHelper.java +++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java @@ -23,6 +23,7 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.view.View; +import android.view.View.MeasureSpec; import android.widget.RemoteViews; import androidx.annotation.Nullable; @@ -53,7 +54,7 @@ public class PendingItemDragHelper extends DragPreviewProvider { private int[] mEstimatedCellSize; @Nullable private RemoteViews mRemoteViewsPreview; - @Nullable private LauncherAppWidgetHostView mAppWidgetHostViewPreview; + @Nullable private NavigableAppWidgetHostView mAppWidgetHostViewPreview; private final float mEnforcedRoundedCornersForWidget; public PendingItemDragHelper(View view) { @@ -71,9 +72,9 @@ public class PendingItemDragHelper extends DragPreviewProvider { mRemoteViewsPreview = remoteViewsPreview; } - /** Sets a {@link LauncherAppWidgetHostView} which shows a preview layout of an app widget. */ + /** Sets a {@link NavigableAppWidgetHostView} which shows a preview layout of an app widget. */ public void setAppWidgetHostViewPreview( - @Nullable LauncherAppWidgetHostView appWidgetHostViewPreview) { + @Nullable NavigableAppWidgetHostView appWidgetHostViewPreview) { mAppWidgetHostViewPreview = appWidgetHostViewPreview; } @@ -110,9 +111,22 @@ public class PendingItemDragHelper extends DragPreviewProvider { int[] previewSizeBeforeScale = new int[1]; if (mRemoteViewsPreview != null) { - preview = new FastBitmapDrawable( - WidgetCell.generateFromRemoteViews(launcher, mRemoteViewsPreview, - createWidgetInfo.info, maxWidth, previewSizeBeforeScale)); + mAppWidgetHostViewPreview = new LauncherAppWidgetHostView(launcher); + mAppWidgetHostViewPreview.setAppWidget(/* appWidgetId= */ -1, + ((PendingAddWidgetInfo) mAddInfo).info); + DeviceProfile deviceProfile = launcher.getDeviceProfile(); + Rect padding = new Rect(); + mAppWidgetHostViewPreview.getWidgetInset(deviceProfile, padding); + mAppWidgetHostViewPreview.setPadding(padding.left, padding.top, padding.right, + padding.bottom); + mAppWidgetHostViewPreview.updateAppWidget(/* remoteViews= */ mRemoteViewsPreview); + int width = + deviceProfile.cellWidthPx * mAddInfo.spanX + padding.left + padding.right; + int height = + deviceProfile.cellHeightPx * mAddInfo.spanY + padding.top + padding.bottom; + mAppWidgetHostViewPreview.measure( + MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); } if (mAppWidgetHostViewPreview != null) { previewSizeBeforeScale[0] = mAppWidgetHostViewPreview.getMeasuredWidth(); diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java index c08160bbef..3fcd3f7b03 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -46,7 +46,6 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.WidgetPreviewLoader; import com.android.launcher3.icons.BaseIconFactory; -import com.android.launcher3.icons.BitmapRenderer; import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.icons.RoundDrawableWrapper; import com.android.launcher3.model.WidgetItem; @@ -100,8 +99,8 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { private final CheckLongPressHelper mLongPressHelper; private final float mEnforcedCornerRadius; - private RemoteViews mPreview; - private LauncherAppWidgetHostView mAppWidgetHostViewPreview; + private RemoteViews mRemoteViewsPreview; + private NavigableAppWidgetHostView mAppWidgetHostViewPreview; public WidgetCell(Context context) { this(context, null); @@ -143,12 +142,13 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { mWidgetDescription = findViewById(R.id.widget_description); } - public void setPreview(RemoteViews view) { - mPreview = view; + public void setRemoteViewsPreview(RemoteViews view) { + mRemoteViewsPreview = view; } - public RemoteViews getPreview() { - return mPreview; + @Nullable + public RemoteViews getRemoteViewsPreview() { + return mRemoteViewsPreview; } /** @@ -172,7 +172,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { mActiveRequest.cancel(); mActiveRequest = null; } - mPreview = null; + mRemoteViewsPreview = null; if (mAppWidgetHostViewPreview != null) { mWidgetImageContainer.removeView(mAppWidgetHostViewPreview); } @@ -180,7 +180,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { } public void applyFromCellItem(WidgetItem item, WidgetPreviewLoader loader) { - applyPreviewLayout(item); + applyPreviewOnAppWidgetHostView(item); mItem = item; mWidgetName.setText(mItem.label); @@ -206,9 +206,26 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { } } - private void applyPreviewLayout(WidgetItem item) { + + private void applyPreviewOnAppWidgetHostView(WidgetItem item) { + if (mRemoteViewsPreview != null) { + mAppWidgetHostViewPreview = new NavigableAppWidgetHostView(getContext()) { + @Override + protected boolean shouldAllowDirectClick() { + return false; + } + }; + mAppWidgetHostViewPreview.setAppWidget(/* appWidgetId= */ -1, item.widgetInfo); + Rect padding = new Rect(); + mAppWidgetHostViewPreview.getWidgetInset(mActivity.getDeviceProfile(), padding); + mAppWidgetHostViewPreview.setPadding(padding.left, padding.top, padding.right, + padding.bottom); + mAppWidgetHostViewPreview.updateAppWidget(/* remoteViews= */ mRemoteViewsPreview); + return; + } + if (ATLEAST_S - && mPreview == null + && mRemoteViewsPreview == null && item.widgetInfo != null && item.widgetInfo.previewLayout != Resources.ID_NULL) { mAppWidgetHostViewPreview = new LauncherAppWidgetHostView(getContext()); @@ -234,7 +251,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { } @Nullable - public LauncherAppWidgetHostView getAppWidgetHostViewPreview() { + public NavigableAppWidgetHostView getAppWidgetHostViewPreview() { return mAppWidgetHostViewPreview; } @@ -303,15 +320,6 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { } public void ensurePreview() { - if (mPreview != null && mActiveRequest == null) { - Bitmap preview = generateFromRemoteViews( - mActivity, mPreview, mItem.widgetInfo, mPresetPreviewSize, new int[1]); - if (preview != null) { - applyPreview(new FastBitmapDrawable(preview)); - return; - } - } - if (mAppWidgetHostViewPreview != null) { setContainerSize(mPreviewWidth, mPreviewHeight); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( @@ -385,53 +393,4 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { super.onInitializeAccessibilityNodeInfo(info); info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK); } - - /** - * Generates a bitmap by inflating {@param views}. - * @see com.android.launcher3.WidgetPreviewLoader#generateWidgetPreview - * - * TODO: Consider moving this to the background thread. - */ - 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; - - v.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY)); - - viewWidth = v.getMeasuredWidth(); - viewHeight = v.getMeasuredHeight(); - v.layout(0, 0, viewWidth, viewHeight); - - preScaledWidthOut[0] = viewWidth; - final int bitmapWidth, bitmapHeight; - final float scale; - if (viewWidth > previewSize) { - scale = ((float) previewSize) / viewWidth; - bitmapWidth = previewSize; - bitmapHeight = (int) (viewHeight * scale); - } else { - scale = 1; - bitmapWidth = viewWidth; - bitmapHeight = viewHeight; - } - - return BitmapRenderer.createSoftwareBitmap(bitmapWidth, bitmapHeight, c -> { - c.scale(scale, scale); - v.draw(c); - }); - } }