Merge "Render RemoteViews in LauncherAppWidgetHostView" into sc-dev

This commit is contained in:
Steven Ng 2021-04-21 16:40:05 +00:00 committed by Android (Google) Code Review
commit 6f944f3624
4 changed files with 71 additions and 85 deletions

View File

@ -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();
}

View File

@ -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) {

View File

@ -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();

View File

@ -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);
});
}
}