diff options
Diffstat (limited to 'src/com/android/launcher3/dragndrop/DragDriver.java')
-rw-r--r-- | src/com/android/launcher3/dragndrop/DragDriver.java | 165 |
1 files changed, 69 insertions, 96 deletions
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; } }; |