summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2016-09-12 14:36:30 -0700
committerSunny Goyal <sunnygoyal@google.com>2016-09-12 14:37:46 -0700
commitd139b0aa7d03f676dc7869dc5b39fd9f24ff0a1d (patch)
tree95ceabb5b61bac8bb4f7cd4588047ad90ca3704c
parent1e35fbbac778a973fefd2f6e0061d4ece8aeff2b (diff)
downloadandroid_packages_apps_Trebuchet-d139b0aa7d03f676dc7869dc5b39fd9f24ff0a1d.tar.gz
android_packages_apps_Trebuchet-d139b0aa7d03f676dc7869dc5b39fd9f24ff0a1d.tar.bz2
android_packages_apps_Trebuchet-d139b0aa7d03f676dc7869dc5b39fd9f24ff0a1d.zip
Adding support for multiwindow drag and drop
Change-Id: I95b46e3c3f1238307d3ef5a6c81a8e530ba0987a
-rw-r--r--src/com/android/launcher3/ButtonDropTarget.java3
-rw-r--r--src/com/android/launcher3/ShortcutInfo.java2
-rw-r--r--src/com/android/launcher3/dragndrop/AnotherWindowDragSource.java76
-rw-r--r--src/com/android/launcher3/dragndrop/DragController.java14
-rw-r--r--src/com/android/launcher3/dragndrop/DragDriver.java165
-rw-r--r--src/com/android/launcher3/dragndrop/DragLayer.java61
-rw-r--r--src/com/android/launcher3/dragndrop/DragOptions.java5
-rw-r--r--src/com/android/launcher3/dragndrop/ExternalDragPreviewProvider.java79
-rw-r--r--src_config/com/android/launcher3/config/FeatureFlags.java2
9 files changed, 301 insertions, 106 deletions
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 2dde7caa6..cf8abae2e 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -259,7 +259,8 @@ public abstract class ButtonDropTarget extends TextView
}
};
dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
- DRAG_VIEW_DROP_DURATION, new DecelerateInterpolator(2),
+ mLauncher.getDragController().isExternalDrag() ? 1 : DRAG_VIEW_DROP_DURATION,
+ new DecelerateInterpolator(2),
new LinearInterpolator(), onAnimationEndRunnable,
DragLayer.ANIMATION_END_DISAPPEAR, null);
}
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 9d7be1693..fb9374314 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -158,7 +158,7 @@ public class ShortcutInfo extends ItemInfo {
*/
Intent promisedIntent;
- ShortcutInfo() {
+ public ShortcutInfo() {
itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT;
}
diff --git a/src/com/android/launcher3/dragndrop/AnotherWindowDragSource.java b/src/com/android/launcher3/dragndrop/AnotherWindowDragSource.java
new file mode 100644
index 000000000..156941a29
--- /dev/null
+++ b/src/com/android/launcher3/dragndrop/AnotherWindowDragSource.java
@@ -0,0 +1,76 @@
+/*
+ * 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.dragndrop;
+
+import android.content.Context;
+import android.view.View;
+
+import com.android.launcher3.DragSource;
+import com.android.launcher3.DropTarget.DragObject;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+
+/**
+ * DragSource used when the drag started at another window.
+ */
+public class AnotherWindowDragSource implements DragSource {
+
+ private final Context mContext;
+
+ AnotherWindowDragSource(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public boolean supportsFlingToDelete() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsAppInfoDropTarget() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsDeleteDropTarget() {
+ return false;
+ }
+
+ @Override
+ public float getIntrinsicIconScaleFactor() {
+ return 1;
+ }
+
+ @Override
+ public void onFlingToDeleteCompleted() {
+ }
+
+ @Override
+ public void onDropCompleted(View target, DragObject d,
+ boolean isFlingToDelete, boolean success) {
+ if (!success) {
+ Launcher.getLauncher(mContext).exitSpringLoadedDragModeDelayed(false, 0, null);
+ }
+
+ }
+
+ @Override
+ public void fillInLaunchSourceData(View v, ItemInfo info, Target target, Target targetParent) {
+ // TODO: Probably log something
+ }
+}
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index 29e33e944..a93ee9019 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -25,7 +25,6 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
-import android.util.Log;
import android.view.DragEvent;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
@@ -213,6 +212,12 @@ public class DragController implements DragDriver.EventListener, TouchController
}
mInputMethodManager.hideSoftInputFromWindow(mWindowToken, 0);
+ mOptions = options;
+ if (mOptions.systemDndStartPoint != null) {
+ mMotionDownX = mOptions.systemDndStartPoint.x;
+ mMotionDownY = mOptions.systemDndStartPoint.y;
+ }
+
final int registrationX = mMotionDownX - dragLayerX;
final int registrationY = mMotionDownY - dragLayerY;
@@ -221,7 +226,6 @@ public class DragController implements DragDriver.EventListener, TouchController
mLastDropTarget = null;
- mOptions = options;
mDragObject = new DropTarget.DragObject();
final Resources res = mLauncher.getResources();
@@ -241,7 +245,7 @@ public class DragController implements DragDriver.EventListener, TouchController
mDragObject.yOffset = mMotionDownY - (dragLayerY + dragRegionTop);
mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
- mDragDriver = DragDriver.create(this, dragInfo, dragView);
+ mDragDriver = DragDriver.create(mLauncher, this, mDragObject, mOptions);
}
mDragObject.dragSource = source;
@@ -293,6 +297,10 @@ 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/DragDriver.java b/src/com/android/launcher3/dragndrop/DragDriver.java
index 2164708ba..4db8c07d5 100644
--- a/src/com/android/launcher3/dragndrop/DragDriver.java
+++ b/src/com/android/launcher3/dragndrop/DragDriver.java
@@ -17,18 +17,19 @@
package com.android.launcher3.dragndrop;
import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.Context;
import android.content.Intent;
-import android.graphics.Canvas;
-import android.graphics.Point;
import android.view.DragEvent;
import android.view.MotionEvent;
-import android.view.View;
-import com.android.launcher3.AnotherWindowDropTarget;
import com.android.launcher3.DropTarget;
-import com.android.launcher3.ItemInfo;
+import com.android.launcher3.DropTarget.DragObject;
+import com.android.launcher3.InstallShortcutReceiver;
+import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
+
+import java.util.ArrayList;
/**
* Base class for driving a drag/drop operation.
@@ -50,7 +51,7 @@ public abstract class DragDriver {
/**
* Handles ending of the DragView animation.
*/
- public abstract void onDragViewAnimationEnd();
+ public void onDragViewAnimationEnd() { }
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
@@ -89,100 +90,46 @@ public abstract class DragDriver {
return true;
}
- public static DragDriver create(
- DragController dragController, ItemInfo dragInfo, DragView dragView) {
- if (FeatureFlags.LAUNCHER3_USE_SYSTEM_DRAG_DRIVER && Utilities.isNycOrAbove()) {
- return new SystemDragDriver(dragController, dragInfo.getIntent(), dragView);
+ public static DragDriver create(Context context, DragController dragController,
+ DragObject dragObject, DragOptions options) {
+ if (Utilities.isNycOrAbove() && options.systemDndStartPoint != null) {
+ return new SystemDragDriver(dragController, context, dragObject);
} else {
return new InternalDragDriver(dragController);
}
}
-
-};
+}
/**
* Class for driving a system (i.e. framework) drag/drop operation.
*/
class SystemDragDriver extends DragDriver {
- /** Intent associated with the drag operation, or null is there no associated intent. */
- private final Intent mDragIntent;
- private final DragView mDragView;
- boolean mIsFrameworkDragActive = false;
+ private final DragObject mDragObject;
+ private final Context mContext;
+
boolean mReceivedDropEvent = false;
float mLastX = 0;
float mLastY = 0;
- public SystemDragDriver(DragController dragController, Intent dragIntent, DragView dragView) {
+ public SystemDragDriver(DragController dragController, Context context, DragObject dragObject) {
super(dragController);
- mDragIntent = dragIntent;
- mDragView = dragView;
- }
-
- private static class ShadowBuilder extends View.DragShadowBuilder {
- final DragView mDragView;
-
- public ShadowBuilder(DragView dragView) {
- mDragView = dragView;
- }
-
- @Override
- public void onProvideShadowMetrics (Point size, Point touch) {
- mDragView.provideDragShadowMetrics(size, touch);
- }
-
- @Override
- public void onDrawShadow(Canvas canvas) {
- mDragView.drawDragShadow(canvas);
- }
- };
-
- @Override
- public void onDragViewAnimationEnd() {
- // Clip data for the drag operation. If there is an intent, create an intent-based ClipData,
- // which will be passed to a global DND.
- // If there is no intent, craft a fake ClipData and start a local DND operation; this
- // ClipData will be ignored.
- final ClipData dragData = mDragIntent != null ?
- ClipData.newIntent("", mDragIntent) :
- ClipData.newPlainText("", "");
-
- View.DragShadowBuilder shadowBuilder = new ShadowBuilder(mDragView);
- // TODO: DND flags are in flux, once settled, use the appropriate constant.
- final int flagGlobal = 1 << 0;
- final int flagOpaque = 1 << 9;
- final int flags = (mDragIntent != null ? flagGlobal : 0) | flagOpaque;
-
- mIsFrameworkDragActive = true;
-
- if (!mDragView.startDrag(dragData, shadowBuilder, null, flags)) {
- mIsFrameworkDragActive = false;
- mEventListener.onDriverDragCancel();
- return;
- }
-
- // Starting from this point, the driver takes over showing the drag shadow, so hiding the
- // drag view.
- mDragView.setVisibility(View.INVISIBLE);
+ mDragObject = dragObject;
+ mContext = context;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
- return !mIsFrameworkDragActive && super.onTouchEvent(ev);
+ return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
- return !mIsFrameworkDragActive && super.onInterceptTouchEvent(ev);
+ return false;
}
@Override
public boolean onDragEvent (DragEvent event) {
- if (!mIsFrameworkDragActive) {
- // We are interested only in drag events started by this driver.
- return false;
- }
-
final int action = event.getAction();
switch (action) {
@@ -192,8 +139,6 @@ class SystemDragDriver extends DragDriver {
return true;
case DragEvent.ACTION_DRAG_ENTERED:
- mLastX = event.getX();
- mLastY = event.getY();
return true;
case DragEvent.ACTION_DRAG_LOCATION:
@@ -205,35 +150,66 @@ class SystemDragDriver extends DragDriver {
case DragEvent.ACTION_DROP:
mLastX = event.getX();
mLastY = event.getY();
- mReceivedDropEvent = true;
- return true;
+ mReceivedDropEvent =
+ updateInfoFromClipData(event.getClipData(), event.getClipDescription());
+ return mReceivedDropEvent;
case DragEvent.ACTION_DRAG_EXITED:
- mLastX = event.getX();
- mLastY = event.getY();
mEventListener.onDriverDragExitWindow();
return true;
case DragEvent.ACTION_DRAG_ENDED:
- final boolean dragAccepted = event.getResult();
- final boolean acceptedByAnotherWindow = dragAccepted && !mReceivedDropEvent;
-
- // When the system drag ends, its drag shadow disappears. Resume showing the drag
- // view for the possible final animation.
- mDragView.setVisibility(View.VISIBLE);
-
- final DropTarget dropTargetOverride = acceptedByAnotherWindow ?
- new AnotherWindowDropTarget(mDragView.getContext()) : null;
-
- mEventListener.onDriverDragEnd(mLastX, mLastY, dropTargetOverride);
- mIsFrameworkDragActive = false;
+ if (mReceivedDropEvent) {
+ mEventListener.onDriverDragEnd(mLastX, mLastY, null);
+ } else {
+ mEventListener.onDriverDragCancel();
+ }
return true;
default:
return false;
}
}
-};
+
+ private boolean updateInfoFromClipData(ClipData data, ClipDescription desc) {
+ if (data == null) {
+ return false;
+ }
+ ArrayList<Intent> intents = new ArrayList<>();
+ int itemCount = data.getItemCount();
+ for (int i = 0; i < itemCount; i++) {
+ Intent intent = data.getItemAt(i).getIntent();
+ if (intent == null) {
+ continue;
+ }
+
+ // Give preference to shortcut intents.
+ if (!Intent.ACTION_CREATE_SHORTCUT.equals(intent.getAction())) {
+ intents.add(intent);
+ continue;
+ }
+ ShortcutInfo info = InstallShortcutReceiver.fromShortcutIntent(mContext, intent);
+ if (info != null) {
+ mDragObject.dragInfo = info;
+ return true;
+ }
+ return true;
+ }
+
+ // Try creating shortcuts just using the intent and label
+ Intent fullIntent = new Intent().putExtra(Intent.EXTRA_SHORTCUT_NAME, desc.getLabel());
+ for (Intent intent : intents) {
+ fullIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
+ ShortcutInfo info = InstallShortcutReceiver.fromShortcutIntent(mContext, fullIntent);
+ if (info != null) {
+ mDragObject.dragInfo = info;
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
/**
* Class for driving an internal (i.e. not using framework) drag/drop operation.
@@ -244,8 +220,5 @@ class InternalDragDriver extends DragDriver {
}
@Override
- public void onDragViewAnimationEnd() {}
-
- @Override
public boolean onDragEvent (DragEvent event) { return false; }
};
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 58638288e..016347b17 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -21,14 +21,22 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.annotation.TargetApi;
+import android.content.ClipDescription;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.DragEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -45,12 +53,14 @@ import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DropTargetBar;
import com.android.launcher3.InsettableFrameLayout;
+import com.android.launcher3.InstallShortcutReceiver;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetHostView;
import com.android.launcher3.PinchToOverviewListener;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
+import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.allapps.AllAppsTransitionController;
@@ -62,6 +72,7 @@ import com.android.launcher3.shortcuts.DeepShortcutsContainer;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.TouchController;
+import java.net.URISyntaxException;
import java.util.ArrayList;
/**
@@ -431,8 +442,46 @@ public class DragLayer extends InsettableFrameLayout {
return false;
}
+ @TargetApi(Build.VERSION_CODES.N)
+ private void handleSystemDragStart(DragEvent event) {
+ if (!FeatureFlags.LAUNCHER3_USE_SYSTEM_DRAG_DRIVER || !Utilities.isNycOrAbove()) {
+ return;
+ }
+ if (mLauncher.isWorkspaceLocked()) {
+ return;
+ }
+
+ ClipDescription description = event.getClipDescription();
+ if (!description.hasMimeType(ClipDescription.MIMETYPE_TEXT_INTENT)) {
+ return;
+ }
+ ShortcutInfo info = new ShortcutInfo();
+ // Set a dummy intent until we get the final value
+ info.intent = new Intent();
+
+ // Since we are not going through the workspace for starting the drag, set drag related
+ // information on the workspace before starting the drag.
+ ExternalDragPreviewProvider previewProvider =
+ new ExternalDragPreviewProvider(mLauncher, info);
+ mLauncher.getWorkspace().prepareDragWithProvider(previewProvider);
+
+ DragOptions options = new DragOptions();
+ options.systemDndStartPoint = new Point((int) event.getX(), (int) event.getY());
+
+ int halfPadding = previewProvider.previewPadding / 2;
+ mDragController.startDrag(
+ Bitmap.createBitmap(1, 1, Config.ARGB_8888),
+ 0, 0,
+ new AnotherWindowDragSource(mLauncher), info,
+ new Point(- halfPadding, halfPadding),
+ previewProvider.getPreviewBounds(), 1f, options);
+ }
+
@Override
public boolean onDragEvent (DragEvent event) {
+ if (event.getAction() == DragEvent.ACTION_DRAG_STARTED) {
+ handleSystemDragStart(event);
+ }
return mDragController.onDragEvent(event);
}
@@ -758,11 +807,15 @@ public class DragLayer extends InsettableFrameLayout {
// If duration < 0, this is a cue to compute the duration based on the distance
if (duration < 0) {
- duration = res.getInteger(R.integer.config_dropAnimMaxDuration);
- if (dist < maxDist) {
- duration *= mCubicEaseOutInterpolator.getInterpolation(dist / maxDist);
+ 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 = 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/DragOptions.java b/src/com/android/launcher3/dragndrop/DragOptions.java
index a7f28726a..3d52a48c6 100644
--- a/src/com/android/launcher3/dragndrop/DragOptions.java
+++ b/src/com/android/launcher3/dragndrop/DragOptions.java
@@ -16,6 +16,8 @@
package com.android.launcher3.dragndrop;
+import android.graphics.Point;
+
/**
* Set of options to control the drag and drop behavior.
*/
@@ -23,4 +25,7 @@ public class DragOptions {
/** Whether or not an accessible drag operation is in progress. */
public boolean isAccessibleDrag = false;
+
+ /** Specifies the start location for the system DnD, null when using internal DnD */
+ public Point systemDndStartPoint = null;
}
diff --git a/src/com/android/launcher3/dragndrop/ExternalDragPreviewProvider.java b/src/com/android/launcher3/dragndrop/ExternalDragPreviewProvider.java
new file mode 100644
index 000000000..6b14be714
--- /dev/null
+++ b/src/com/android/launcher3/dragndrop/ExternalDragPreviewProvider.java
@@ -0,0 +1,79 @@
+/*
+ * 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.dragndrop;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.HolographicOutlineHelper;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.graphics.DragPreviewProvider;
+
+/**
+ * Extension of {@link DragPreviewProvider} which provides a dummy outline when drag starts from
+ * a different window.
+ * It just draws an empty circle to a placeholder outline.
+ */
+public class ExternalDragPreviewProvider extends DragPreviewProvider {
+
+ private final Launcher mLauncher;
+ private final ItemInfo mAddInfo;
+
+ private final int[] mOutlineSize;
+
+ public ExternalDragPreviewProvider(Launcher launcher, ItemInfo addInfo) {
+ super(null);
+ mLauncher = launcher;
+ mAddInfo = addInfo;
+
+ mOutlineSize = mLauncher.getWorkspace().estimateItemSize(mAddInfo, false);
+ }
+
+ public Rect getPreviewBounds() {
+ Rect rect = new Rect();
+ DeviceProfile dp = mLauncher.getDeviceProfile();
+ rect.left = DRAG_BITMAP_PADDING / 2;
+ rect.top = (mOutlineSize[1] - dp.cellHeightPx) / 2;
+ rect.right = rect.left + dp.iconSizePx;
+ rect.bottom = rect.top + dp.iconSizePx;
+ return rect;
+ }
+
+ @Override
+ public Bitmap createDragOutline(Canvas canvas) {
+ final Bitmap b = Bitmap.createBitmap(mOutlineSize[0], mOutlineSize[1], Bitmap.Config.ALPHA_8);
+ canvas.setBitmap(b);
+
+ Paint paint = new Paint();
+ paint.setColor(Color.WHITE);
+ paint.setStyle(Paint.Style.FILL);
+
+ // Use 0.9f times the radius for the actual circle to account for icon normalization.
+ float radius = getPreviewBounds().width() * 0.5f;
+ canvas.drawCircle(DRAG_BITMAP_PADDING / 2 + radius,
+ DRAG_BITMAP_PADDING / 2 + radius, radius * 0.9f, paint);
+
+ HolographicOutlineHelper.obtain(mLauncher).applyExpensiveOutlineWithBlur(b, canvas);
+ canvas.setBitmap(null);
+ return b;
+ }
+}
diff --git a/src_config/com/android/launcher3/config/FeatureFlags.java b/src_config/com/android/launcher3/config/FeatureFlags.java
index 69d8f0f5f..81fa3370f 100644
--- a/src_config/com/android/launcher3/config/FeatureFlags.java
+++ b/src_config/com/android/launcher3/config/FeatureFlags.java
@@ -27,7 +27,7 @@ public final class FeatureFlags {
// As opposed to the new spring-loaded workspace.
public static boolean LAUNCHER3_LEGACY_WORKSPACE_DND = false;
public static boolean LAUNCHER3_LEGACY_FOLDER_ICON = false;
- public static boolean LAUNCHER3_USE_SYSTEM_DRAG_DRIVER = false;
+ public static boolean LAUNCHER3_USE_SYSTEM_DRAG_DRIVER = true;
public static boolean LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW = false;
public static boolean LAUNCHER3_ALL_APPS_PULL_UP = true;