Include the local state obj in ACTION_DRAG_STARTED events

Fixes bug 3362502

The underlying cause was that the DragEvent.obtain() variant which
clones an existing event was failing to copy the local state field.

This change also moves the logic for inserting the local state object
into DragEvents about to be dispatched from the Binder incall thread
into the main-thread code sequence.  This is to eliminate any potential
SMP memory coherency issues around drag start vs incoming events
needing to refer to the local state object.

Change-Id: I368e8936dbf8a00b7d5cc19c2ef0101bd75b6b2d
This commit is contained in:
Christopher Tate
2011-01-20 13:46:41 -08:00
parent a7cb63a153
commit 7fb8b565f9
2 changed files with 8 additions and 6 deletions

View File

@@ -130,12 +130,13 @@ public static final int ACTION_DRAG_EXITED = 6;
}
private void init(int action, float x, float y, ClipDescription description, ClipData data,
boolean result) {
Object localState, boolean result) {
mAction = action;
mX = x;
mY = y;
mClipDescription = description;
mClipData = data;
mLocalState = localState;
mDragResult = result;
}
@@ -150,7 +151,7 @@ public static final int ACTION_DRAG_EXITED = 6;
synchronized (gRecyclerLock) {
if (gRecyclerTop == null) {
ev = new DragEvent();
ev.init(action, x, y, description, data, result);
ev.init(action, x, y, description, data, localState, result);
return ev;
}
ev = gRecyclerTop;
@@ -161,7 +162,7 @@ public static final int ACTION_DRAG_EXITED = 6;
ev.mRecycled = false;
ev.mNext = null;
ev.init(action, x, y, description, data, result);
ev.init(action, x, y, description, data, localState, result);
return ev;
}

View File

@@ -228,7 +228,7 @@ public final class ViewRoot extends Handler implements ViewParent,
/* Drag/drop */
ClipDescription mDragDescription;
View mCurrentDragView;
Object mLocalDragState;
volatile Object mLocalDragState;
final PointF mDragPoint = new PointF();
final PointF mLastTouchPoint = new PointF();
@@ -2051,7 +2051,9 @@ public final class ViewRoot extends Handler implements ViewParent,
} break;
case DISPATCH_DRAG_EVENT:
case DISPATCH_DRAG_LOCATION_EVENT: {
handleDragEvent((DragEvent)msg.obj);
DragEvent event = (DragEvent)msg.obj;
event.mLocalState = mLocalDragState; // only present when this app called startDrag()
handleDragEvent(event);
} break;
}
}
@@ -3133,7 +3135,6 @@ 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);
}