131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/*
231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License.
631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at
731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and
1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License.
1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
17fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevpackage com.android.launcher3.dragndrop;
1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
19df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chungimport android.content.ComponentName;
206e1bdaf4198f9eb7b4124550d3ad07da2a0226e4Winson Chungimport android.content.res.Resources;
2100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Bitmap;
22b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chungimport android.graphics.Point;
2300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Rect;
240280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.os.IBinder;
25d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshevimport android.view.DragEvent;
264390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport android.view.HapticFeedbackConstants;
274390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport android.view.KeyEvent;
284390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport android.view.MotionEvent;
294390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport android.view.View;
3000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.inputmethod.InputMethodManager;
31c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen
32fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.DragSource;
33fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.DropTarget;
34fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.ItemInfo;
35fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.Launcher;
369d4380856ff41ecb26c0d5aee1747b6060d2ef0eSunny Goyalimport com.android.launcher3.R;
37fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.ShortcutInfo;
38e78e3d734b577c1ab6dc0738a83600374908ea52Sunny Goyalimport com.android.launcher3.accessibility.DragViewStateAnnouncer;
39d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyalimport com.android.launcher3.util.ItemInfoMatcher;
40091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
41645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.util.TouchController;
42091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen
43c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.ArrayList;
4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/**
4600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Class for initiating a drag within a view or across multiple views.
4731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
48645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songpublic class DragController implements DragDriver.EventListener, TouchController {
4900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final boolean PROFILE_DRAWING_DURING_DRAG = false;
5000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
51091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Launcher mLauncher;
520f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal    private FlingToDeleteHelper mFlingToDeleteHelper;
5300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
5400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    // temporaries to avoid gc thrash
5500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Rect mRectTemp = new Rect();
5600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private final int[] mCoordinatesTemp = new int[2];
5700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
58d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    /**
59d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev     * Drag driver for the current drag/drop operation, or null if there is no active DND operation.
6056e40989197420f9c7acf0ab9251a2a87d9513fdVadim Tryshev     * It's null during accessible drag operations.
61d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev     */
62d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    private DragDriver mDragDriver = null;
6300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
6494b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal    /** Options controlling the drag behavior. */
6594b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal    private DragOptions mOptions;
66c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
6700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** X coordinate of the down event. */
68e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    private int mMotionDownX;
6900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
7000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Y coordinate of the down event. */
71e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    private int mMotionDownY;
7200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
739932a9b1e66fed4b5f38ce50f13d56331bbdcd7eAdam Cohen    private DropTarget.DragObject mDragObject;
7400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
7500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Who can receive drop events */
76f5440cbd6c0525769d24b890e16313a728831e04Sunny Goyal    private ArrayList<DropTarget> mDropTargets = new ArrayList<>();
77f5440cbd6c0525769d24b890e16313a728831e04Sunny Goyal    private ArrayList<DragListener> mListeners = new ArrayList<>();
7800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
7900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** The window token used as the parent for the DragView. */
8000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private IBinder mWindowToken;
8100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
82ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    private View mMoveTarget;
83ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy
8400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DropTarget mLastDropTarget;
8500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
86091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk int mLastTouch[] = new int[2];
87091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk long mLastTouchUpTime = -1;
880f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham    @Thunk int mDistanceSinceScroll = 0;
89a16fd5a6bd5371d40a5679261d416f06f8efa022Patrick Dubroy
90273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung    private int mTmpPoint[] = new int[2];
91273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung    private Rect mDragLayerRect = new Rect();
92273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung
9310236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham    private boolean mIsInPreDrag;
946e74e899d314663415f54895227bb79a51fd734bTony Wickham
9531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
9631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Interface to receive notifications when a drag starts or stops
9731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
98fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal    public interface DragListener {
9931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        /**
10031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * A drag has begun
10153b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini         *
10294b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal         * @param dragObject The object being dragged
10394b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal         * @param options Options used to start the drag
10431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         */
10594b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal        void onDragStart(DropTarget.DragObject dragObject, DragOptions options);
10653b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini
10731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        /**
108e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung         * The drag has ended
10931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         */
11031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        void onDragEnd();
11131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
112aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal
11331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
11400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Used to create a new DragLayer from XML.
11531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1168dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    public DragController(Launcher launcher) {
1178dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mLauncher = launcher;
1180f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal        mFlingToDeleteHelper = new FlingToDeleteHelper(launcher);
11900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
12031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
1225162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * Starts a drag.
123a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka     *
1245162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param b The bitmap to display as the drag image.  It will be re-scaled to the
1255162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     *          enlarged size.
1268dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param dragLayerX The x position in the DragLayer of the left-top of the bitmap.
1278dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param dragLayerY The y position in the DragLayer of the left-top of the bitmap.
1285162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param source An object representing where the drag originated
129ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy     * @param dragInfo The data associated with the object that is being dragged
130a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka     * @param dragRegion Coordinates within the bitmap b for the position of item being dragged.
131a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka     *          Makes dragging feel more precise, e.g. you can clip out a transparent border
132a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka     */
133eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung    public DragView startDrag(Bitmap b, int dragLayerX, int dragLayerY,
13494b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal            DragSource source, ItemInfo dragInfo, Point dragOffset, Rect dragRegion,
13594b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal            float initialDragViewScale, DragOptions options) {
13600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (PROFILE_DRAWING_DURING_DRAG) {
13700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            android.os.Debug.startMethodTracing("Launcher");
13800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
13900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
14000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        // Hide soft keyboard, if visible
1410f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal        mLauncher.getSystemService(InputMethodManager.class)
1420f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal                .hideSoftInputFromWindow(mWindowToken, 0);
14300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
144d139b0aa7d03f676dc7869dc5b39fd9f24ff0a1dSunny Goyal        mOptions = options;
145d139b0aa7d03f676dc7869dc5b39fd9f24ff0a1dSunny Goyal        if (mOptions.systemDndStartPoint != null) {
146d139b0aa7d03f676dc7869dc5b39fd9f24ff0a1dSunny Goyal            mMotionDownX = mOptions.systemDndStartPoint.x;
147d139b0aa7d03f676dc7869dc5b39fd9f24ff0a1dSunny Goyal            mMotionDownY = mOptions.systemDndStartPoint.y;
148d139b0aa7d03f676dc7869dc5b39fd9f24ff0a1dSunny Goyal        }
149d139b0aa7d03f676dc7869dc5b39fd9f24ff0a1dSunny Goyal
1508dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        final int registrationX = mMotionDownX - dragLayerX;
1518dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        final int registrationY = mMotionDownY - dragLayerY;
15200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
153a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left;
154a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top;
155e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen
156d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        mLastDropTarget = null;
157cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen
1589932a9b1e66fed4b5f38ce50f13d56331bbdcd7eAdam Cohen        mDragObject = new DropTarget.DragObject();
1599932a9b1e66fed4b5f38ce50f13d56331bbdcd7eAdam Cohen
16010236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        mIsInPreDrag = mOptions.preDragCondition != null
16110236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham                && !mOptions.preDragCondition.shouldStartDrag(0);
1626e74e899d314663415f54895227bb79a51fd734bTony Wickham
1631bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham        final Resources res = mLauncher.getResources();
164f5440cbd6c0525769d24b890e16313a728831e04Sunny Goyal        final float scaleDps = mIsInPreDrag
165f5440cbd6c0525769d24b890e16313a728831e04Sunny Goyal                ? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f;
166e78e3d734b577c1ab6dc0738a83600374908ea52Sunny Goyal        final DragView dragView = mDragObject.dragView = new DragView(mLauncher, b, registrationX,
167157793dda450b69da388b859d1c1a7a1083c4ec9Sunny Goyal                registrationY, initialDragViewScale, scaleDps);
1684a5fd100d743fcd9e51c2da36a9f9f542c5b5cddHyunyoung Song        dragView.setItemInfo(dragInfo);
169bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mDragObject.dragComplete = false;
17094b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal        if (mOptions.isAccessibleDrag) {
171c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            // For an accessible drag, we assume the view is being dragged from the center.
172c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            mDragObject.xOffset = b.getWidth() / 2;
173c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            mDragObject.yOffset = b.getHeight() / 2;
174c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            mDragObject.accessibleDrag = true;
175c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        } else {
176c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            mDragObject.xOffset = mMotionDownX - (dragLayerX + dragRegionLeft);
177c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            mDragObject.yOffset = mMotionDownY - (dragLayerY + dragRegionTop);
178e78e3d734b577c1ab6dc0738a83600374908ea52Sunny Goyal            mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
1799d4380856ff41ecb26c0d5aee1747b6060d2ef0eSunny Goyal
180d139b0aa7d03f676dc7869dc5b39fd9f24ff0a1dSunny Goyal            mDragDriver = DragDriver.create(mLauncher, this, mDragObject, mOptions);
181c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        }
182c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
183cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen        mDragObject.dragSource = source;
184cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen        mDragObject.dragInfo = dragInfo;
18559a238095e82fd02355f4cb53abe01655a50b051Hyunyoung Song        mDragObject.originalDragInfo = new ItemInfo();
18659a238095e82fd02355f4cb53abe01655a50b051Hyunyoung Song        mDragObject.originalDragInfo.copyFrom(dragInfo);
18700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
188b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung        if (dragOffset != null) {
189b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung            dragView.setDragVisualizeOffset(new Point(dragOffset));
190b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung        }
191a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        if (dragRegion != null) {
192e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen            dragView.setDragRegion(new Rect(dragRegion));
193a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        }
194a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
195780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung        mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
1968dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        dragView.show(mMotionDownX, mMotionDownY);
197855b1b5fff5f6f03a641b3b6973780a24fd9641eTony Wickham        mDistanceSinceScroll = 0;
19894b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal
19910236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        if (!mIsInPreDrag) {
20010236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham            callOnDragStart();
20110236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        } else if (mOptions.preDragCondition != null) {
2022bcb3fb1f3ac6234ead13d27817b7a32b7c79b1dSunny Goyal            mOptions.preDragCondition.onPreDragStart(mDragObject);
20394b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal        }
20494b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal
205855b1b5fff5f6f03a641b3b6973780a24fd9641eTony Wickham        mLastTouch[0] = mMotionDownX;
206855b1b5fff5f6f03a641b3b6973780a24fd9641eTony Wickham        mLastTouch[1] = mMotionDownY;
2078dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        handleMoveEvent(mMotionDownX, mMotionDownY);
20859a238095e82fd02355f4cb53abe01655a50b051Hyunyoung Song        mLauncher.getUserEventDispatcher().resetActionDurationMillis();
209eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung        return dragView;
21000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
21100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
21210236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham    private void callOnDragStart() {
21310236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        if (mOptions.preDragCondition != null) {
2142bcb3fb1f3ac6234ead13d27817b7a32b7c79b1dSunny Goyal            mOptions.preDragCondition.onPreDragEnd(mDragObject, true /* dragStarted*/);
21510236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        }
21610236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        mIsInPreDrag = false;
2171322f9cb9a8715d463094e13079af7e6e689429aHyunyoung Song        for (DragListener listener : new ArrayList<>(mListeners)) {
2181322f9cb9a8715d463094e13079af7e6e689429aHyunyoung Song            listener.onDragStart(mDragObject, mOptions);
2191322f9cb9a8715d463094e13079af7e6e689429aHyunyoung Song        }
22010236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham    }
22110236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham
22200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
22300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Call this from a drag source view like this:
22400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
22500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * <pre>
22600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *  @Override
22700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *  public boolean dispatchKeyEvent(KeyEvent event) {
22800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *      return mDragController.dispatchKeyEvent(this, event)
22900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *              || super.dispatchKeyEvent(event);
23000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * </pre>
23100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
23200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public boolean dispatchKeyEvent(KeyEvent event) {
233d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        return mDragDriver != null;
23400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
23500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
236304dcde0e301c2f1a0b2bdc80ea8617930691b6eWinson Chung    public boolean isDragging() {
23794b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal        return mDragDriver != null || (mOptions != null && mOptions.isAccessibleDrag);
238304dcde0e301c2f1a0b2bdc80ea8617930691b6eWinson Chung    }
239304dcde0e301c2f1a0b2bdc80ea8617930691b6eWinson Chung
24024b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato    /**
24124b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato     * Stop dragging without dropping.
24224b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato     */
24324b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato    public void cancelDrag() {
24456e40989197420f9c7acf0ab9251a2a87d9513fdVadim Tryshev        if (isDragging()) {
245c07918d0053fc7d2a19d7b013565a5d2e7d4af51Winson Chung            if (mLastDropTarget != null) {
246c07918d0053fc7d2a19d7b013565a5d2e7d4af51Winson Chung                mLastDropTarget.onDragExit(mDragObject);
247c07918d0053fc7d2a19d7b013565a5d2e7d4af51Winson Chung            }
24841bb19d2775836e30ebf42f681b4617bc71600aaWinson Chung            mDragObject.deferDragViewCleanupPostAnimation = false;
24936cc09b07b19198f4ea886583cef462ade27192cAdam Cohen            mDragObject.cancelled = true;
250bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mDragObject.dragComplete = true;
25110236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham            if (!mIsInPreDrag) {
25210236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham                mDragObject.dragSource.onDropCompleted(null, mDragObject, false, false);
25310236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham            }
254621e6406fadba27d6cff1c38b31d5cdf99c0f97aWinson Chung        }
25524b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato        endDrag();
25624b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato    }
257ca51dcd6ca154b2fb97c79ab0846e58a6ca0623bVadim Tryshev
258d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal    public void onAppsRemoved(ItemInfoMatcher matcher) {
259a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung        // Cancel the current drag if we are removing an app that we are dragging
260a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung        if (mDragObject != null) {
261d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal            ItemInfo dragInfo = mDragObject.dragInfo;
262d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal            if (dragInfo instanceof ShortcutInfo) {
263d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal                ComponentName cn = dragInfo.getTargetComponent();
264d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal                if (cn != null && matcher.matches(dragInfo, cn)) {
265d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal                    cancelDrag();
266a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung                }
267a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung            }
268a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung        }
269a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung    }
27024b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato
27100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private void endDrag() {
27256e40989197420f9c7acf0ab9251a2a87d9513fdVadim Tryshev        if (isDragging()) {
273d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev            mDragDriver = null;
274043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung            boolean isDeferred = false;
275cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen            if (mDragObject.dragView != null) {
276043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung                isDeferred = mDragObject.deferDragViewCleanupPostAnimation;
277043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung                if (!isDeferred) {
2787bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung                    mDragObject.dragView.remove();
279ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham                } else if (mIsInPreDrag) {
280ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham                    animateDragViewToOriginalPosition(null, null, -1);
2817bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung                }
282cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen                mDragObject.dragView = null;
28300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
284043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
285043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung            // Only end the drag if we are not deferred
286043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung            if (!isDeferred) {
28710236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham                callOnDragEnd();
288043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung            }
289043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        }
290043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
2910f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal        mFlingToDeleteHelper.releaseVelocityTracker();
292043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    }
293043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
294ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham    public void animateDragViewToOriginalPosition(final Runnable onComplete,
295ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham            final View originalIcon, int duration) {
296ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham        Runnable onCompleteRunnable = new Runnable() {
297ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham            @Override
298ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham            public void run() {
299ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham                if (originalIcon != null) {
300ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham                    originalIcon.setVisibility(View.VISIBLE);
301ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham                }
302ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham                if (onComplete != null) {
303ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham                    onComplete.run();
304ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham                }
305ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham            }
306ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham        };
307ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham        mDragObject.dragView.animateTo(mMotionDownX, mMotionDownY, onCompleteRunnable, duration);
308ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham    }
309ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham
31010236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham    private void callOnDragEnd() {
31110236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        if (mIsInPreDrag && mOptions.preDragCondition != null) {
3122bcb3fb1f3ac6234ead13d27817b7a32b7c79b1dSunny Goyal            mOptions.preDragCondition.onPreDragEnd(mDragObject, false /* dragStarted*/);
31310236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        }
31410236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        mIsInPreDrag = false;
31510236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        mOptions = null;
31610236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        for (DragListener listener : new ArrayList<>(mListeners)) {
31710236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham            listener.onDragEnd();
31810236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        }
31910236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham    }
32010236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham
321043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    /**
322043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung     * This only gets called as a result of drag view cleanup being deferred in endDrag();
323043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung     */
324043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    void onDeferredEndDrag(DragView dragView) {
325043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        dragView.remove();
326043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
3271e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka        if (mDragObject.deferDragViewCleanupPostAnimation) {
3281e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka            // If we skipped calling onDragEnd() before, do it now
32910236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham            callOnDragEnd();
33000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
33100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
33200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
33300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
334273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung     * Clamps the position to the drag layer bounds.
335273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung     */
336273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung    private int[] getClampedDragLayerPos(float x, float y) {
337273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung        mLauncher.getDragLayer().getLocalVisibleRect(mDragLayerRect);
338273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung        mTmpPoint[0] = (int) Math.max(mDragLayerRect.left, Math.min(x, mDragLayerRect.right - 1));
339273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung        mTmpPoint[1] = (int) Math.max(mDragLayerRect.top, Math.min(y, mDragLayerRect.bottom - 1));
340273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung        return mTmpPoint;
341273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung    }
342273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung
343fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshev    public long getLastGestureUpTime() {
344d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        if (mDragDriver != null) {
345a2413751e3a698aef9c87411a639637883856939Winson Chung            return System.currentTimeMillis();
346a2413751e3a698aef9c87411a639637883856939Winson Chung        } else {
347a2413751e3a698aef9c87411a639637883856939Winson Chung            return mLastTouchUpTime;
348a2413751e3a698aef9c87411a639637883856939Winson Chung        }
349a2413751e3a698aef9c87411a639637883856939Winson Chung    }
350a2413751e3a698aef9c87411a639637883856939Winson Chung
351fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshev    public void resetLastGestureUpTime() {
352a2413751e3a698aef9c87411a639637883856939Winson Chung        mLastTouchUpTime = -1;
353a2413751e3a698aef9c87411a639637883856939Winson Chung    }
354a2413751e3a698aef9c87411a639637883856939Winson Chung
355ca51dcd6ca154b2fb97c79ab0846e58a6ca0623bVadim Tryshev    @Override
356d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    public void onDriverDragMove(float x, float y) {
357d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        final int[] dragLayerPos = getClampedDragLayerPos(x, y);
358d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev
359d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        handleMoveEvent(dragLayerPos[0], dragLayerPos[1]);
360d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    }
361d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev
362ca51dcd6ca154b2fb97c79ab0846e58a6ca0623bVadim Tryshev    @Override
363ceed3b87dc5c1229bcd9050392e023f9a58eaa2cVadim Tryshev    public void onDriverDragExitWindow() {
364ceed3b87dc5c1229bcd9050392e023f9a58eaa2cVadim Tryshev        if (mLastDropTarget != null) {
365ceed3b87dc5c1229bcd9050392e023f9a58eaa2cVadim Tryshev            mLastDropTarget.onDragExit(mDragObject);
366ceed3b87dc5c1229bcd9050392e023f9a58eaa2cVadim Tryshev            mLastDropTarget = null;
367ceed3b87dc5c1229bcd9050392e023f9a58eaa2cVadim Tryshev        }
368ceed3b87dc5c1229bcd9050392e023f9a58eaa2cVadim Tryshev    }
369ceed3b87dc5c1229bcd9050392e023f9a58eaa2cVadim Tryshev
370ceed3b87dc5c1229bcd9050392e023f9a58eaa2cVadim Tryshev    @Override
3710f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal    public void onDriverDragEnd(float x, float y) {
372d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        DropTarget dropTarget;
3730f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal        Runnable flingAnimation = mFlingToDeleteHelper.getFlingAnimation(mDragObject);
3740f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal        if (flingAnimation != null) {
3750f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal            dropTarget = mFlingToDeleteHelper.getDropTarget();
376d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        } else {
3770f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal            dropTarget = findDropTarget((int) x, (int) y, mCoordinatesTemp);
378d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        }
379d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev
3800f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal        drop(dropTarget, flingAnimation);
381d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev
382d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        endDrag();
383d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    }
384d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev
385ca51dcd6ca154b2fb97c79ab0846e58a6ca0623bVadim Tryshev    @Override
386ca51dcd6ca154b2fb97c79ab0846e58a6ca0623bVadim Tryshev    public void onDriverDragCancel() {
387ca51dcd6ca154b2fb97c79ab0846e58a6ca0623bVadim Tryshev        cancelDrag();
388ca51dcd6ca154b2fb97c79ab0846e58a6ca0623bVadim Tryshev    }
389ca51dcd6ca154b2fb97c79ab0846e58a6ca0623bVadim Tryshev
390d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    /**
39100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Call this from a drag source view.
39200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
3936ad72f02fd233f2294222477102e83d721100493Sunny Goyal    public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
39494b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal        if (mOptions != null && mOptions.isAccessibleDrag) {
395c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen            return false;
396c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        }
397c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
398043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        // Update the velocity tracker
3990f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal        mFlingToDeleteHelper.recordMotionEvent(ev);
400043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
401043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        final int action = ev.getAction();
402273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung        final int[] dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY());
403273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung        final int dragLayerX = dragLayerPos[0];
404273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung        final int dragLayerY = dragLayerPos[1];
40500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
40600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        switch (action) {
40700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            case MotionEvent.ACTION_DOWN:
40800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                // Remember location of down touch
4098dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                mMotionDownX = dragLayerX;
4108dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                mMotionDownY = dragLayerY;
41100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                break;
41200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            case MotionEvent.ACTION_UP:
413a2413751e3a698aef9c87411a639637883856939Winson Chung                mLastTouchUpTime = System.currentTimeMillis();
414621e6406fadba27d6cff1c38b31d5cdf99c0f97aWinson Chung                break;
41500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
41600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
417d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        return mDragDriver != null && mDragDriver.onInterceptTouchEvent(ev);
418d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    }
419d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev
420d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    /**
421d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev     * Call this from a drag source view.
422d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev     */
423b38fab75735c601b61765ecae61494c8637aaef4Sunny Goyal    public boolean onDragEvent(long dragStartTime, DragEvent event) {
424b38fab75735c601b61765ecae61494c8637aaef4Sunny Goyal        mFlingToDeleteHelper.recordDragEvent(dragStartTime, event);
425d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        return mDragDriver != null && mDragDriver.onDragEvent(event);
426d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    }
427d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev
428d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    /**
429d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev     * Call this from a drag view.
430d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev     */
431d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev    public void onDragViewAnimationEnd() {
43256e40989197420f9c7acf0ab9251a2a87d9513fdVadim Tryshev        if (mDragDriver != null) {
433d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev            mDragDriver.onDragViewAnimationEnd();
434d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        }
43500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
43600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
43700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
438ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy     * Sets the view that should handle move events.
439ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy     */
440fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshev    public void setMoveTarget(View view) {
441ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy        mMoveTarget = view;
44259a238095e82fd02355f4cb53abe01655a50b051Hyunyoung Song    }
443ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy
444ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    public boolean dispatchUnhandledMove(View focused, int direction) {
445ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy        return mMoveTarget != null && mMoveTarget.dispatchUnhandledMove(focused, direction);
446ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    }
447ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy
448de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy    private void handleMoveEvent(int x, int y) {
449cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen        mDragObject.dragView.move(x, y);
450de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy
451de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        // Drop on someone?
452de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        final int[] coordinates = mCoordinatesTemp;
453de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        DropTarget dropTarget = findDropTarget(x, y, coordinates);
454cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen        mDragObject.x = coordinates[0];
455cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen        mDragObject.y = coordinates[1];
45625460a1d5cb473033408c9e76898bb77e785c66fWinson Chung        checkTouchMove(dropTarget);
45725460a1d5cb473033408c9e76898bb77e785c66fWinson Chung
4580f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham        // Check if we are hovering over the scroll areas
4590f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham        mDistanceSinceScroll += Math.hypot(mLastTouch[0] - x, mLastTouch[1] - y);
46025460a1d5cb473033408c9e76898bb77e785c66fWinson Chung        mLastTouch[0] = x;
46125460a1d5cb473033408c9e76898bb77e785c66fWinson Chung        mLastTouch[1] = y;
4626e74e899d314663415f54895227bb79a51fd734bTony Wickham
46310236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        if (mIsInPreDrag && mOptions.preDragCondition != null
46410236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham                && mOptions.preDragCondition.shouldStartDrag(mDistanceSinceScroll)) {
46510236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham            callOnDragStart();
4666e74e899d314663415f54895227bb79a51fd734bTony Wickham        }
46725460a1d5cb473033408c9e76898bb77e785c66fWinson Chung    }
46825460a1d5cb473033408c9e76898bb77e785c66fWinson Chung
469855b1b5fff5f6f03a641b3b6973780a24fd9641eTony Wickham    public float getDistanceDragged() {
470855b1b5fff5f6f03a641b3b6973780a24fd9641eTony Wickham        return mDistanceSinceScroll;
471855b1b5fff5f6f03a641b3b6973780a24fd9641eTony Wickham    }
472855b1b5fff5f6f03a641b3b6973780a24fd9641eTony Wickham
47325460a1d5cb473033408c9e76898bb77e785c66fWinson Chung    public void forceTouchMove() {
47425460a1d5cb473033408c9e76898bb77e785c66fWinson Chung        int[] dummyCoordinates = mCoordinatesTemp;
47525460a1d5cb473033408c9e76898bb77e785c66fWinson Chung        DropTarget dropTarget = findDropTarget(mLastTouch[0], mLastTouch[1], dummyCoordinates);
4764ef75f523c5b2bfed37bf1ed4bd2bcf8bda8b502Adam Cohen        mDragObject.x = dummyCoordinates[0];
4774ef75f523c5b2bfed37bf1ed4bd2bcf8bda8b502Adam Cohen        mDragObject.y = dummyCoordinates[1];
47825460a1d5cb473033408c9e76898bb77e785c66fWinson Chung        checkTouchMove(dropTarget);
47925460a1d5cb473033408c9e76898bb77e785c66fWinson Chung    }
48025460a1d5cb473033408c9e76898bb77e785c66fWinson Chung
48125460a1d5cb473033408c9e76898bb77e785c66fWinson Chung    private void checkTouchMove(DropTarget dropTarget) {
482de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        if (dropTarget != null) {
483de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy            if (mLastDropTarget != dropTarget) {
484de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy                if (mLastDropTarget != null) {
485cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen                    mLastDropTarget.onDragExit(mDragObject);
486de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy                }
487cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen                dropTarget.onDragEnter(mDragObject);
488de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy            }
489cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen            dropTarget.onDragOver(mDragObject);
490de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        } else {
491de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy            if (mLastDropTarget != null) {
492cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen                mLastDropTarget.onDragExit(mDragObject);
493de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy            }
494de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        }
495de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        mLastDropTarget = dropTarget;
49625460a1d5cb473033408c9e76898bb77e785c66fWinson Chung    }
497de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy
498ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    /**
49900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Call this from a drag source view.
50000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
5016ad72f02fd233f2294222477102e83d721100493Sunny Goyal    public boolean onControllerTouchEvent(MotionEvent ev) {
50294b510cc683a6436ae82c6d323cbd8b429561b06Sunny Goyal        if (mDragDriver == null || mOptions == null || mOptions.isAccessibleDrag) {
50300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            return false;
50400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
50500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
506043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        // Update the velocity tracker
5070f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal        mFlingToDeleteHelper.recordMotionEvent(ev);
508043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
50900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final int action = ev.getAction();
510273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung        final int[] dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY());
511273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung        final int dragLayerX = dragLayerPos[0];
512273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung        final int dragLayerY = dragLayerPos[1];
51300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
51400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        switch (action) {
515d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev            case MotionEvent.ACTION_DOWN:
516d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev                // Remember where the motion event started
517d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev                mMotionDownX = dragLayerX;
518d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev                mMotionDownY = dragLayerY;
519d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev                break;
52000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
52100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
522d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        return mDragDriver.onTouchEvent(ev);
52300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
52400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
525043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    /**
526c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen     * Since accessible drag and drop won't cause the same sequence of touch events, we manually
527c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen     * inject the appropriate state.
528c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen     */
529c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public void prepareAccessibleDrag(int x, int y) {
530c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mMotionDownX = x;
531c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mMotionDownY = y;
532c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
533c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
534c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    /**
535c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen     * As above, since accessible drag and drop won't cause the same sequence of touch events,
536c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen     * we manually ensure appropriate drag and drop events get emulated for accessible drag.
537c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen     */
538c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    public void completeAccessibleDrag(int[] location) {
539c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        final int[] coordinates = mCoordinatesTemp;
540c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
541c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        // We make sure that we prime the target for drop.
542c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        DropTarget dropTarget = findDropTarget(location[0], location[1], coordinates);
543c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragObject.x = coordinates[0];
544c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        mDragObject.y = coordinates[1];
545c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        checkTouchMove(dropTarget);
546c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
547e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal        dropTarget.prepareAccessibilityDrop();
548c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        // Perform the drop
5490f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal        drop(dropTarget, null);
550c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen        endDrag();
551c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen    }
552c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen
5530f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal    private void drop(DropTarget dropTarget, Runnable flingAnimation) {
554043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        final int[] coordinates = mCoordinatesTemp;
555043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        mDragObject.x = coordinates[0];
556043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        mDragObject.y = coordinates[1];
557043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
558d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        // Move dragging to the final target.
559d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        if (dropTarget != mLastDropTarget) {
560d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev            if (mLastDropTarget != null) {
561d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev                mLastDropTarget.onDragExit(mDragObject);
562d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev            }
563d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev            mLastDropTarget = dropTarget;
564d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev            if (dropTarget != null) {
565d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev                dropTarget.onDragEnter(mDragObject);
566d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev            }
567043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        }
568043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
569232decb008661d82ed2ca6d5f3080ee5a50d3be1Winson Chung        mDragObject.dragComplete = true;
57000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
571d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        // Drop onto the target.
572b0a6bbeeab0960419dcd1f695c209ca0ec36ab8aPatrick Dubroy        boolean accepted = false;
57300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (dropTarget != null) {
574cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen            dropTarget.onDragExit(mDragObject);
575cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen            if (dropTarget.acceptDrop(mDragObject)) {
5760f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal                if (flingAnimation != null) {
5770f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal                    flingAnimation.run();
578ea62fe0be19c54f8fbb434c6334418b96626f70dTony Wickham                } else if (!mIsInPreDrag) {
579d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev                    dropTarget.onDrop(mDragObject);
580d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev                }
581b0a6bbeeab0960419dcd1f695c209ca0ec36ab8aPatrick Dubroy                accepted = true;
58200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
58300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
584d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev        final View dropTargetAsView = dropTarget instanceof View ? (View) dropTarget : null;
58510236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham        if (!mIsInPreDrag) {
586c6b79e307f59e936ee380da07b0bd6fafe0a490cTony Wickham            mLauncher.getUserEventDispatcher().logDragNDrop(mDragObject, dropTargetAsView);
58710236d6ac7f5f787ca21736494ccb5eaf2bd7c27Tony Wickham            mDragObject.dragSource.onDropCompleted(
5880f76b56865bd7b63bd21d53aaac47300396aa38fSunny Goyal                    dropTargetAsView, mDragObject, flingAnimation != null, accepted);
5896e74e899d314663415f54895227bb79a51fd734bTony Wickham        }
59000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
59100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
59200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DropTarget findDropTarget(int x, int y, int[] dropCoordinates) {
59300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final Rect r = mRectTemp;
59400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
59500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final ArrayList<DropTarget> dropTargets = mDropTargets;
59600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final int count = dropTargets.size();
59700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        for (int i=count-1; i>=0; i--) {
598440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            DropTarget target = dropTargets.get(i);
5990280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            if (!target.isDropEnabled())
6000280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                continue;
6010280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
6027d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen            target.getHitRectRelativeToDragLayer(r);
603440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy
604cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen            mDragObject.x = x;
605cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen            mDragObject.y = y;
60600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (r.contains(x, y)) {
607440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy
6087d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen                dropCoordinates[0] = x;
6097d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen                dropCoordinates[1] = y;
6100de011705b132eacdd10f7bfb5cdc4bd79a147e8Hyunyoung Song                mLauncher.getDragLayer().mapCoordInSelfToDescendant((View) target, dropCoordinates);
611440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy
61200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                return target;
61300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
61400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
61500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return null;
61600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
61700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
61800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setWindowToken(IBinder token) {
61900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mWindowToken = token;
62000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
62100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
62231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
6230de011705b132eacdd10f7bfb5cdc4bd79a147e8Hyunyoung Song     * Sets the drag listener which will be notified when a drag starts or ends.
62431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
6254ed6278e518cc6894cb150b606382e8e6a012599Patrick Dubroy    public void addDragListener(DragListener l) {
6264ed6278e518cc6894cb150b606382e8e6a012599Patrick Dubroy        mListeners.add(l);
62700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
62800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
62931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
63031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove a previously installed drag listener.
63131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
63200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void removeDragListener(DragListener l) {
6334ed6278e518cc6894cb150b606382e8e6a012599Patrick Dubroy        mListeners.remove(l);
63400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
63500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
63600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
63700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Add a DropTarget to the list of potential places to receive drop events.
63800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
63900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void addDropTarget(DropTarget target) {
64000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDropTargets.add(target);
64100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
64200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
64300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
64400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Don't send drop events to <em>target</em> any more.
64500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
64600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void removeDropTarget(DropTarget target) {
64700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDropTargets.remove(target);
64800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
64900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
65031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
651