diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 35d5d8ec6c3dd..7455b8bc3cf32 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -17,6 +17,7 @@ package android.view; import static android.content.res.Resources.ID_NULL; +import static android.view.ContentInfo.SOURCE_DRAG_AND_DROP; import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED; import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_BOUNDS; import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW; @@ -26747,6 +26748,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@link android.view.DragEvent#getAction()} returns one of the action type constants defined * in DragEvent. The method uses these to determine what is happening in the drag and drop * operation. + *

+ *

+ * The default implementation returns false, except if an {@link OnReceiveContentListener} + * is {@link #setOnReceiveContentListener set} for this view. If an + * {@link OnReceiveContentListener} is set, the default implementation... + *

+ *

+ * * @param event The {@link android.view.DragEvent} sent by the system. * The {@link android.view.DragEvent#getAction()} method returns an action type constant defined * in DragEvent, indicating the type of drag event represented by this object. @@ -26766,6 +26782,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback, *

*/ public boolean onDragEvent(DragEvent event) { + if (mListenerInfo == null || mListenerInfo.mOnReceiveContentListener == null) { + return false; + } + // Accept drag events by default if there's an OnReceiveContentListener set. + if (event.getAction() == DragEvent.ACTION_DRAG_STARTED) { + return true; + } + if (event.getAction() == DragEvent.ACTION_DROP) { + final DragAndDropPermissions permissions = DragAndDropPermissions.obtain(event); + if (permissions != null) { + permissions.takeTransient(); + } + final ContentInfo payload = new ContentInfo.Builder( + event.getClipData(), SOURCE_DRAG_AND_DROP).build(); + ContentInfo remainingPayload = performReceiveContent(payload); + // Return true unless none of the payload was consumed. + return remainingPayload != payload; + } return false; } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index dba7fa915f359..940a3c9cccdf2 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -13071,11 +13071,37 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return getLayout().getOffsetForHorizontal(line, x); } + /** + * Handles drag events sent by the system following a call to + * {@link android.view.View#startDragAndDrop(ClipData,DragShadowBuilder,Object,int) + * startDragAndDrop()}. + * + *

If this text view is not editable, delegates to the default {@link View#onDragEvent} + * implementation. + * + *

If this text view is editable, accepts all drag actions (returns true for an + * {@link android.view.DragEvent#ACTION_DRAG_STARTED ACTION_DRAG_STARTED} event and all + * subsequent drag events). While the drag is in progress, updates the cursor position + * to follow the touch location. Once a drop event is received, handles content insertion + * via {@link #performReceiveContent}. + * + * @param event The {@link android.view.DragEvent} sent by the system. + * The {@link android.view.DragEvent#getAction()} method returns an action type constant + * defined in DragEvent, indicating the type of drag event represented by this object. + * @return Returns true if this text view is editable and delegates to super otherwise. + * See {@link View#onDragEvent}. + */ @Override public boolean onDragEvent(DragEvent event) { + if (mEditor == null || !mEditor.hasInsertionController()) { + // If this TextView is not editable, defer to the default View implementation. This + // will check for the presence of an OnReceiveContentListener and accept/reject + // drag events depending on whether the listener is/isn't set. + return super.onDragEvent(event); + } switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: - return mEditor != null && mEditor.hasInsertionController(); + return true; case DragEvent.ACTION_DRAG_ENTERED: TextView.this.requestFocus();