1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.view;
import android.content.ClipData;
import android.content.ClipDescription;
import android.os.Parcel;
import android.os.Parcelable;
/** !!! TODO: real docs */
public class DragEvent implements Parcelable {
private static final boolean TRACK_RECYCLED_LOCATION = false;
int mAction;
float mX, mY;
ClipDescription mClipDescription;
ClipData mClipData;
private DragEvent mNext;
private RuntimeException mRecycledLocation;
private boolean mRecycled;
private static final int MAX_RECYCLED = 10;
private static final Object gRecyclerLock = new Object();
private static int gRecyclerUsed = 0;
private static DragEvent gRecyclerTop = null;
/**
* action constants for DragEvent dispatch
*/
public static final int ACTION_DRAG_STARTED = 1;
public static final int ACTION_DRAG_LOCATION = 2;
public static final int ACTION_DROP = 3;
public static final int ACTION_DRAG_ENDED = 4;
public static final int ACTION_DRAG_ENTERED = 5;
public static final int ACTION_DRAG_EXITED = 6;
/* hide the constructor behind package scope */
private DragEvent() {
}
static DragEvent obtain() {
return DragEvent.obtain(0, 0f, 0f, null, null);
}
public static DragEvent obtain(int action, float x, float y,
ClipDescription description, ClipData data) {
final DragEvent ev;
synchronized (gRecyclerLock) {
if (gRecyclerTop == null) {
return new DragEvent();
}
ev = gRecyclerTop;
gRecyclerTop = ev.mNext;
gRecyclerUsed -= 1;
}
ev.mRecycledLocation = null;
ev.mRecycled = false;
ev.mNext = null;
ev.mAction = action;
ev.mX = x;
ev.mY = y;
ev.mClipDescription = description;
ev.mClipData = data;
return ev;
}
public static DragEvent obtain(DragEvent source) {
return obtain(source.mAction, source.mX, source.mY,
source.mClipDescription, source.mClipData);
}
public int getAction() {
return mAction;
}
public float getX() {
return mX;
}
public float getY() {
return mY;
}
public ClipData getClipData() {
return mClipData;
}
public ClipDescription getClipDescription() {
return mClipDescription;
}
/**
* Recycle the DragEvent, to be re-used by a later caller. After calling
* this function you must never touch the event again.
*/
public final void recycle() {
// Ensure recycle is only called once!
if (TRACK_RECYCLED_LOCATION) {
if (mRecycledLocation != null) {
throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation);
}
mRecycledLocation = new RuntimeException("Last recycled here");
} else {
if (mRecycled) {
throw new RuntimeException(toString() + " recycled twice!");
}
mRecycled = true;
}
mClipData = null;
mClipDescription = null;
synchronized (gRecyclerLock) {
if (gRecyclerUsed < MAX_RECYCLED) {
gRecyclerUsed++;
mNext = gRecyclerTop;
gRecyclerTop = this;
}
}
}
@Override
public String toString() {
return "DragEvent{" + Integer.toHexString(System.identityHashCode(this))
+ " action=" + mAction + " @ (" + mX + ", " + mY + ") desc=" + mClipDescription
+ " data=" + mClipData
+ "}";
}
/* Parcelable interface */
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mAction);
dest.writeFloat(mX);
dest.writeFloat(mY);
if (mClipData == null) {
dest.writeInt(0);
} else {
dest.writeInt(1);
mClipData.writeToParcel(dest, flags);
}
if (mClipDescription == null) {
dest.writeInt(0);
} else {
dest.writeInt(1);
mClipDescription.writeToParcel(dest, flags);
}
}
public static final Parcelable.Creator<DragEvent> CREATOR =
new Parcelable.Creator<DragEvent>() {
public DragEvent createFromParcel(Parcel in) {
DragEvent event = DragEvent.obtain();
event.mAction = in.readInt();
event.mX = in.readFloat();
event.mY = in.readFloat();
if (in.readInt() != 0) {
event.mClipData = ClipData.CREATOR.createFromParcel(in);
}
if (in.readInt() != 0) {
event.mClipDescription = ClipDescription.CREATOR.createFromParcel(in);
}
return event;
}
public DragEvent[] newArray(int size) {
return new DragEvent[size];
}
};
}
|