summaryrefslogtreecommitdiffstats
path: root/core/jni/android_view_MotionEvent.cpp
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/jni/android_view_MotionEvent.cpp
parent3a0146cd29fae3c5bc29d8d535d67826284f8cc9 (diff)
downloadframeworks_base-5c225b1680e696ae8bbf505a1997d6f720672f74.zip
frameworks_base-5c225b1680e696ae8bbf505a1997d6f720672f74.tar.gz
frameworks_base-5c225b1680e696ae8bbf505a1997d6f720672f74.tar.bz2
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/jni/android_view_MotionEvent.cpp')
-rw-r--r--core/jni/android_view_MotionEvent.cpp183
1 files changed, 77 insertions, 106 deletions
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index 629c8fe..78137e2 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -36,11 +36,10 @@ static struct {
jmethodID obtain;
jmethodID recycle;
- jfieldID mDownTime;
- jfieldID mEventTimeNano;
+ jfieldID mDownTimeNano;
jfieldID mAction;
- jfieldID mRawX;
- jfieldID mRawY;
+ jfieldID mXOffset;
+ jfieldID mYOffset;
jfieldID mXPrecision;
jfieldID mYPrecision;
jfieldID mDeviceId;
@@ -50,7 +49,9 @@ static struct {
jfieldID mNumSamples;
jfieldID mPointerIdentifiers;
jfieldID mDataSamples;
- jfieldID mTimeSamples;
+ jfieldID mEventTimeNanoSamples;
+ jfieldID mLastDataSampleIndex;
+ jfieldID mLastEventTimeNanoSampleIndex;
} gMotionEventClassInfo;
// ----------------------------------------------------------------------------
@@ -69,22 +70,14 @@ jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* even
return NULL;
}
- // MotionEvent.mEventTimeNano is the time of the oldest sample because
- // MotionEvent.addBatch does not update it as successive samples are added.
- jlong eventTimeNano = numHistoricalSamples != 0
- ? event->getHistoricalEventTime(0)
- : event->getEventTime();
-
- env->SetLongField(eventObj, gMotionEventClassInfo.mDownTime,
- nanoseconds_to_milliseconds(event->getDownTime()));
- env->SetLongField(eventObj, gMotionEventClassInfo.mEventTimeNano,
- eventTimeNano);
+ env->SetLongField(eventObj, gMotionEventClassInfo.mDownTimeNano,
+ event->getDownTime());
env->SetIntField(eventObj, gMotionEventClassInfo.mAction,
event->getAction());
- env->SetFloatField(eventObj, gMotionEventClassInfo.mRawX,
- event->getRawX());
- env->SetFloatField(eventObj, gMotionEventClassInfo.mRawY,
- event->getRawY());
+ env->SetFloatField(eventObj, gMotionEventClassInfo.mXOffset,
+ event->getXOffset());
+ env->SetFloatField(eventObj, gMotionEventClassInfo.mYOffset,
+ event->getYOffset());
env->SetFloatField(eventObj, gMotionEventClassInfo.mXPrecision,
event->getXPrecision());
env->SetFloatField(eventObj, gMotionEventClassInfo.mYPrecision,
@@ -99,65 +92,62 @@ jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* even
numPointers);
env->SetIntField(eventObj, gMotionEventClassInfo.mNumSamples,
numSamples);
+ env->SetIntField(eventObj, gMotionEventClassInfo.mLastDataSampleIndex,
+ (numSamples - 1) * numPointers * NUM_SAMPLE_DATA);
+ env->SetIntField(eventObj, gMotionEventClassInfo.mLastEventTimeNanoSampleIndex,
+ numSamples - 1);
jintArray pointerIdentifierArray = jintArray(env->GetObjectField(eventObj,
gMotionEventClassInfo.mPointerIdentifiers));
jfloatArray dataSampleArray = jfloatArray(env->GetObjectField(eventObj,
gMotionEventClassInfo.mDataSamples));
- jlongArray timeSampleArray = jlongArray(env->GetObjectField(eventObj,
- gMotionEventClassInfo.mTimeSamples));
+ jlongArray eventTimeNanoSampleArray = jlongArray(env->GetObjectField(eventObj,
+ gMotionEventClassInfo.mEventTimeNanoSamples));
jint* pointerIdentifiers = (jint*)env->GetPrimitiveArrayCritical(pointerIdentifierArray, NULL);
jfloat* dataSamples = (jfloat*)env->GetPrimitiveArrayCritical(dataSampleArray, NULL);
- jlong* timeSamples = (jlong*)env->GetPrimitiveArrayCritical(timeSampleArray, NULL);
+ jlong* eventTimeNanoSamples = (jlong*)env->GetPrimitiveArrayCritical(
+ eventTimeNanoSampleArray, NULL);
+ const int32_t* srcPointerIdentifiers = event->getPointerIds();
+ jint* destPointerIdentifiers = pointerIdentifiers;
for (jint i = 0; i < numPointers; i++) {
- pointerIdentifiers[i] = event->getPointerId(i);
+ *(destPointerIdentifiers++) = *(srcPointerIdentifiers++);
}
- // Most recent data is in first slot of the DVM array, followed by the oldest,
- // and then all others are in order.
-
- jfloat* currentDataSample = dataSamples;
- jlong* currentTimeSample = timeSamples;
-
- *(currentTimeSample++) = nanoseconds_to_milliseconds(event->getEventTime());
- for (jint j = 0; j < numPointers; j++) {
- *(currentDataSample++) = event->getX(j);
- *(currentDataSample++) = event->getY(j);
- *(currentDataSample++) = event->getPressure(j);
- *(currentDataSample++) = event->getSize(j);
+ const nsecs_t* srcSampleEventTimes = event->getSampleEventTimes();
+ jlong* destEventTimeNanoSamples = eventTimeNanoSamples;
+ for (jint i = 0; i < numSamples; i++) {
+ *(destEventTimeNanoSamples++) = *(srcSampleEventTimes++);
}
- for (jint i = 0; i < numHistoricalSamples; i++) {
- *(currentTimeSample++) = nanoseconds_to_milliseconds(event->getHistoricalEventTime(i));
- for (jint j = 0; j < numPointers; j++) {
- *(currentDataSample++) = event->getHistoricalX(j, i);
- *(currentDataSample++) = event->getHistoricalY(j, i);
- *(currentDataSample++) = event->getHistoricalPressure(j, i);
- *(currentDataSample++) = event->getHistoricalSize(j, i);
- }
+ const PointerCoords* srcSamplePointerCoords = event->getSamplePointerCoords();
+ jfloat* destDataSamples = dataSamples;
+ jint numItems = numSamples * numPointers;
+ for (jint i = 0; i < numItems; i++) {
+ *(destDataSamples++) = srcSamplePointerCoords->x;
+ *(destDataSamples++) = srcSamplePointerCoords->y;
+ *(destDataSamples++) = srcSamplePointerCoords->pressure;
+ *(destDataSamples++) = srcSamplePointerCoords->size;
+ srcSamplePointerCoords += 1;
}
env->ReleasePrimitiveArrayCritical(pointerIdentifierArray, pointerIdentifiers, 0);
env->ReleasePrimitiveArrayCritical(dataSampleArray, dataSamples, 0);
- env->ReleasePrimitiveArrayCritical(timeSampleArray, timeSamples, 0);
+ env->ReleasePrimitiveArrayCritical(eventTimeNanoSampleArray, eventTimeNanoSamples, 0);
env->DeleteLocalRef(pointerIdentifierArray);
env->DeleteLocalRef(dataSampleArray);
- env->DeleteLocalRef(timeSampleArray);
+ env->DeleteLocalRef(eventTimeNanoSampleArray);
return eventObj;
}
void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, int32_t nature,
MotionEvent* event) {
- // MotionEvent.mEventTimeNano is the time of the oldest sample because
- // MotionEvent.addBatch does not update it as successive samples are added.
- jlong downTime = env->GetLongField(eventObj, gMotionEventClassInfo.mDownTime);
- jlong eventTimeNano = env->GetLongField(eventObj, gMotionEventClassInfo.mEventTimeNano);
+ jlong downTimeNano = env->GetLongField(eventObj, gMotionEventClassInfo.mDownTimeNano);
jint action = env->GetIntField(eventObj, gMotionEventClassInfo.mAction);
- jfloat rawX = env->GetFloatField(eventObj, gMotionEventClassInfo.mRawX);
- jfloat rawY = env->GetFloatField(eventObj, gMotionEventClassInfo.mRawY);
+ jfloat xOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mXOffset);
+ jfloat yOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mYOffset);
jfloat xPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mXPrecision);
jfloat yPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mYPrecision);
jint deviceId = env->GetIntField(eventObj, gMotionEventClassInfo.mDeviceId);
@@ -169,72 +159,51 @@ void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, int32_t na
gMotionEventClassInfo.mPointerIdentifiers));
jfloatArray dataSampleArray = jfloatArray(env->GetObjectField(eventObj,
gMotionEventClassInfo.mDataSamples));
- jlongArray timeSampleArray = jlongArray(env->GetObjectField(eventObj,
- gMotionEventClassInfo.mTimeSamples));
+ jlongArray eventTimeNanoSampleArray = jlongArray(env->GetObjectField(eventObj,
+ gMotionEventClassInfo.mEventTimeNanoSamples));
LOG_FATAL_IF(numPointers == 0, "numPointers was zero");
LOG_FATAL_IF(numSamples == 0, "numSamples was zero");
jint* pointerIdentifiers = (jint*)env->GetPrimitiveArrayCritical(pointerIdentifierArray, NULL);
jfloat* dataSamples = (jfloat*)env->GetPrimitiveArrayCritical(dataSampleArray, NULL);
- jlong* timeSamples = (jlong*)env->GetPrimitiveArrayCritical(timeSampleArray, NULL);
-
- // Most recent data is in first slot of the DVM array, followed by the oldest,
- // and then all others are in order. eventTimeNano is the time of the oldest sample
- // since MotionEvent.addBatch does not update it.
-
- jint numHistoricalSamples = numSamples - 1;
- jint dataSampleStride = numPointers * NUM_SAMPLE_DATA;
-
- const jfloat* currentDataSample;
- const jlong* currentTimeSample;
- if (numHistoricalSamples == 0) {
- currentDataSample = dataSamples;
- currentTimeSample = timeSamples;
- } else {
- currentDataSample = dataSamples + dataSampleStride;
- currentTimeSample = timeSamples + 1;
- }
+ jlong* eventTimeNanoSamples = (jlong*)env->GetPrimitiveArrayCritical(
+ eventTimeNanoSampleArray, NULL);
+
+ jfloat* srcDataSamples = dataSamples;
+ jlong* srcEventTimeNanoSamples = eventTimeNanoSamples;
- PointerCoords pointerCoords[MAX_POINTERS];
+ jlong sampleEventTime = *(srcEventTimeNanoSamples++);
+ PointerCoords samplePointerCoords[MAX_POINTERS];
for (jint j = 0; j < numPointers; j++) {
- pointerCoords[j].x = *(currentDataSample++);
- pointerCoords[j].y = *(currentDataSample++);
- pointerCoords[j].pressure = *(currentDataSample++);
- pointerCoords[j].size = *(currentDataSample++);
+ samplePointerCoords[j].x = *(srcDataSamples++);
+ samplePointerCoords[j].y = *(srcDataSamples++);
+ samplePointerCoords[j].pressure = *(srcDataSamples++);
+ samplePointerCoords[j].size = *(srcDataSamples++);
}
event->initialize(deviceId, nature, action, edgeFlags, metaState,
- rawX, rawY, xPrecision, yPrecision,
- milliseconds_to_nanoseconds(downTime), eventTimeNano,
- numPointers, pointerIdentifiers, pointerCoords);
-
- while (numHistoricalSamples > 0) {
- numHistoricalSamples -= 1;
- if (numHistoricalSamples == 0) {
- currentDataSample = dataSamples;
- currentTimeSample = timeSamples;
- }
-
- nsecs_t sampleEventTime = milliseconds_to_nanoseconds(*(currentTimeSample++));
+ xOffset, yOffset, xPrecision, yPrecision, downTimeNano, sampleEventTime,
+ numPointers, pointerIdentifiers, samplePointerCoords);
+ for (jint i = 1; i < numSamples; i++) {
+ sampleEventTime = *(srcEventTimeNanoSamples++);
for (jint j = 0; j < numPointers; j++) {
- pointerCoords[j].x = *(currentDataSample++);
- pointerCoords[j].y = *(currentDataSample++);
- pointerCoords[j].pressure = *(currentDataSample++);
- pointerCoords[j].size = *(currentDataSample++);
+ samplePointerCoords[j].x = *(srcDataSamples++);
+ samplePointerCoords[j].y = *(srcDataSamples++);
+ samplePointerCoords[j].pressure = *(srcDataSamples++);
+ samplePointerCoords[j].size = *(srcDataSamples++);
}
-
- event->addSample(sampleEventTime, pointerCoords);
+ event->addSample(sampleEventTime, samplePointerCoords);
}
env->ReleasePrimitiveArrayCritical(pointerIdentifierArray, pointerIdentifiers, JNI_ABORT);
env->ReleasePrimitiveArrayCritical(dataSampleArray, dataSamples, JNI_ABORT);
- env->ReleasePrimitiveArrayCritical(timeSampleArray, timeSamples, JNI_ABORT);
+ env->ReleasePrimitiveArrayCritical(eventTimeNanoSampleArray, eventTimeNanoSamples, JNI_ABORT);
env->DeleteLocalRef(pointerIdentifierArray);
env->DeleteLocalRef(dataSampleArray);
- env->DeleteLocalRef(timeSampleArray);
+ env->DeleteLocalRef(eventTimeNanoSampleArray);
}
void android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj) {
@@ -273,16 +242,14 @@ int register_android_view_MotionEvent(JNIEnv* env) {
GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
"recycle", "()V");
- GET_FIELD_ID(gMotionEventClassInfo.mDownTime, gMotionEventClassInfo.clazz,
- "mDownTime", "J");
- GET_FIELD_ID(gMotionEventClassInfo.mEventTimeNano, gMotionEventClassInfo.clazz,
- "mEventTimeNano", "J");
+ GET_FIELD_ID(gMotionEventClassInfo.mDownTimeNano, gMotionEventClassInfo.clazz,
+ "mDownTimeNano", "J");
GET_FIELD_ID(gMotionEventClassInfo.mAction, gMotionEventClassInfo.clazz,
"mAction", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mRawX, gMotionEventClassInfo.clazz,
- "mRawX", "F");
- GET_FIELD_ID(gMotionEventClassInfo.mRawY, gMotionEventClassInfo.clazz,
- "mRawY", "F");
+ GET_FIELD_ID(gMotionEventClassInfo.mXOffset, gMotionEventClassInfo.clazz,
+ "mXOffset", "F");
+ GET_FIELD_ID(gMotionEventClassInfo.mYOffset, gMotionEventClassInfo.clazz,
+ "mYOffset", "F");
GET_FIELD_ID(gMotionEventClassInfo.mXPrecision, gMotionEventClassInfo.clazz,
"mXPrecision", "F");
GET_FIELD_ID(gMotionEventClassInfo.mYPrecision, gMotionEventClassInfo.clazz,
@@ -301,8 +268,12 @@ int register_android_view_MotionEvent(JNIEnv* env) {
"mPointerIdentifiers", "[I");
GET_FIELD_ID(gMotionEventClassInfo.mDataSamples, gMotionEventClassInfo.clazz,
"mDataSamples", "[F");
- GET_FIELD_ID(gMotionEventClassInfo.mTimeSamples, gMotionEventClassInfo.clazz,
- "mTimeSamples", "[J");
+ GET_FIELD_ID(gMotionEventClassInfo.mEventTimeNanoSamples, gMotionEventClassInfo.clazz,
+ "mEventTimeNanoSamples", "[J");
+ GET_FIELD_ID(gMotionEventClassInfo.mLastDataSampleIndex, gMotionEventClassInfo.clazz,
+ "mLastDataSampleIndex", "I");
+ GET_FIELD_ID(gMotionEventClassInfo.mLastEventTimeNanoSampleIndex, gMotionEventClassInfo.clazz,
+ "mLastEventTimeNanoSampleIndex", "I");
return 0;
}