summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2017-01-25 18:23:36 -0800
committerSunny Goyal <sunnygoyal@google.com>2017-01-27 15:09:10 -0800
commitdec3a908bfa395095e80e4a532cff98612b624de (patch)
tree77ea2c951253ef5ca2d63655dcd7071f328b41ed
parent5cfd1158ec1e4a19689217e9fbddd0fd795b2611 (diff)
downloadandroid_packages_apps_Trebuchet-dec3a908bfa395095e80e4a532cff98612b624de.tar.gz
android_packages_apps_Trebuchet-dec3a908bfa395095e80e4a532cff98612b624de.tar.bz2
android_packages_apps_Trebuchet-dec3a908bfa395095e80e4a532cff98612b624de.zip
Updating the preview generation logic so that it aligns better with
the drag source image > Using common code for pending item drag (WidgetContainerView and PinItemDragListener) > Adding a shortcut-circuit in Workspace when a pendingItem can create a shortcut directly. Previously the multi-window drop was routing through onActivityResult which was causing some state information to be lost. Bug: 33584624 Change-Id: I0259870032185713caa9bff27092dbae6ce91199
-rw-r--r--src/com/android/launcher3/ButtonDropTarget.java2
-rw-r--r--src/com/android/launcher3/Launcher.java21
-rw-r--r--src/com/android/launcher3/Workspace.java56
-rw-r--r--src/com/android/launcher3/compat/LauncherAppsCompat.java38
-rw-r--r--src/com/android/launcher3/compat/PinItemRequestCompat.java4
-rw-r--r--src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java17
-rw-r--r--src/com/android/launcher3/dragndrop/AddItemActivity.java10
-rw-r--r--src/com/android/launcher3/dragndrop/DragController.java26
-rw-r--r--src/com/android/launcher3/dragndrop/DragLayer.java12
-rw-r--r--src/com/android/launcher3/dragndrop/DragView.java4
-rw-r--r--src/com/android/launcher3/dragndrop/PinItemDragListener.java79
-rw-r--r--src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java12
-rw-r--r--src/com/android/launcher3/widget/PendingItemDragHelper.java191
-rw-r--r--src/com/android/launcher3/widget/PendingItemPreviewProvider.java76
-rw-r--r--src/com/android/launcher3/widget/WidgetsContainerView.java72
15 files changed, 335 insertions, 285 deletions
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 85b08d116..8d69fe374 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -229,7 +229,7 @@ public abstract class ButtonDropTarget extends TextView
}
};
dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
- mLauncher.getDragController().isExternalDrag() ? 1 : DRAG_VIEW_DROP_DURATION,
+ DRAG_VIEW_DROP_DURATION,
new DecelerateInterpolator(2),
new LinearInterpolator(), onAnimationEndRunnable,
DragLayer.ANIMATION_END_DISAPPEAR, null);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index a1aafb821..11db9a0eb 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -101,7 +101,6 @@ import com.android.launcher3.dragndrop.PinItemDragListener;
import com.android.launcher3.dynamicui.ExtractedColors;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.keyboard.CustomActionsPopup;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.logging.FileLog;
@@ -111,7 +110,6 @@ import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.shortcuts.DeepShortcutManager;
-import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -836,7 +834,7 @@ public class Launcher extends BaseActivity
}
@Override
- public void onActivityResult(
+ protected void onActivityResult(
final int requestCode, final int resultCode, final Intent data) {
handleActivityResult(requestCode, resultCode, data);
if (mLauncherCallbacks != null) {
@@ -1459,21 +1457,8 @@ public class Launcher extends BaseActivity
ShortcutInfo info = null;
if (Utilities.isAtLeastO()) {
- PinItemRequestCompat request = PinItemRequestCompat.getPinItemRequest(data);
- // request.accept will initiate a shortcutChanged callback. To ensure that the model is
- // consistent, that callback must be processed by the model, after the ShortcutInfo is
- // added to the model. This is guaranteed here the callback comes on the UI thread, and
- // we will add the shortcut on the UI thread as well.
- if (request != null &&
- request.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT &&
- request.isValid() && request.accept()) {
- ShortcutInfoCompat compat = new ShortcutInfoCompat(request.getShortcutInfo());
- info = new ShortcutInfo(compat, this);
- // Apply the unbadged icon and fetch the actual icon asynchronously.
- info.iconBitmap = LauncherIcons
- .createShortcutIcon(compat, this, false /* badged */);
- getModel().updateAndBindShortcutInfo(info, compat);
- }
+ info = LauncherAppsCompat.createShortcutInfoFromPinItemRequest(
+ this, PinItemRequestCompat.getPinItemRequest(data));
}
if (info == null) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index cd1d8d9a2..72dff6686 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2523,7 +2523,7 @@ public class Workspace extends PagedView
if (d.dragSource != this) {
final int[] touchXY = new int[] { (int) mDragViewVisualCenter[0],
(int) mDragViewVisualCenter[1] };
- onDropExternal(touchXY, d.dragInfo, dropTargetLayout, d);
+ onDropExternal(touchXY, dropTargetLayout, d);
} else if (mDragInfo != null) {
final View cell = mDragInfo.cell;
boolean droppedOnOriginalCellDuringTransition = false;
@@ -3226,8 +3226,7 @@ public class Workspace extends PagedView
* NOTE: This can also be called when we are outside of a drag event, when we want
* to add an item to one of the workspace screens.
*/
- private void onDropExternal(final int[] touchXY, final ItemInfo dragInfo,
- final CellLayout cellLayout, DragObject d) {
+ private void onDropExternal(final int[] touchXY, final CellLayout cellLayout, DragObject d) {
final Runnable exitSpringLoadedRunnable = new Runnable() {
@Override
public void run() {
@@ -3236,7 +3235,15 @@ public class Workspace extends PagedView
}
};
- ItemInfo info = dragInfo;
+ if (d.dragInfo instanceof PendingAddShortcutInfo) {
+ ShortcutInfo si = ((PendingAddShortcutInfo) d.dragInfo)
+ .activityInfo.createShortcutInfo();
+ if (si != null) {
+ d.dragInfo = si;
+ }
+ }
+
+ ItemInfo info = d.dragInfo;
int spanX = info.spanX;
int spanY = info.spanY;
if (mDragInfo != null) {
@@ -3255,7 +3262,7 @@ public class Workspace extends PagedView
}
if (info instanceof PendingAddItemInfo) {
- final PendingAddItemInfo pendingInfo = (PendingAddItemInfo) dragInfo;
+ final PendingAddItemInfo pendingInfo = (PendingAddItemInfo) info;
boolean findNearestVacantCell = true;
if (pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
@@ -3318,7 +3325,7 @@ public class Workspace extends PagedView
int animationStyle = ANIMATE_INTO_POSITION_AND_DISAPPEAR;
if (isWidget && ((PendingAddWidgetInfo) pendingInfo).info != null &&
- ((PendingAddWidgetInfo) pendingInfo).info.configure != null) {
+ ((PendingAddWidgetInfo) pendingInfo).getHandler().needsConfigure()) {
animationStyle = ANIMATE_INTO_POSITION_AND_REMAIN;
}
animateWidgetDrop(info, cellLayout, d.dragView, onAnimationCompleteRunnable,
@@ -3433,21 +3440,32 @@ public class Workspace extends PagedView
mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(layout, loc, true);
resetTransitionTransform(layout);
- float dragViewScaleX = 1f;
- float dragViewScaleY = 1f;
if (scale) {
- dragViewScaleX = (1.0f * r.width()) / dragView.getMeasuredWidth();
- dragViewScaleY = (1.0f * r.height()) / dragView.getMeasuredHeight();
+ float dragViewScaleX = (1.0f * r.width()) / dragView.getMeasuredWidth();
+ float dragViewScaleY = (1.0f * r.height()) / dragView.getMeasuredHeight();
+
+ // The animation will scale the dragView about its center, so we need to center about
+ // the final location.
+ loc[0] -= (dragView.getMeasuredWidth() - cellLayoutScale * r.width()) / 2
+ - Math.ceil(layout.getUnusedHorizontalSpace() / 2f);
+ loc[1] -= (dragView.getMeasuredHeight() - cellLayoutScale * r.height()) / 2;
+ scaleXY[0] = dragViewScaleX * cellLayoutScale;
+ scaleXY[1] = dragViewScaleY * cellLayoutScale;
+ } else {
+ // Since we are not cross-fading the dragView, align the drag view to the
+ // final cell position.
+ float dragScale = dragView.getInitialScale() * cellLayoutScale;
+ loc[0] += (dragScale - 1) * dragView.getWidth() / 2;
+ loc[1] += (dragScale - 1) * dragView.getHeight() / 2;
+ scaleXY[0] = scaleXY[1] = dragScale;
+
+ // If a dragRegion was provided, offset the final position accordingly.
+ Rect dragRegion = dragView.getDragRegion();
+ if (dragRegion != null) {
+ loc[0] += cellLayoutScale * dragRegion.left;
+ loc[1] += cellLayoutScale * dragRegion.top;
+ }
}
-
- // The animation will scale the dragView about its center, so we need to center about
- // the final location.
- loc[0] -= (dragView.getMeasuredWidth() - cellLayoutScale * r.width()) / 2
- - Math.ceil(layout.getUnusedHorizontalSpace() / 2f);
- loc[1] -= (dragView.getMeasuredHeight() - cellLayoutScale * r.height()) / 2;
-
- scaleXY[0] = dragViewScaleX * cellLayoutScale;
- scaleXY[1] = dragViewScaleY * cellLayoutScale;
}
public void animateWidgetDrop(ItemInfo info, CellLayout cellLayout, final DragView dragView,
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 281069af0..b9142ed16 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -23,8 +23,12 @@ import android.content.pm.LauncherActivityInfo;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.UserHandle;
+import android.support.annotation.Nullable;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
+import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import java.util.List;
@@ -75,4 +79,38 @@ public abstract class LauncherAppsCompat {
public abstract boolean isActivityEnabledForProfile(ComponentName component,
UserHandle user);
public abstract List<ShortcutConfigActivityInfo> getCustomShortcutActivityList();
+
+ /**
+ * request.accept() will initiate the following flow:
+ * -> go-to-system-process for actual processing (a)
+ * -> callback-to-launcher on UI thread (b)
+ * -> post callback on the worker thread (c)
+ * -> Update model and unpin (in system) any shortcut not in out model. (d)
+ *
+ * Note that (b) will take at-least one frame as it involves posting callback from binder
+ * thread to UI thread.
+ * If (d) happens before we add this shortcut to our model, we will end up unpinning
+ * the shortcut in the system.
+ * Here its the caller's responsibility to add the newly created ShortcutInfo immediately
+ * to the model (which may involves a single post-to-worker-thread). That will guarantee
+ * that (d) happens after model is updated.
+ */
+ @Nullable
+ public static ShortcutInfo createShortcutInfoFromPinItemRequest(
+ Context context, PinItemRequestCompat request) {
+ if (request != null &&
+ request.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT &&
+ request.isValid() && request.accept()) {
+ ShortcutInfoCompat compat = new ShortcutInfoCompat(request.getShortcutInfo());
+ ShortcutInfo info = new ShortcutInfo(compat, context);
+ // Apply the unbadged icon and fetch the actual icon asynchronously.
+ info.iconBitmap = LauncherIcons
+ .createShortcutIcon(compat, context, false /* badged */);
+ LauncherAppState.getInstance(context).getModel()
+ .updateAndBindShortcutInfo(info, compat);
+ return info;
+ } else {
+ return null;
+ }
+ }
}
diff --git a/src/com/android/launcher3/compat/PinItemRequestCompat.java b/src/com/android/launcher3/compat/PinItemRequestCompat.java
index 481310a15..f76b77655 100644
--- a/src/com/android/launcher3/compat/PinItemRequestCompat.java
+++ b/src/com/android/launcher3/compat/PinItemRequestCompat.java
@@ -94,10 +94,6 @@ public class PinItemRequestCompat implements Parcelable {
parcel.writeParcelable(mObject, i);
}
- public Intent toIntent() {
- return new Intent().putExtra(EXTRA_PIN_ITEM_REQUEST, mObject);
- }
-
public static final Parcelable.Creator<PinItemRequestCompat> CREATOR =
new Parcelable.Creator<PinItemRequestCompat>() {
public PinItemRequestCompat createFromParcel(Parcel source) {
diff --git a/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java b/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
index 1cfbd2061..ebe95d680 100644
--- a/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
+++ b/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
@@ -26,18 +26,15 @@ import android.content.pm.ActivityInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
-import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.util.Log;
import android.widget.Toast;
import com.android.launcher3.IconCache;
-import com.android.launcher3.Launcher;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.ShortcutInfo;
import java.lang.reflect.Method;
@@ -68,7 +65,15 @@ public abstract class ShortcutConfigActivityInfo {
public abstract Drawable getFullResIcon(IconCache cache);
- public boolean startConfigActivity(Launcher activity, int requestCode) {
+ /**
+ * Return a shortcut info, if it can be created directly on drop, without requiring any
+ * {@link #startConfigActivity(Activity, int)}.
+ */
+ public ShortcutInfo createShortcutInfo() {
+ return null;
+ }
+
+ public boolean startConfigActivity(Activity activity, int requestCode) {
Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT)
.setComponent(getComponent());
try {
@@ -137,7 +142,7 @@ public abstract class ShortcutConfigActivityInfo {
}
@Override
- public boolean startConfigActivity(Launcher activity, int requestCode) {
+ public boolean startConfigActivity(Activity activity, int requestCode) {
if (getUser().equals(Process.myUserHandle())) {
return super.startConfigActivity(activity, requestCode);
}
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 423fdabfc..b80baf32f 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -117,11 +117,19 @@ 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();
+
+ // If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and
+ // we abort the drag.
+ if (img.getBitmap() == null) {
+ return false;
+ }
+
Rect bounds = img.getBitmapBounds();
bounds.offset(img.getLeft() - (int) mLastTouchPos.x, img.getTop() - (int) mLastTouchPos.y);
// Start home and pass the draw request params
- PinItemDragListener listener = new PinItemDragListener(mRequest, bounds);
+ PinItemDragListener listener = new PinItemDragListener(mRequest, bounds,
+ img.getBitmap().getWidth(), img.getWidth());
Intent homeIntent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME)
.setPackage(getPackageName())
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index 5a5e7d0ab..e31c8ffdd 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -121,28 +121,6 @@ public class DragController implements DragDriver.EventListener, TouchController
/**
* Starts a drag.
*
- * @param v The view that is being dragged
- * @param bmp The bitmap that represents the view being dragged
- * @param source An object representing where the drag originated
- * @param dragInfo The data associated with the object that is being dragged
- * @param viewImageBounds the position of the image inside the view
- */
- public void startDrag(View v, Bitmap bmp, DragSource source, ItemInfo dragInfo,
- Rect viewImageBounds, float initialDragViewScale, DragOptions options) {
- int[] loc = mCoordinatesTemp;
- mLauncher.getDragLayer().getLocationInDragLayer(v, loc);
- int dragLayerX = loc[0] + viewImageBounds.left
- + (int) ((initialDragViewScale * bmp.getWidth() - bmp.getWidth()) / 2);
- int dragLayerY = loc[1] + viewImageBounds.top
- + (int) ((initialDragViewScale * bmp.getHeight() - bmp.getHeight()) / 2);
-
- startDrag(bmp, dragLayerX, dragLayerY, source, dragInfo, null,
- null, initialDragViewScale, options);
- }
-
- /**
- * Starts a drag.
- *
* @param b The bitmap to display as the drag image. It will be re-scaled to the
* enlarged size.
* @param dragLayerX The x position in the DragLayer of the left-top of the bitmap.
@@ -259,10 +237,6 @@ public class DragController implements DragDriver.EventListener, TouchController
return mDragDriver != null || (mOptions != null && mOptions.isAccessibleDrag);
}
- public boolean isExternalDrag() {
- return (mOptions != null && mOptions.systemDndStartPoint != null);
- }
-
/**
* Stop dragging without dropping.
*/
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index de416e3bc..1be40f7e2 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -673,15 +673,11 @@ public class DragLayer extends InsettableFrameLayout {
// If duration < 0, this is a cue to compute the duration based on the distance
if (duration < 0) {
- if (mDragController != null && mDragController.isExternalDrag()) {
- duration = 1;
- } else {
- duration = res.getInteger(R.integer.config_dropAnimMaxDuration);
- if (dist < maxDist) {
- duration *= mCubicEaseOutInterpolator.getInterpolation(dist / maxDist);
- }
- duration = Math.max(duration, res.getInteger(R.integer.config_dropAnimMinDuration));
+ duration = res.getInteger(R.integer.config_dropAnimMaxDuration);
+ if (dist < maxDist) {
+ duration *= mCubicEaseOutInterpolator.getInterpolation(dist / maxDist);
}
+ duration = Math.max(duration, res.getInteger(R.integer.config_dropAnimMinDuration));
}
// Fall back to cubic ease out interpolator for the animation if none is specified
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index c94623536..3a98ae71b 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -392,4 +392,8 @@ public class DragView extends View {
public int getBlurSizeOutline() {
return mBlurSizeOutline;
}
+
+ public float getInitialScale() {
+ return mInitialScale;
+ }
}
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index 9770d40e9..6e5318f2a 100644
--- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
@@ -17,9 +17,6 @@
package com.android.launcher3.dragndrop;
import android.content.ClipDescription;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
@@ -32,30 +29,25 @@ import android.view.DragEvent;
import android.view.View;
import com.android.launcher3.DeleteDropTarget;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.R;
import com.android.launcher3.compat.PinItemRequestCompat;
import com.android.launcher3.folder.Folder;
-import com.android.launcher3.graphics.LauncherIcons;
-import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
-import com.android.launcher3.widget.PendingItemPreviewProvider;
+import com.android.launcher3.widget.PendingItemDragHelper;
import com.android.launcher3.widget.WidgetAddFlowHandler;
-import com.android.launcher3.widget.WidgetHostViewLoader;
import java.util.UUID;
/**
- * {@link DragSource} for handling drop from from a different window. This object is initialized
+ * {@link DragSource} for handling drop from a different window. This object is initialized
* in the source window and is passed on to the Launcher activity as an Intent extra.
*/
public class PinItemDragListener
@@ -71,6 +63,9 @@ public class PinItemDragListener
// Position of preview relative to the touch location
private final Rect mPreviewRect;
+ private final int mPreviewBitmapWidth;
+ private final int mPreviewViewWidth;
+
// Randomly generated id used to verify the drag event.
private final String mId;
@@ -78,15 +73,20 @@ public class PinItemDragListener
private DragController mDragController;
private long mDragStartTime;
- public PinItemDragListener(PinItemRequestCompat request, Rect previewRect) {
+ public PinItemDragListener(PinItemRequestCompat request, Rect previewRect,
+ int previewBitmapWidth, int previewViewWidth) {
mRequest = request;
mPreviewRect = previewRect;
+ mPreviewBitmapWidth = previewBitmapWidth;
+ mPreviewViewWidth = previewViewWidth;
mId = UUID.randomUUID().toString();
}
private PinItemDragListener(Parcel parcel) {
mRequest = PinItemRequestCompat.CREATOR.createFromParcel(parcel);
mPreviewRect = Rect.CREATOR.createFromParcel(parcel);
+ mPreviewBitmapWidth = parcel.readInt();
+ mPreviewViewWidth = parcel.readInt();
mId = parcel.readString();
}
@@ -103,6 +103,8 @@ public class PinItemDragListener
public void writeToParcel(Parcel parcel, int i) {
mRequest.writeToParcel(parcel, i);
mPreviewRect.writeToParcel(parcel, i);
+ parcel.writeInt(mPreviewBitmapWidth);
+ parcel.writeInt(mPreviewViewWidth);
parcel.writeString(mId);
}
@@ -139,26 +141,9 @@ public class PinItemDragListener
}
final PendingAddItemInfo item;
- final Bitmap preview;
- final View view = new View(mLauncher);
-
- Point dragShift = new Point(mPreviewRect.left, mPreviewRect.top);
if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT) {
item = new PendingAddShortcutInfo(
new PinShortcutRequestActivityInfo(mRequest, mLauncher));
-
- ShortcutInfoCompat compat = new ShortcutInfoCompat(mRequest.getShortcutInfo());
- Bitmap icon = LauncherIcons.createShortcutIcon(compat, mLauncher, false /* badged */);
-
- // Create a preview same as the workspace cell size and draw the icon at the
- // appropriate position.
- int[] size = mLauncher.getWorkspace().estimateItemSize(item, true, false);
- preview = Bitmap.createBitmap(size[0], size[1], Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(preview);
- DeviceProfile dp = mLauncher.getDeviceProfile();
- c.drawBitmap(icon, (size[0] - icon.getWidth()) / 2,
- (size[1] - icon.getHeight() - dp.iconTextSizePx - dp.iconDrawablePaddingPx) / 2,
- new Paint(Paint.FILTER_BITMAP_FLAG));
} else {
// mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_APPWIDGET
LauncherAppWidgetProviderInfo providerInfo =
@@ -166,46 +151,28 @@ public class PinItemDragListener
mLauncher, mRequest.getAppWidgetProviderInfo(mLauncher));
final PinWidgetFlowHandler flowHandler =
new PinWidgetFlowHandler(providerInfo, mRequest);
- PendingAddWidgetInfo info = new PendingAddWidgetInfo(providerInfo) {
+ item = new PendingAddWidgetInfo(providerInfo) {
@Override
public WidgetAddFlowHandler getHandler() {
return flowHandler;
}
};
- int[] size = mLauncher.getWorkspace().estimateItemSize(info, true, false);
-
- float minScale = 1.25f;
- int maxWidth = Math.min((int) (mPreviewRect.width() * minScale), size[0]);
- int[] previewSizeBeforeScale = new int[1];
- preview = LauncherAppState.getInstance(mLauncher).getWidgetCache()
- .generateWidgetPreview(mLauncher, info.info, maxWidth, null,
- previewSizeBeforeScale);
-
- dragShift.offset(
- (mPreviewRect.width() - preview.getWidth()) / 2,
- (mPreviewRect.height() - preview.getHeight()) / 2);
- item = info;
-
- view.setTag(info);
- mDragController.addDragListener(new WidgetHostViewLoader(mLauncher, view));
}
-
- PendingItemPreviewProvider previewProvider =
- new PendingItemPreviewProvider(view, item, preview);
-
- // Since we are not going through the workspace for starting the drag, set drag related
- // information on the workspace before starting the drag.
- mLauncher.getWorkspace().prepareDragWithProvider(previewProvider);
+ View view = new View(mLauncher);
+ view.setTag(item);
Point downPos = new Point((int) event.getX(), (int) event.getY());
DragOptions options = new DragOptions();
options.systemDndStartPoint = downPos;
options.preDragCondition = this;
- int x = downPos.x + dragShift.x;
- int y = downPos.y + dragShift.y;
- mDragController.startDrag(
- preview, x, y, this, item, null, null, 1f, options);
+ // We use drag event position as the screenPos for the preview image. Since mPreviewRect
+ // already includes the view position relative to the drag event on the source window,
+ // and the absolute position (position relative to the screen) of drag event is same
+ // across windows, using drag position here give a good estimate for relative position
+ // to source window.
+ new PendingItemDragHelper(view).startDrag(new Rect(mPreviewRect),
+ mPreviewBitmapWidth, mPreviewViewWidth, downPos, this, options);
mDragStartTime = SystemClock.uptimeMillis();
return true;
}
diff --git a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
index 2121b438a..6a8c19f4b 100644
--- a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
+++ b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
@@ -26,8 +26,8 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import com.android.launcher3.IconCache;
-import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PinItemRequestCompat;
import com.android.launcher3.compat.ShortcutConfigActivityInfo;
@@ -66,9 +66,13 @@ class PinShortcutRequestActivityInfo extends ShortcutConfigActivityInfo {
}
@Override
- public boolean startConfigActivity(Launcher activity, int requestCode) {
- activity.onActivityResult(requestCode, Activity.RESULT_OK, mRequest.toIntent());
- return true;
+ public com.android.launcher3.ShortcutInfo createShortcutInfo() {
+ return LauncherAppsCompat.createShortcutInfoFromPinItemRequest(mContext, mRequest);
+ }
+
+ @Override
+ public boolean startConfigActivity(Activity activity, int requestCode) {
+ return false;
}
@Override
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
new file mode 100644
index 000000000..a4698c292
--- /dev/null
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.widget;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DragSource;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.PendingAddItemInfo;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.graphics.DragPreviewProvider;
+import com.android.launcher3.graphics.HolographicOutlineHelper;
+import com.android.launcher3.graphics.LauncherIcons;
+
+/**
+ * Extension of {@link DragPreviewProvider} with logic specific to pending widgets/shortcuts
+ * dragged from the widget tray.
+ */
+public class PendingItemDragHelper extends DragPreviewProvider {
+
+ private static final float MAX_WIDGET_SCALE = 1.25f;
+
+ private final PendingAddItemInfo mAddInfo;
+
+ private Bitmap mPreviewBitmap;
+
+ public PendingItemDragHelper(View view) {
+ super(view);
+ mAddInfo = (PendingAddItemInfo) view.getTag();
+ }
+
+ /**
+ * Starts the drag for the pending item associated with the view.
+ *
+ * @param previewBounds The bounds where the image was displayed,
+ * {@link WidgetImageView#getBitmapBounds()}
+ * @param previewBitmapWidth The actual width of the bitmap displayed in the view.
+ * @param previewViewWidth The width of {@link WidgetImageView} displaying the preview
+ * @param screenPos Position of {@link WidgetImageView} on the screen
+ */
+ public void startDrag(Rect previewBounds, int previewBitmapWidth, int previewViewWidth,
+ Point screenPos, DragSource source, DragOptions options) {
+ final Launcher launcher = Launcher.getLauncher(mView.getContext());
+ LauncherAppState app = LauncherAppState.getInstance(launcher);
+
+ final Bitmap preview;
+ final float scale;
+ final Point dragOffset;
+ final Rect dragRegion;
+
+
+ if (mAddInfo instanceof PendingAddWidgetInfo) {
+ PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) mAddInfo;
+ int[] size = launcher.getWorkspace().estimateItemSize(createWidgetInfo, true, false);
+
+ int maxWidth = Math.min((int) (previewBitmapWidth * MAX_WIDGET_SCALE), size[0]);
+
+ int[] previewSizeBeforeScale = new int[1];
+ preview = app.getWidgetCache() .generateWidgetPreview(
+ launcher, createWidgetInfo.info, maxWidth, null, previewSizeBeforeScale);
+
+ if (previewSizeBeforeScale[0] < previewBitmapWidth) {
+ // The icon has extra padding around it.
+ int padding = (previewBitmapWidth - previewSizeBeforeScale[0]) / 2;
+ if (previewBitmapWidth > previewViewWidth) {
+ padding = padding * previewViewWidth / previewBitmapWidth;
+ }
+
+ previewBounds.left += padding;
+ previewBounds.right -= padding;
+ }
+ scale = previewBounds.width() / (float) preview.getWidth();
+ launcher.getDragController().addDragListener(new WidgetHostViewLoader(launcher, mView));
+
+ dragOffset = null;
+ dragRegion = null;
+ } else {
+ PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) mAddInfo;
+ Drawable icon = createShortcutInfo.activityInfo.getFullResIcon(app.getIconCache());
+ preview = LauncherIcons.createScaledBitmapWithoutShadow(icon, launcher);
+ mAddInfo.spanX = mAddInfo.spanY = 1;
+ scale = ((float) launcher.getDeviceProfile().iconSizePx) / preview.getWidth();
+
+ dragOffset = new Point(previewPadding / 2, previewPadding / 2);
+
+ // Create a preview same as the workspace cell size and draw the icon at the
+ // appropriate position.
+ int[] size = launcher.getWorkspace().estimateItemSize(mAddInfo, false, true);
+ DeviceProfile dp = launcher.getDeviceProfile();
+ int iconSize = dp.iconSizePx;
+
+ dragRegion = new Rect();
+ dragRegion.left = (size[0] - iconSize) / 2;
+ dragRegion.right = dragRegion.left + iconSize;
+ dragRegion.top = (size[1] - iconSize - dp.iconTextSizePx - dp.iconDrawablePaddingPx) / 2;
+ dragRegion.bottom = dragRegion.top + iconSize;
+ }
+
+ // Since we are not going through the workspace for starting the drag, set drag related
+ // information on the workspace before starting the drag.
+ launcher.getWorkspace().prepareDragWithProvider(this);
+
+ int dragLayerX = screenPos.x + previewBounds.left
+ + (int) ((scale * preview.getWidth() - preview.getWidth()) / 2);
+ int dragLayerY = screenPos.y + previewBounds.top
+ + (int) ((scale * preview.getHeight() - preview.getHeight()) / 2);
+
+ mPreviewBitmap = preview;
+ // Start the drag
+ launcher.getDragController().startDrag(preview, dragLayerX, dragLayerY, source, mAddInfo,
+ dragOffset, dragRegion, scale, options);
+ }
+
+
+ @Override
+ public Bitmap createDragOutline(Canvas canvas) {
+ if (mAddInfo instanceof PendingAddShortcutInfo) {
+ int width = mPreviewBitmap.getWidth();
+ int height = mPreviewBitmap.getHeight();
+ Bitmap b = Bitmap.createBitmap(width + blurSizeOutline, height + blurSizeOutline,
+ Bitmap.Config.ALPHA_8);
+ canvas.setBitmap(b);
+
+ Launcher launcher = Launcher.getLauncher(mView.getContext());
+ int size = launcher.getDeviceProfile().iconSizePx;
+
+ Rect src = new Rect(0, 0, mPreviewBitmap.getWidth(), mPreviewBitmap.getHeight());
+ Rect dst = new Rect(0, 0, size, size);
+ dst.offset(blurSizeOutline / 2, blurSizeOutline / 2);
+ canvas.drawBitmap(mPreviewBitmap, src, dst, new Paint(Paint.FILTER_BITMAP_FLAG));
+
+ HolographicOutlineHelper.getInstance(mView.getContext())
+ .applyExpensiveOutlineWithBlur(b, canvas);
+
+ canvas.setBitmap(null);
+ return b;
+ }
+
+ Workspace workspace = Launcher.getLauncher(mView.getContext()).getWorkspace();
+ int[] size = workspace.estimateItemSize(mAddInfo, false, false);
+
+ int w = size[0];
+ int h = size[1];
+ final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ALPHA_8);
+ canvas.setBitmap(b);
+
+ Rect src = new Rect(0, 0, mPreviewBitmap.getWidth(), mPreviewBitmap.getHeight());
+ float scaleFactor = Math.min((w - blurSizeOutline) / (float) mPreviewBitmap.getWidth(),
+ (h - blurSizeOutline) / (float) mPreviewBitmap.getHeight());
+ int scaledWidth = (int) (scaleFactor * mPreviewBitmap.getWidth());
+ int scaledHeight = (int) (scaleFactor * mPreviewBitmap.getHeight());
+ Rect dst = new Rect(0, 0, scaledWidth, scaledHeight);
+
+ // center the image
+ dst.offset((w - scaledWidth) / 2, (h - scaledHeight) / 2);
+
+ canvas.drawBitmap(mPreviewBitmap, src, dst, null);
+
+ // Don't clip alpha values for the drag outline if we're using the default widget preview
+ boolean clipAlpha = !(mAddInfo instanceof PendingAddWidgetInfo &&
+ (((PendingAddWidgetInfo) mAddInfo).previewImage == 0));
+ HolographicOutlineHelper.getInstance(mView.getContext())
+ .applyExpensiveOutlineWithBlur(b, canvas, clipAlpha);
+ canvas.setBitmap(null);
+
+ return b;
+ }
+}
diff --git a/src/com/android/launcher3/widget/PendingItemPreviewProvider.java b/src/com/android/launcher3/widget/PendingItemPreviewProvider.java
deleted file mode 100644
index 3a49a6cdd..000000000
--- a/src/com/android/launcher3/widget/PendingItemPreviewProvider.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.widget;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.view.View;
-
-import com.android.launcher3.graphics.HolographicOutlineHelper;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.PendingAddItemInfo;
-import com.android.launcher3.Workspace;
-import com.android.launcher3.graphics.DragPreviewProvider;
-
-/**
- * Extension of {@link DragPreviewProvider} with logic specific to pending widgets/shortcuts
- * dragged from the widget tray.
- */
-public class PendingItemPreviewProvider extends DragPreviewProvider {
-
- private final PendingAddItemInfo mAddInfo;
- private final Bitmap mPreviewBitmap;
-
- public PendingItemPreviewProvider(View view, PendingAddItemInfo addInfo, Bitmap preview) {
- super(view);
- mAddInfo = addInfo;
- mPreviewBitmap = preview;
- }
-
- @Override
- public Bitmap createDragOutline(Canvas canvas) {
- Workspace workspace = Launcher.getLauncher(mView.getContext()).getWorkspace();
- int[] size = workspace.estimateItemSize(mAddInfo, false, false);
-
- int w = size[0];
- int h = size[1];
- final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ALPHA_8);
- canvas.setBitmap(b);
-
- Rect src = new Rect(0, 0, mPreviewBitmap.getWidth(), mPreviewBitmap.getHeight());
- float scaleFactor = Math.min((w - blurSizeOutline) / (float) mPreviewBitmap.getWidth(),
- (h - blurSizeOutline) / (float) mPreviewBitmap.getHeight());
- int scaledWidth = (int) (scaleFactor * mPreviewBitmap.getWidth());
- int scaledHeight = (int) (scaleFactor * mPreviewBitmap.getHeight());
- Rect dst = new Rect(0, 0, scaledWidth, scaledHeight);
-
- // center the image
- dst.offset((w - scaledWidth) / 2, (h - scaledHeight) / 2);
-
- canvas.drawBitmap(mPreviewBitmap, src, dst, null);
-
- // Don't clip alpha values for the drag outline if we're using the default widget preview
- boolean clipAlpha = !(mAddInfo instanceof PendingAddWidgetInfo &&
- (((PendingAddWidgetInfo) mAddInfo).previewImage == 0));
- HolographicOutlineHelper.getInstance(mView.getContext())
- .applyExpensiveOutlineWithBlur(b, canvas, clipAlpha);
- canvas.setBitmap(null);
-
- return b;
- }
-}
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index d1421e05a..b2321a7d3 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -17,9 +17,7 @@
package com.android.launcher3.widget;
import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
+import android.graphics.Point;
import android.support.v7.widget.LinearLayoutManager;
import android.util.AttributeSet;
import android.util.Log;
@@ -35,17 +33,13 @@ import com.android.launcher3.IconCache;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.WidgetPreviewLoader;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.folder.Folder;
-import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.MultiHashMap;
@@ -71,9 +65,6 @@ public class WidgetsContainerView extends BaseContainerView
/* Touch handling related member variables. */
private Toast mWidgetInstructionToast;
- /* Rendering related. */
- private WidgetPreviewLoader mWidgetPreviewLoader;
-
public WidgetsContainerView(Context context) {
this(context, null);
}
@@ -174,7 +165,6 @@ public class WidgetsContainerView extends BaseContainerView
private boolean beginDraggingWidget(WidgetCell v) {
// Get the widget preview as the drag representation
WidgetImageView image = (WidgetImageView) v.findViewById(R.id.widget_preview);
- PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag();
// If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and
// we abort the drag.
@@ -182,55 +172,12 @@ public class WidgetsContainerView extends BaseContainerView
return false;
}
- // Compose the drag image
- Bitmap preview;
- final float scale;
- final Rect bounds = image.getBitmapBounds();
-
- if (createItemInfo instanceof PendingAddWidgetInfo) {
- // This can happen in some weird cases involving multi-touch. We can't start dragging
- // the widget if this is null, so we break out.
-
- PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) createItemInfo;
- int[] size = mLauncher.getWorkspace().estimateItemSize(createWidgetInfo, true, false);
-
- Bitmap icon = image.getBitmap();
- float minScale = 1.25f;
- int maxWidth = Math.min((int) (icon.getWidth() * minScale), size[0]);
-
- int[] previewSizeBeforeScale = new int[1];
- preview = getWidgetPreviewLoader().generateWidgetPreview(mLauncher,
- createWidgetInfo.info, maxWidth, null, previewSizeBeforeScale);
-
- if (previewSizeBeforeScale[0] < icon.getWidth()) {
- // The icon has extra padding around it.
- int padding = (icon.getWidth() - previewSizeBeforeScale[0]) / 2;
- if (icon.getWidth() > image.getWidth()) {
- padding = padding * image.getWidth() / icon.getWidth();
- }
-
- bounds.left += padding;
- bounds.right -= padding;
- }
- scale = bounds.width() / (float) preview.getWidth();
+ int[] loc = new int[2];
+ mLauncher.getDragLayer().getLocationInDragLayer(image, loc);
- mLauncher.getDragController().addDragListener(new WidgetHostViewLoader(mLauncher, v));
- } else {
- PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) v.getTag();
- Drawable icon = createShortcutInfo.activityInfo.getFullResIcon(mIconCache);
- preview = LauncherIcons.createIconBitmap(icon, mLauncher);
- createItemInfo.spanX = createItemInfo.spanY = 1;
- scale = ((float) mLauncher.getDeviceProfile().iconSizePx) / preview.getWidth();
- }
-
- // Since we are not going through the workspace for starting the drag, set drag related
- // information on the workspace before starting the drag.
- mLauncher.getWorkspace().prepareDragWithProvider(
- new PendingItemPreviewProvider(v, createItemInfo, preview));
-
- // Start the drag
- mDragController.startDrag(image, preview, this, createItemInfo,
- bounds, scale, new DragOptions());
+ new PendingItemDragHelper(v).startDrag(
+ image.getBitmapBounds(), image.getBitmap().getWidth(), image.getWidth(),
+ new Point(loc[0], loc[1]), this, new DragOptions());
return true;
}
@@ -294,13 +241,6 @@ public class WidgetsContainerView extends BaseContainerView
return mAdapter.getItemCount() == 0;
}
- private WidgetPreviewLoader getWidgetPreviewLoader() {
- if (mWidgetPreviewLoader == null) {
- mWidgetPreviewLoader = LauncherAppState.getInstance(getContext()).getWidgetCache();
- }
- return mWidgetPreviewLoader;
- }
-
@Override
public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
targetParent.containerType = ContainerType.WIDGETS;