diff options
-rw-r--r-- | api/current.xml | 13 | ||||
-rw-r--r-- | core/java/android/view/DragEvent.java | 17 | ||||
-rw-r--r-- | core/java/android/view/View.java | 23 | ||||
-rw-r--r-- | core/java/android/view/ViewRoot.java | 14 | ||||
-rw-r--r-- | core/java/android/widget/TextView.java | 2 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java | 2 | ||||
-rw-r--r-- | services/java/com/android/server/WindowManagerService.java | 10 |
7 files changed, 68 insertions, 13 deletions
diff --git a/api/current.xml b/api/current.xml index 9fc6e3e..31626b9 100644 --- a/api/current.xml +++ b/api/current.xml @@ -194856,6 +194856,17 @@ visibility="public" > </method> +<method name="getLocalState" + return="java.lang.Object" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getResult" return="boolean" abstract="false" @@ -208857,6 +208868,8 @@ </parameter> <parameter name="myWindowOnly" type="boolean"> </parameter> +<parameter name="myLocalState" type="java.lang.Object"> +</parameter> </method> <method name="unscheduleDrawable" return="void" diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java index 07e87d6..6634f00 100644 --- a/core/java/android/view/DragEvent.java +++ b/core/java/android/view/DragEvent.java @@ -29,6 +29,7 @@ public class DragEvent implements Parcelable { float mX, mY; ClipDescription mClipDescription; ClipData mClipData; + Object mLocalState; boolean mDragResult; private DragEvent mNext; @@ -139,11 +140,11 @@ public static final int ACTION_DRAG_EXITED = 6; } static DragEvent obtain() { - return DragEvent.obtain(0, 0f, 0f, null, null, false); + return DragEvent.obtain(0, 0f, 0f, null, null, null, false); } /** @hide */ - public static DragEvent obtain(int action, float x, float y, + public static DragEvent obtain(int action, float x, float y, Object localState, ClipDescription description, ClipData data, boolean result) { final DragEvent ev; synchronized (gRecyclerLock) { @@ -167,7 +168,7 @@ public static final int ACTION_DRAG_EXITED = 6; /** @hide */ public static DragEvent obtain(DragEvent source) { - return obtain(source.mAction, source.mX, source.mY, + return obtain(source.mAction, source.mX, source.mY, source.mLocalState, source.mClipDescription, source.mClipData, source.mDragResult); } @@ -218,6 +219,15 @@ public static final int ACTION_DRAG_EXITED = 6; } /** + * Provides the local state object passed as the {@code myLocalState} parameter to + * View.startDrag(). The object will always be null here if the application receiving + * the DragEvent is not the one that started the drag. + */ + public Object getLocalState() { + return mLocalState; + } + + /** * Provides an indication of whether the drag operation concluded successfully. * This method is only available on ACTION_DRAG_ENDED events. * @return {@code true} if the drag operation ended with an accepted drop; {@code false} @@ -249,6 +259,7 @@ public static final int ACTION_DRAG_EXITED = 6; mClipData = null; mClipDescription = null; + mLocalState = null; synchronized (gRecyclerLock) { if (gRecyclerUsed < MAX_RECYCLED) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index f135fcc..ea237e3 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -10081,9 +10081,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility * onProvideThumbnailMetrics() and onDrawThumbnail() methods happen, then the drag * operation is handed over to the OS. * !!! TODO: real docs + * + * @param data !!! TODO + * @param thumbBuilder !!! TODO + * @param myWindowOnly When {@code true}, indicates that the drag operation should be + * restricted to the calling application. In this case only the calling application + * will see any DragEvents related to this drag operation. + * @param myLocalState An arbitrary object that will be passed as part of every DragEvent + * delivered to the calling application during the course of the current drag operation. + * This object is private to the application that called startDrag(), and is not + * visible to other applications. It provides a lightweight way for the application to + * propagate information from the initiator to the recipient of a drag within its own + * application; for example, to help disambiguate between 'copy' and 'move' semantics. + * @return {@code true} if the drag operation was initiated successfully; {@code false} if + * an error prevented the drag from taking place. */ public final boolean startDrag(ClipData data, DragThumbnailBuilder thumbBuilder, - boolean myWindowOnly) { + boolean myWindowOnly, Object myLocalState) { if (ViewDebug.DEBUG_DRAG) { Log.d(VIEW_LOG_TAG, "startDrag: data=" + data + " local=" + myWindowOnly); } @@ -10117,8 +10131,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility surface.unlockCanvasAndPost(canvas); } + final ViewRoot root = getViewRoot(); + + // Cache the local state object for delivery with DragEvents + root.setLocalDragState(myLocalState); + // repurpose 'thumbSize' for the last touch point - getViewRoot().getLastTouchPoint(thumbSize); + root.getLastTouchPoint(thumbSize); okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, token, (float) thumbSize.x, (float) thumbSize.y, diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 77083a9..17d413a 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -228,6 +228,7 @@ public final class ViewRoot extends Handler implements ViewParent, /* Drag/drop */ ClipDescription mDragDescription; View mCurrentDragView; + Object mLocalDragState; final PointF mDragPoint = new PointF(); final PointF mLastTouchPoint = new PointF(); @@ -2680,6 +2681,10 @@ public final class ViewRoot extends Handler implements ViewParent, } /* drag/drop */ + void setLocalDragState(Object obj) { + mLocalDragState = obj; + } + private void handleDragEvent(DragEvent event) { // From the root, only drag start/end/location are dispatched. entered/exited // are determined and dispatched by the viewgroup hierarchy, who then report @@ -2738,7 +2743,7 @@ public final class ViewRoot extends Handler implements ViewParent, } } - // Report the drop result if necessary + // Report the drop result when we're done if (what == DragEvent.ACTION_DROP) { try { Log.i(TAG, "Reporting drop result: " + result); @@ -2747,6 +2752,12 @@ public final class ViewRoot extends Handler implements ViewParent, Log.e(TAG, "Unable to report drop result"); } } + + // When the drag operation ends, release any local state object + // that may have been in use + if (what == DragEvent.ACTION_DRAG_ENDED) { + setLocalDragState(null); + } } } event.recycle(); @@ -3063,6 +3074,7 @@ public final class ViewRoot extends Handler implements ViewParent, } else { what = DISPATCH_DRAG_EVENT; } + event.mLocalState = mLocalDragState; // only present when this app called startDrag() Message msg = obtainMessage(what, event); sendMessage(msg); } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index b4512cf..43434d3 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -7818,7 +7818,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener final int end = getSelectionEnd(); CharSequence selectedText = mTransformed.subSequence(start, end); ClipData data = ClipData.newPlainText(null, null, selectedText); - startDrag(data, getTextThumbnailBuilder(selectedText), false); + startDrag(data, getTextThumbnailBuilder(selectedText), false, null); mDragSourcePositions = packRangeInLong(start, end); stopSelectionActionMode(); } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java index d1e61a9..4d0835f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java @@ -169,7 +169,7 @@ public class ShirtPocket extends FrameLayout { thumb = new DragThumbnailBuilder(mWindow.findViewById(R.id.preview)); } - v.startDrag(clip, thumb, false); + v.startDrag(clip, thumb, false, null); // TODO: only discard the clipping if it was accepted stash(null); diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 27ec1af..d7a6a0e 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -619,7 +619,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mDragInProgress && newWin.isPotentialDragTarget()) { DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, touchX - newWin.mFrame.left, touchY - newWin.mFrame.top, - desc, null, false); + null, desc, null, false); try { newWin.mClient.dispatchDragEvent(event); // track each window that we've notified that the drag is starting @@ -659,7 +659,7 @@ public class WindowManagerService extends IWindowManager.Stub Slog.d(TAG, "broadcasting DRAG_ENDED"); } DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED, - 0, 0, null, null, mDragResult); + 0, 0, null, null, null, mDragResult); for (WindowState ws: mNotifiedWindows) { try { ws.mClient.dispatchDragEvent(evt); @@ -711,7 +711,7 @@ public class WindowManagerService extends IWindowManager.Stub // force DRAG_EXITED_EVENT if appropriate DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED, x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top, - null, null, false); + null, null, null, false); mTargetWindow.mClient.dispatchDragEvent(evt); if (myPid != mTargetWindow.mSession.mPid) { evt.recycle(); @@ -723,7 +723,7 @@ public class WindowManagerService extends IWindowManager.Stub } DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION, x - touchedWin.mFrame.left, y - touchedWin.mFrame.top, - null, null, false); + null, null, null, false); touchedWin.mClient.dispatchDragEvent(evt); if (myPid != touchedWin.mSession.mPid) { evt.recycle(); @@ -754,7 +754,7 @@ public class WindowManagerService extends IWindowManager.Stub final IBinder token = touchedWin.mClient.asBinder(); DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP, x - touchedWin.mFrame.left, y - touchedWin.mFrame.top, - null, mData, false); + null, null, mData, false); try { touchedWin.mClient.dispatchDragEvent(evt); |