summaryrefslogtreecommitdiff
path: root/core/java/android/view/MotionEvent.java
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2010-06-16 01:53:36 -0700
committerJeff Brown <jeffbrown@google.com>2010-06-17 13:27:16 -0700
commit5c225b1680e696ae8bbf505a1997d6f720672f74 (patch)
tree932326fd02ee91d8a64adfcc9415027646c56563 /core/java/android/view/MotionEvent.java
parent3a0146cd29fae3c5bc29d8d535d67826284f8cc9 (diff)
Even more native input dispatch work in progress.
Added more tests. Fixed a regression in Vector. Fixed bugs in pointer tracking. Fixed a starvation issue in PollLoop when setting or removing callbacks. Fixed a couple of policy nits. Modified the internal representation of MotionEvent to be more efficient and more consistent. Added code to skip/cancel virtual key processing when there are multiple pointers down. This helps to better disambiguate virtual key presses from stray touches (such as cheek presses). Change-Id: I2a7d2cce0195afb9125b23378baa94fd2fc6671c
Diffstat (limited to 'core/java/android/view/MotionEvent.java')
-rw-r--r--core/java/android/view/MotionEvent.java593
1 files changed, 244 insertions, 349 deletions
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 1f0619141b42..ae8c21dd666b 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -27,6 +27,7 @@ import android.util.Log;
* it is being used for.
*/
public final class MotionEvent implements Parcelable {
+ private static final long MS_PER_NS = 1000000;
static final boolean DEBUG_POINTERS = false;
/**
@@ -218,31 +219,32 @@ public final class MotionEvent implements Parcelable {
static private int gRecyclerUsed = 0;
static private MotionEvent gRecyclerTop = null;
- private long mDownTime;
- private long mEventTimeNano;
+ private long mDownTimeNano;
private int mAction;
- private float mRawX;
- private float mRawY;
+ private float mXOffset;
+ private float mYOffset;
private float mXPrecision;
private float mYPrecision;
private int mDeviceId;
private int mEdgeFlags;
private int mMetaState;
- // Here is the actual event data. Note that the order of the array
- // is a little odd: the first entry is the most recent, and the ones
- // following it are the historical data from oldest to newest. This
- // allows us to easily retrieve the most recent data, without having
- // to copy the arrays every time a new sample is added.
-
private int mNumPointers;
private int mNumSamples;
+
+ private int mLastDataSampleIndex;
+ private int mLastEventTimeNanoSampleIndex;
+
// Array of mNumPointers size of identifiers for each pointer of data.
private int[] mPointerIdentifiers;
+
// Array of (mNumSamples * mNumPointers * NUM_SAMPLE_DATA) size of event data.
+ // Samples are ordered from oldest to newest.
private float[] mDataSamples;
- // Array of mNumSamples size of time stamps.
- private long[] mTimeSamples;
+
+ // Array of mNumSamples size of event time stamps in nanoseconds.
+ // Samples are ordered from oldest to newest.
+ private long[] mEventTimeNanoSamples;
private MotionEvent mNext;
private RuntimeException mRecycledLocation;
@@ -251,26 +253,9 @@ public final class MotionEvent implements Parcelable {
private MotionEvent(int pointerCount, int sampleCount) {
mPointerIdentifiers = new int[pointerCount];
mDataSamples = new float[pointerCount * sampleCount * NUM_SAMPLE_DATA];
- mTimeSamples = new long[sampleCount];
+ mEventTimeNanoSamples = new long[sampleCount];
}
- static private MotionEvent obtain() {
- final MotionEvent ev;
- synchronized (gRecyclerLock) {
- if (gRecyclerTop == null) {
- return new MotionEvent(BASE_AVAIL_POINTERS, BASE_AVAIL_SAMPLES);
- }
- ev = gRecyclerTop;
- gRecyclerTop = ev.mNext;
- gRecyclerUsed--;
- }
- ev.mRecycledLocation = null;
- ev.mRecycled = false;
- ev.mNext = null;
- return ev;
- }
-
- @SuppressWarnings("unused") // used by native code
static private MotionEvent obtain(int pointerCount, int sampleCount) {
final MotionEvent ev;
synchronized (gRecyclerLock) {
@@ -285,7 +270,7 @@ public final class MotionEvent implements Parcelable {
}
ev = gRecyclerTop;
gRecyclerTop = ev.mNext;
- gRecyclerUsed--;
+ gRecyclerUsed -= 1;
}
ev.mRecycledLocation = null;
ev.mRecycled = false;
@@ -295,20 +280,18 @@ public final class MotionEvent implements Parcelable {
ev.mPointerIdentifiers = new int[pointerCount];
}
- final int timeSamplesLength = ev.mTimeSamples.length;
- if (timeSamplesLength < sampleCount) {
- ev.mTimeSamples = new long[sampleCount];
+ if (ev.mEventTimeNanoSamples.length < sampleCount) {
+ ev.mEventTimeNanoSamples = new long[sampleCount];
}
- final int dataSamplesLength = ev.mDataSamples.length;
final int neededDataSamplesLength = pointerCount * sampleCount * NUM_SAMPLE_DATA;
- if (dataSamplesLength < neededDataSamplesLength) {
+ if (ev.mDataSamples.length < neededDataSamplesLength) {
ev.mDataSamples = new float[neededDataSamplesLength];
}
return ev;
}
-
+
/**
* Create a new MotionEvent, filling in all of the basic values that
* define the motion.
@@ -342,45 +325,39 @@ public final class MotionEvent implements Parcelable {
static public MotionEvent obtainNano(long downTime, long eventTime, long eventTimeNano,
int action, int pointers, int[] inPointerIds, float[] inData, int metaState,
float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
- MotionEvent ev = obtain();
+ MotionEvent ev = obtain(pointers, 1);
ev.mDeviceId = deviceId;
ev.mEdgeFlags = edgeFlags;
- ev.mDownTime = downTime;
- ev.mEventTimeNano = eventTimeNano;
+ ev.mDownTimeNano = downTime * MS_PER_NS;
ev.mAction = action;
ev.mMetaState = metaState;
- ev.mRawX = inData[SAMPLE_X];
- ev.mRawY = inData[SAMPLE_Y];
+ ev.mXOffset = 0;
+ ev.mYOffset = 0;
ev.mXPrecision = xPrecision;
ev.mYPrecision = yPrecision;
+
ev.mNumPointers = pointers;
ev.mNumSamples = 1;
- int[] pointerIdentifiers = ev.mPointerIdentifiers;
- if (pointerIdentifiers.length < pointers) {
- ev.mPointerIdentifiers = pointerIdentifiers = new int[pointers];
- }
- System.arraycopy(inPointerIds, 0, pointerIdentifiers, 0, pointers);
+ ev.mLastDataSampleIndex = 0;
+ ev.mLastEventTimeNanoSampleIndex = 0;
- final int ND = pointers * NUM_SAMPLE_DATA;
- float[] dataSamples = ev.mDataSamples;
- if (dataSamples.length < ND) {
- ev.mDataSamples = dataSamples = new float[ND];
- }
- System.arraycopy(inData, 0, dataSamples, 0, ND);
+ System.arraycopy(inPointerIds, 0, ev.mPointerIdentifiers, 0, pointers);
- ev.mTimeSamples[0] = eventTime;
+ ev.mEventTimeNanoSamples[0] = eventTimeNano;
+
+ System.arraycopy(inData, 0, ev.mDataSamples, 0, pointers * NUM_SAMPLE_DATA);
if (DEBUG_POINTERS) {
StringBuilder sb = new StringBuilder(128);
sb.append("New:");
- for (int i=0; i<pointers; i++) {
+ for (int i = 0; i < pointers; i++) {
sb.append(" #");
- sb.append(ev.mPointerIdentifiers[i]);
+ sb.append(ev.getPointerId(i));
sb.append("(");
- sb.append(ev.mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_X]);
+ sb.append(ev.getX(i));
sb.append(",");
- sb.append(ev.mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_Y]);
+ sb.append(ev.getY(i));
sb.append(")");
}
Log.v("MotionEvent", sb.toString());
@@ -423,27 +400,32 @@ public final class MotionEvent implements Parcelable {
static public MotionEvent obtain(long downTime, long eventTime, int action,
float x, float y, float pressure, float size, int metaState,
float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
- MotionEvent ev = obtain();
+ MotionEvent ev = obtain(1, 1);
ev.mDeviceId = deviceId;
ev.mEdgeFlags = edgeFlags;
- ev.mDownTime = downTime;
- ev.mEventTimeNano = eventTime * 1000000;
+ ev.mDownTimeNano = downTime * MS_PER_NS;
ev.mAction = action;
ev.mMetaState = metaState;
+ ev.mXOffset = 0;
+ ev.mYOffset = 0;
ev.mXPrecision = xPrecision;
ev.mYPrecision = yPrecision;
-
+
ev.mNumPointers = 1;
ev.mNumSamples = 1;
- int[] pointerIds = ev.mPointerIdentifiers;
- pointerIds[0] = 0;
- float[] data = ev.mDataSamples;
- data[SAMPLE_X] = ev.mRawX = x;
- data[SAMPLE_Y] = ev.mRawY = y;
- data[SAMPLE_PRESSURE] = pressure;
- data[SAMPLE_SIZE] = size;
- ev.mTimeSamples[0] = eventTime;
-
+
+ ev.mLastDataSampleIndex = 0;
+ ev.mLastEventTimeNanoSampleIndex = 0;
+
+ ev.mPointerIdentifiers[0] = 0;
+
+ ev.mEventTimeNanoSamples[0] = eventTime * MS_PER_NS;
+
+ float[] dataSamples = ev.mDataSamples;
+ dataSamples[SAMPLE_X] = x;
+ dataSamples[SAMPLE_Y] = y;
+ dataSamples[SAMPLE_PRESSURE] = pressure;
+ dataSamples[SAMPLE_SIZE] = size;
return ev;
}
@@ -478,33 +460,16 @@ public final class MotionEvent implements Parcelable {
* numbers are arbitrary and you shouldn't depend on the values.
* @param edgeFlags A bitfield indicating which edges, if any, where touched by this
* MotionEvent.
+ *
+ * @deprecated Use {@link #obtain(long, long, int, float, float, float, float, int, float, float, int, int)}
+ * instead.
*/
+ @Deprecated
static public MotionEvent obtain(long downTime, long eventTime, int action,
int pointers, float x, float y, float pressure, float size, int metaState,
float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
- MotionEvent ev = obtain();
- ev.mDeviceId = deviceId;
- ev.mEdgeFlags = edgeFlags;
- ev.mDownTime = downTime;
- ev.mEventTimeNano = eventTime * 1000000;
- ev.mAction = action;
- ev.mNumPointers = pointers;
- ev.mMetaState = metaState;
- ev.mXPrecision = xPrecision;
- ev.mYPrecision = yPrecision;
-
- ev.mNumPointers = 1;
- ev.mNumSamples = 1;
- int[] pointerIds = ev.mPointerIdentifiers;
- pointerIds[0] = 0;
- float[] data = ev.mDataSamples;
- data[SAMPLE_X] = ev.mRawX = x;
- data[SAMPLE_Y] = ev.mRawY = y;
- data[SAMPLE_PRESSURE] = pressure;
- data[SAMPLE_SIZE] = size;
- ev.mTimeSamples[0] = eventTime;
-
- return ev;
+ return obtain(downTime, eventTime, action, x, y, pressure, size,
+ metaState, xPrecision, yPrecision, deviceId, edgeFlags);
}
/**
@@ -526,89 +491,36 @@ public final class MotionEvent implements Parcelable {
*/
static public MotionEvent obtain(long downTime, long eventTime, int action,
float x, float y, int metaState) {
- MotionEvent ev = obtain();
- ev.mDeviceId = 0;
- ev.mEdgeFlags = 0;
- ev.mDownTime = downTime;
- ev.mEventTimeNano = eventTime * 1000000;
- ev.mAction = action;
- ev.mNumPointers = 1;
- ev.mMetaState = metaState;
- ev.mXPrecision = 1.0f;
- ev.mYPrecision = 1.0f;
-
- ev.mNumPointers = 1;
- ev.mNumSamples = 1;
- int[] pointerIds = ev.mPointerIdentifiers;
- pointerIds[0] = 0;
- float[] data = ev.mDataSamples;
- data[SAMPLE_X] = ev.mRawX = x;
- data[SAMPLE_Y] = ev.mRawY = y;
- data[SAMPLE_PRESSURE] = 1.0f;
- data[SAMPLE_SIZE] = 1.0f;
- ev.mTimeSamples[0] = eventTime;
-
- return ev;
- }
-
- /**
- * Scales down the coordination of this event by the given scale.
- *
- * @hide
- */
- public void scale(float scale) {
- mRawX *= scale;
- mRawY *= scale;
- mXPrecision *= scale;
- mYPrecision *= scale;
- float[] history = mDataSamples;
- final int length = mNumPointers * mNumSamples * NUM_SAMPLE_DATA;
- for (int i = 0; i < length; i += NUM_SAMPLE_DATA) {
- history[i + SAMPLE_X] *= scale;
- history[i + SAMPLE_Y] *= scale;
- // no need to scale pressure
- history[i + SAMPLE_SIZE] *= scale; // TODO: square this?
- }
+ return obtain(downTime, eventTime, action, x, y, 1.0f, 1.0f,
+ metaState, 1.0f, 1.0f, 0, 0);
}
/**
* Create a new MotionEvent, copying from an existing one.
*/
static public MotionEvent obtain(MotionEvent o) {
- MotionEvent ev = obtain();
+ MotionEvent ev = obtain(o.mNumPointers, o.mNumSamples);
ev.mDeviceId = o.mDeviceId;
ev.mEdgeFlags = o.mEdgeFlags;
- ev.mDownTime = o.mDownTime;
- ev.mEventTimeNano = o.mEventTimeNano;
+ ev.mDownTimeNano = o.mDownTimeNano;
ev.mAction = o.mAction;
- ev.mNumPointers = o.mNumPointers;
- ev.mRawX = o.mRawX;
- ev.mRawY = o.mRawY;
ev.mMetaState = o.mMetaState;
+ ev.mXOffset = o.mXOffset;
+ ev.mYOffset = o.mYOffset;
ev.mXPrecision = o.mXPrecision;
ev.mYPrecision = o.mYPrecision;
+ int numPointers = ev.mNumPointers = o.mNumPointers;
+ int numSamples = ev.mNumSamples = o.mNumSamples;
- final int NS = ev.mNumSamples = o.mNumSamples;
- if (ev.mTimeSamples.length >= NS) {
- System.arraycopy(o.mTimeSamples, 0, ev.mTimeSamples, 0, NS);
- } else {
- ev.mTimeSamples = (long[])o.mTimeSamples.clone();
- }
+ ev.mLastDataSampleIndex = o.mLastDataSampleIndex;
+ ev.mLastEventTimeNanoSampleIndex = o.mLastEventTimeNanoSampleIndex;
- final int NP = (ev.mNumPointers=o.mNumPointers);
- if (ev.mPointerIdentifiers.length >= NP) {
- System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, NP);
- } else {
- ev.mPointerIdentifiers = (int[])o.mPointerIdentifiers.clone();
- }
+ System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, numPointers);
- final int ND = NP * NS * NUM_SAMPLE_DATA;
- if (ev.mDataSamples.length >= ND) {
- System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0, ND);
- } else {
- ev.mDataSamples = (float[])o.mDataSamples.clone();
- }
+ System.arraycopy(o.mEventTimeNanoSamples, 0, ev.mEventTimeNanoSamples, 0, numSamples);
+ System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0,
+ numPointers * numSamples * NUM_SAMPLE_DATA);
return ev;
}
@@ -617,36 +529,29 @@ public final class MotionEvent implements Parcelable {
* any historical point information.
*/
static public MotionEvent obtainNoHistory(MotionEvent o) {
- MotionEvent ev = obtain();
+ MotionEvent ev = obtain(o.mNumPointers, 1);
ev.mDeviceId = o.mDeviceId;
ev.mEdgeFlags = o.mEdgeFlags;
- ev.mDownTime = o.mDownTime;
- ev.mEventTimeNano = o.mEventTimeNano;
+ ev.mDownTimeNano = o.mDownTimeNano;
ev.mAction = o.mAction;
- ev.mNumPointers = o.mNumPointers;
- ev.mRawX = o.mRawX;
- ev.mRawY = o.mRawY;
ev.mMetaState = o.mMetaState;
+ ev.mXOffset = o.mXOffset;
+ ev.mYOffset = o.mYOffset;
ev.mXPrecision = o.mXPrecision;
ev.mYPrecision = o.mYPrecision;
+ int numPointers = ev.mNumPointers = o.mNumPointers;
ev.mNumSamples = 1;
- ev.mTimeSamples[0] = o.mTimeSamples[0];
- final int NP = (ev.mNumPointers=o.mNumPointers);
- if (ev.mPointerIdentifiers.length >= NP) {
- System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, NP);
- } else {
- ev.mPointerIdentifiers = (int[])o.mPointerIdentifiers.clone();
- }
+ ev.mLastDataSampleIndex = 0;
+ ev.mLastEventTimeNanoSampleIndex = 0;
- final int ND = NP * NUM_SAMPLE_DATA;
- if (ev.mDataSamples.length >= ND) {
- System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0, ND);
- } else {
- ev.mDataSamples = (float[])o.mDataSamples.clone();
- }
+ System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, numPointers);
+ ev.mEventTimeNanoSamples[0] = o.mEventTimeNanoSamples[o.mLastEventTimeNanoSampleIndex];
+
+ System.arraycopy(o.mDataSamples, o.mLastDataSampleIndex, ev.mDataSamples, 0,
+ numPointers * NUM_SAMPLE_DATA);
return ev;
}
@@ -654,7 +559,7 @@ public final class MotionEvent implements Parcelable {
* Recycle the MotionEvent, to be re-used by a later caller. After calling
* this function you must not ever touch the event again.
*/
- public void recycle() {
+ public final void recycle() {
// Ensure recycle is only called once!
if (TRACK_RECYCLED_LOCATION) {
if (mRecycledLocation != null) {
@@ -678,6 +583,27 @@ public final class MotionEvent implements Parcelable {
}
}
}
+
+ /**
+ * Scales down the coordination of this event by the given scale.
+ *
+ * @hide
+ */
+ public final void scale(float scale) {
+ mXOffset *= scale;
+ mYOffset *= scale;
+ mXPrecision *= scale;
+ mYPrecision *= scale;
+
+ float[] history = mDataSamples;
+ final int length = mNumPointers * mNumSamples * NUM_SAMPLE_DATA;
+ for (int i = 0; i < length; i += NUM_SAMPLE_DATA) {
+ history[i + SAMPLE_X] *= scale;
+ history[i + SAMPLE_Y] *= scale;
+ // no need to scale pressure
+ history[i + SAMPLE_SIZE] *= scale; // TODO: square this?
+ }
+ }
/**
* Return the kind of action being performed -- one of either
@@ -719,14 +645,14 @@ public final class MotionEvent implements Parcelable {
* a stream of position events.
*/
public final long getDownTime() {
- return mDownTime;
+ return mDownTimeNano / MS_PER_NS;
}
/**
* Returns the time (in ms) when this specific event was generated.
*/
public final long getEventTime() {
- return mTimeSamples[0];
+ return mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] / MS_PER_NS;
}
/**
@@ -736,7 +662,7 @@ public final class MotionEvent implements Parcelable {
* @hide
*/
public final long getEventTimeNano() {
- return mEventTimeNano;
+ return mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex];
}
/**
@@ -744,7 +670,7 @@ public final class MotionEvent implements Parcelable {
* arbitrary pointer identifier).
*/
public final float getX() {
- return mDataSamples[SAMPLE_X];
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_X] + mXOffset;
}
/**
@@ -752,7 +678,7 @@ public final class MotionEvent implements Parcelable {
* arbitrary pointer identifier).
*/
public final float getY() {
- return mDataSamples[SAMPLE_Y];
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_Y] + mYOffset;
}
/**
@@ -760,7 +686,7 @@ public final class MotionEvent implements Parcelable {
* arbitrary pointer identifier).
*/
public final float getPressure() {
- return mDataSamples[SAMPLE_PRESSURE];
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_PRESSURE];
}
/**
@@ -768,7 +694,7 @@ public final class MotionEvent implements Parcelable {
* arbitrary pointer identifier).
*/
public final float getSize() {
- return mDataSamples[SAMPLE_SIZE];
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_SIZE];
}
/**
@@ -820,7 +746,8 @@ public final class MotionEvent implements Parcelable {
* (the first pointer that is down) to {@link #getPointerCount()}-1.
*/
public final float getX(int pointerIndex) {
- return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_X];
+ return mDataSamples[mLastDataSampleIndex
+ + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_X] + mXOffset;
}
/**
@@ -833,7 +760,8 @@ public final class MotionEvent implements Parcelable {
* (the first pointer that is down) to {@link #getPointerCount()}-1.
*/
public final float getY(int pointerIndex) {
- return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_Y];
+ return mDataSamples[mLastDataSampleIndex
+ + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_Y] + mYOffset;
}
/**
@@ -848,7 +776,8 @@ public final class MotionEvent implements Parcelable {
* (the first pointer that is down) to {@link #getPointerCount()}-1.
*/
public final float getPressure(int pointerIndex) {
- return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_PRESSURE];
+ return mDataSamples[mLastDataSampleIndex
+ + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_PRESSURE];
}
/**
@@ -864,7 +793,8 @@ public final class MotionEvent implements Parcelable {
* (the first pointer that is down) to {@link #getPointerCount()}-1.
*/
public final float getSize(int pointerIndex) {
- return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_SIZE];
+ return mDataSamples[mLastDataSampleIndex
+ + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_SIZE];
}
/**
@@ -888,7 +818,7 @@ public final class MotionEvent implements Parcelable {
* and views.
*/
public final float getRawX() {
- return mRawX;
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_X];
}
/**
@@ -898,7 +828,7 @@ public final class MotionEvent implements Parcelable {
* and views.
*/
public final float getRawY() {
- return mRawY;
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_Y];
}
/**
@@ -930,7 +860,7 @@ public final class MotionEvent implements Parcelable {
* @return Returns the number of historical points in the event.
*/
public final int getHistorySize() {
- return mNumSamples - 1;
+ return mLastEventTimeNanoSampleIndex;
}
/**
@@ -944,7 +874,7 @@ public final class MotionEvent implements Parcelable {
* @see #getEventTime
*/
public final long getHistoricalEventTime(int pos) {
- return mTimeSamples[pos + 1];
+ return mEventTimeNanoSamples[pos] / MS_PER_NS;
}
/**
@@ -952,7 +882,7 @@ public final class MotionEvent implements Parcelable {
* arbitrary pointer identifier).
*/
public final float getHistoricalX(int pos) {
- return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_X];
+ return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_X] + mXOffset;
}
/**
@@ -960,7 +890,7 @@ public final class MotionEvent implements Parcelable {
* arbitrary pointer identifier).
*/
public final float getHistoricalY(int pos) {
- return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_Y];
+ return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_Y] + mYOffset;
}
/**
@@ -968,7 +898,7 @@ public final class MotionEvent implements Parcelable {
* arbitrary pointer identifier).
*/
public final float getHistoricalPressure(int pos) {
- return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_PRESSURE];
+ return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_PRESSURE];
}
/**
@@ -976,7 +906,7 @@ public final class MotionEvent implements Parcelable {
* arbitrary pointer identifier).
*/
public final float getHistoricalSize(int pos) {
- return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_SIZE];
+ return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_SIZE];
}
/**
@@ -993,8 +923,8 @@ public final class MotionEvent implements Parcelable {
* @see #getX
*/
public final float getHistoricalX(int pointerIndex, int pos) {
- return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
- + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_X];
+ return mDataSamples[(pos * mNumPointers + pointerIndex)
+ * NUM_SAMPLE_DATA + SAMPLE_X] + mXOffset;
}
/**
@@ -1011,8 +941,8 @@ public final class MotionEvent implements Parcelable {
* @see #getY
*/
public final float getHistoricalY(int pointerIndex, int pos) {
- return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
- + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_Y];
+ return mDataSamples[(pos * mNumPointers + pointerIndex)
+ * NUM_SAMPLE_DATA + SAMPLE_Y] + mYOffset;
}
/**
@@ -1029,8 +959,8 @@ public final class MotionEvent implements Parcelable {
* @see #getPressure
*/
public final float getHistoricalPressure(int pointerIndex, int pos) {
- return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
- + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_PRESSURE];
+ return mDataSamples[(pos * mNumPointers + pointerIndex)
+ * NUM_SAMPLE_DATA + SAMPLE_PRESSURE];
}
/**
@@ -1047,8 +977,8 @@ public final class MotionEvent implements Parcelable {
* @see #getSize
*/
public final float getHistoricalSize(int pointerIndex, int pos) {
- return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
- + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_SIZE];
+ return mDataSamples[(pos * mNumPointers + pointerIndex)
+ * NUM_SAMPLE_DATA + SAMPLE_SIZE];
}
/**
@@ -1098,12 +1028,8 @@ public final class MotionEvent implements Parcelable {
* @param deltaY Amount to add to the current Y coordinate of the event.
*/
public final void offsetLocation(float deltaX, float deltaY) {
- final int N = mNumPointers*mNumSamples*4;
- final float[] pos = mDataSamples;
- for (int i=0; i<N; i+=NUM_SAMPLE_DATA) {
- pos[i+SAMPLE_X] += deltaX;
- pos[i+SAMPLE_Y] += deltaY;
- }
+ mXOffset += deltaX;
+ mYOffset += deltaY;
}
/**
@@ -1114,11 +1040,28 @@ public final class MotionEvent implements Parcelable {
* @param y New absolute Y location.
*/
public final void setLocation(float x, float y) {
- float deltaX = x-mDataSamples[SAMPLE_X];
- float deltaY = y-mDataSamples[SAMPLE_Y];
- if (deltaX != 0 || deltaY != 0) {
- offsetLocation(deltaX, deltaY);
+ mXOffset = x - mDataSamples[mLastDataSampleIndex + SAMPLE_X];
+ mYOffset = y - mDataSamples[mLastDataSampleIndex + SAMPLE_Y];
+ }
+
+ private final void incrementNumSamplesAndReserveStorage(int dataSampleStride) {
+ if (mNumSamples == mEventTimeNanoSamples.length) {
+ long[] newEventTimeNanoSamples = new long[mNumSamples + BASE_AVAIL_SAMPLES];
+ System.arraycopy(mEventTimeNanoSamples, 0, newEventTimeNanoSamples, 0, mNumSamples);
+ mEventTimeNanoSamples = newEventTimeNanoSamples;
}
+
+ int nextDataSampleIndex = mLastDataSampleIndex + dataSampleStride;
+ if (nextDataSampleIndex + dataSampleStride > mDataSamples.length) {
+ float[] newDataSamples = new float[nextDataSampleIndex
+ + BASE_AVAIL_SAMPLES * dataSampleStride];
+ System.arraycopy(mDataSamples, 0, newDataSamples, 0, nextDataSampleIndex);
+ mDataSamples = newDataSamples;
+ }
+
+ mLastEventTimeNanoSampleIndex = mNumSamples;
+ mLastDataSampleIndex = nextDataSampleIndex;
+ mNumSamples += 1;
}
/**
@@ -1136,42 +1079,16 @@ public final class MotionEvent implements Parcelable {
*/
public final void addBatch(long eventTime, float x, float y,
float pressure, float size, int metaState) {
- float[] data = mDataSamples;
- long[] times = mTimeSamples;
+ incrementNumSamplesAndReserveStorage(NUM_SAMPLE_DATA);
- final int NP = mNumPointers;
- final int NS = mNumSamples;
- final int NI = NP*NS;
- final int ND = NI * NUM_SAMPLE_DATA;
- if (data.length <= ND) {
- final int NEW_ND = ND + (NP * (BASE_AVAIL_SAMPLES * NUM_SAMPLE_DATA));
- float[] newData = new float[NEW_ND];
- System.arraycopy(data, 0, newData, 0, ND);
- mDataSamples = data = newData;
- }
- if (times.length <= NS) {
- final int NEW_NS = NS + BASE_AVAIL_SAMPLES;
- long[] newHistoryTimes = new long[NEW_NS];
- System.arraycopy(times, 0, newHistoryTimes, 0, NS);
- mTimeSamples = times = newHistoryTimes;
- }
+ mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] = eventTime * MS_PER_NS;
- times[NS] = times[0];
- times[0] = eventTime;
+ float[] dataSamples = mDataSamples;
+ dataSamples[mLastDataSampleIndex + SAMPLE_X] = x - mXOffset;
+ dataSamples[mLastDataSampleIndex + SAMPLE_Y] = y - mYOffset;
+ dataSamples[mLastDataSampleIndex + SAMPLE_PRESSURE] = pressure;
+ dataSamples[mLastDataSampleIndex + SAMPLE_SIZE] = size;
- final int pos = NS*NUM_SAMPLE_DATA;
- data[pos+SAMPLE_X] = data[SAMPLE_X];
- data[pos+SAMPLE_Y] = data[SAMPLE_Y];
- data[pos+SAMPLE_PRESSURE] = data[SAMPLE_PRESSURE];
- data[pos+SAMPLE_SIZE] = data[SAMPLE_SIZE];
- data[SAMPLE_X] = x;
- data[SAMPLE_Y] = y;
- data[SAMPLE_PRESSURE] = pressure;
- data[SAMPLE_SIZE] = size;
- mNumSamples = NS+1;
-
- mRawX = x;
- mRawY = y;
mMetaState |= metaState;
}
@@ -1187,48 +1104,36 @@ public final class MotionEvent implements Parcelable {
* @hide
*/
public final void addBatch(long eventTime, float[] inData, int metaState) {
- float[] data = mDataSamples;
- long[] times = mTimeSamples;
+ final int numPointers = mNumPointers;
+ final int dataSampleStride = numPointers * NUM_SAMPLE_DATA;
+ incrementNumSamplesAndReserveStorage(dataSampleStride);
- final int NP = mNumPointers;
- final int NS = mNumSamples;
- final int NI = NP*NS;
- final int ND = NI * NUM_SAMPLE_DATA;
- if (data.length < (ND+(NP*NUM_SAMPLE_DATA))) {
- final int NEW_ND = ND + (NP * (BASE_AVAIL_SAMPLES * NUM_SAMPLE_DATA));
- float[] newData = new float[NEW_ND];
- System.arraycopy(data, 0, newData, 0, ND);
- mDataSamples = data = newData;
- }
- if (times.length < (NS+1)) {
- final int NEW_NS = NS + BASE_AVAIL_SAMPLES;
- long[] newHistoryTimes = new long[NEW_NS];
- System.arraycopy(times, 0, newHistoryTimes, 0, NS);
- mTimeSamples = times = newHistoryTimes;
- }
-
- times[NS] = times[0];
- times[0] = eventTime;
+ mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] = eventTime * MS_PER_NS;
- System.arraycopy(data, 0, data, ND, mNumPointers*NUM_SAMPLE_DATA);
- System.arraycopy(inData, 0, data, 0, mNumPointers*NUM_SAMPLE_DATA);
+ float[] dataSamples = mDataSamples;
+ System.arraycopy(inData, 0, dataSamples, mLastDataSampleIndex, dataSampleStride);
+
+ if (mXOffset != 0 || mYOffset != 0) {
+ int index = mLastEventTimeNanoSampleIndex;
+ for (int i = 0; i < numPointers; i++) {
+ dataSamples[index + SAMPLE_X] -= mXOffset;
+ dataSamples[index + SAMPLE_Y] -= mYOffset;
+ index += NUM_SAMPLE_DATA;
+ }
+ }
- mNumSamples = NS+1;
-
- mRawX = inData[SAMPLE_X];
- mRawY = inData[SAMPLE_Y];
mMetaState |= metaState;
if (DEBUG_POINTERS) {
StringBuilder sb = new StringBuilder(128);
sb.append("Add:");
- for (int i=0; i<mNumPointers; i++) {
+ for (int i = 0; i < mNumPointers; i++) {
sb.append(" #");
- sb.append(mPointerIdentifiers[i]);
+ sb.append(getPointerId(i));
sb.append("(");
- sb.append(mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_X]);
+ sb.append(getX(i));
sb.append(",");
- sb.append(mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_Y]);
+ sb.append(getY(i));
sb.append(")");
}
Log.v("MotionEvent", sb.toString());
@@ -1245,8 +1150,41 @@ public final class MotionEvent implements Parcelable {
public static final Parcelable.Creator<MotionEvent> CREATOR
= new Parcelable.Creator<MotionEvent>() {
public MotionEvent createFromParcel(Parcel in) {
- MotionEvent ev = obtain();
- ev.readFromParcel(in);
+ final int NP = in.readInt();
+ final int NS = in.readInt();
+ final int NI = NP * NS * NUM_SAMPLE_DATA;
+
+ MotionEvent ev = obtain(NP, NS);
+ ev.mNumPointers = NP;
+ ev.mNumSamples = NS;
+
+ ev.mDownTimeNano = in.readLong();
+ ev.mAction = in.readInt();
+ ev.mXOffset = in.readFloat();
+ ev.mYOffset = in.readFloat();
+ ev.mXPrecision = in.readFloat();
+ ev.mYPrecision = in.readFloat();
+ ev.mDeviceId = in.readInt();
+ ev.mEdgeFlags = in.readInt();
+ ev.mMetaState = in.readInt();
+
+ final int[] pointerIdentifiers = ev.mPointerIdentifiers;
+ for (int i = 0; i < NP; i++) {
+ pointerIdentifiers[i] = in.readInt();
+ }
+
+ final long[] eventTimeNanoSamples = ev.mEventTimeNanoSamples;
+ for (int i = 0; i < NS; i++) {
+ eventTimeNanoSamples[i] = in.readLong();
+ }
+
+ final float[] dataSamples = ev.mDataSamples;
+ for (int i = 0; i < NI; i++) {
+ dataSamples[i] = in.readFloat();
+ }
+
+ ev.mLastEventTimeNanoSampleIndex = NS - 1;
+ ev.mLastDataSampleIndex = (NS - 1) * NP * NUM_SAMPLE_DATA;
return ev;
}
@@ -1260,79 +1198,36 @@ public final class MotionEvent implements Parcelable {
}
public void writeToParcel(Parcel out, int flags) {
- out.writeLong(mDownTime);
- out.writeLong(mEventTimeNano);
- out.writeInt(mAction);
- out.writeInt(mMetaState);
- out.writeFloat(mRawX);
- out.writeFloat(mRawY);
final int NP = mNumPointers;
- out.writeInt(NP);
final int NS = mNumSamples;
+ final int NI = NP * NS * NUM_SAMPLE_DATA;
+
+ out.writeInt(NP);
out.writeInt(NS);
- final int NI = NP*NS;
- if (NI > 0) {
- int i;
- int[] state = mPointerIdentifiers;
- for (i=0; i<NP; i++) {
- out.writeInt(state[i]);
- }
- final int ND = NI*NUM_SAMPLE_DATA;
- float[] history = mDataSamples;
- for (i=0; i<ND; i++) {
- out.writeFloat(history[i]);
- }
- long[] times = mTimeSamples;
- for (i=0; i<NS; i++) {
- out.writeLong(times[i]);
- }
- }
+
+ out.writeLong(mDownTimeNano);
+ out.writeInt(mAction);
+ out.writeFloat(mXOffset);
+ out.writeFloat(mYOffset);
out.writeFloat(mXPrecision);
out.writeFloat(mYPrecision);
out.writeInt(mDeviceId);
out.writeInt(mEdgeFlags);
- }
+ out.writeInt(mMetaState);
+
+ final int[] pointerIdentifiers = mPointerIdentifiers;
+ for (int i = 0; i < NP; i++) {
+ out.writeInt(pointerIdentifiers[i]);
+ }
+
+ final long[] eventTimeNanoSamples = mEventTimeNanoSamples;
+ for (int i = 0; i < NS; i++) {
+ out.writeLong(eventTimeNanoSamples[i]);
+ }
- private void readFromParcel(Parcel in) {
- mDownTime = in.readLong();
- mEventTimeNano = in.readLong();
- mAction = in.readInt();
- mMetaState = in.readInt();
- mRawX = in.readFloat();
- mRawY = in.readFloat();
- final int NP = in.readInt();
- mNumPointers = NP;
- final int NS = in.readInt();
- mNumSamples = NS;
- final int NI = NP*NS;
- if (NI > 0) {
- int[] ids = mPointerIdentifiers;
- if (ids.length < NP) {
- mPointerIdentifiers = ids = new int[NP];
- }
- for (int i=0; i<NP; i++) {
- ids[i] = in.readInt();
- }
- float[] history = mDataSamples;
- final int ND = NI*NUM_SAMPLE_DATA;
- if (history.length < ND) {
- mDataSamples = history = new float[ND];
- }
- for (int i=0; i<ND; i++) {
- history[i] = in.readFloat();
- }
- long[] times = mTimeSamples;
- if (times == null || times.length < NS) {
- mTimeSamples = times = new long[NS];
- }
- for (int i=0; i<NS; i++) {
- times[i] = in.readLong();
- }
+ final float[] dataSamples = mDataSamples;
+ for (int i = 0; i < NI; i++) {
+ out.writeFloat(dataSamples[i]);
}
- mXPrecision = in.readFloat();
- mYPrecision = in.readFloat();
- mDeviceId = in.readInt();
- mEdgeFlags = in.readInt();
}
-
}