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