android_view_MotionEvent.cpp revision 1f2451007c660091b7b090c1ea332f9044515d2d
146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown/*
246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Copyright (C) 2010 The Android Open Source Project
346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *
446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * you may not use this file except in compliance with the License.
646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * You may obtain a copy of the License at
746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *
846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *
1046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Unless required by applicable law or agreed to in writing, software
1146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * See the License for the specific language governing permissions and
1446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * limitations under the License.
1546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown */
1646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define LOG_TAG "MotionEvent-JNI"
1846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "JNIHelp.h"
2046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <android_runtime/AndroidRuntime.h>
2246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <utils/Log.h>
2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <ui/Input.h>
2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_view_MotionEvent.h"
2520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#include "android/graphics/Matrix.h"
2620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
2720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#include <math.h>
2820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#include "SkMatrix.h"
2920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#include "SkScalar.h"
3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Number of float items per entry in a DVM sample data array
32c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown#define NUM_SAMPLE_DATA 9
3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#define SAMPLE_X 0
3520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#define SAMPLE_Y 1
3620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#define SAMPLE_PRESSURE 2
3720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#define SAMPLE_SIZE 3
3820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#define SAMPLE_TOUCH_MAJOR 4
3920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#define SAMPLE_TOUCH_MINOR 5
4020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#define SAMPLE_TOOL_MAJOR 6
4120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#define SAMPLE_TOOL_MINOR 7
4220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#define SAMPLE_ORIENTATION 8
4320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
4420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android {
4646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic struct {
5046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jclass clazz;
5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jmethodID obtain;
5346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jmethodID recycle;
5446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
55c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    jfieldID mDeviceId;
56c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    jfieldID mSource;
575c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jfieldID mDownTimeNano;
5846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mAction;
595c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jfieldID mXOffset;
605c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jfieldID mYOffset;
6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mXPrecision;
6246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mYPrecision;
6346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mEdgeFlags;
6446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mMetaState;
6585a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown    jfieldID mFlags;
6646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mNumPointers;
6746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mNumSamples;
6846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mPointerIdentifiers;
6946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mDataSamples;
705c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jfieldID mEventTimeNanoSamples;
715c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jfieldID mLastDataSampleIndex;
725c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jfieldID mLastEventTimeNanoSampleIndex;
7346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} gMotionEventClassInfo;
7446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
7646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownjobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* event) {
7846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint numPointers = jint(event->getPointerCount());
7946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint numHistoricalSamples = jint(event->getHistorySize());
8046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint numSamples = numHistoricalSamples + 1;
8146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jobject eventObj = env->CallStaticObjectMethod(gMotionEventClassInfo.clazz,
8346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            gMotionEventClassInfo.obtain, numPointers, numSamples);
8446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (env->ExceptionCheck()) {
8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOGE("An exception occurred while obtaining a motion event.");
8646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOGE_EX(env);
8746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        env->ExceptionClear();
8846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return NULL;
8946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
9046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
91c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mDeviceId,
92c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            event->getDeviceId());
93c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mSource,
94c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            event->getSource());
955c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    env->SetLongField(eventObj, gMotionEventClassInfo.mDownTimeNano,
965c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            event->getDownTime());
9746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mAction,
9846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getAction());
995c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    env->SetFloatField(eventObj, gMotionEventClassInfo.mXOffset,
1005c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            event->getXOffset());
1015c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    env->SetFloatField(eventObj, gMotionEventClassInfo.mYOffset,
1025c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            event->getYOffset());
10346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->SetFloatField(eventObj, gMotionEventClassInfo.mXPrecision,
10446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getXPrecision());
10546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->SetFloatField(eventObj, gMotionEventClassInfo.mYPrecision,
10646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getYPrecision());
10746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mEdgeFlags,
10846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getEdgeFlags());
10946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mMetaState,
11046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getMetaState());
11185a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mFlags,
11285a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown            event->getFlags());
11346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mNumPointers,
11446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            numPointers);
11546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mNumSamples,
11646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            numSamples);
1175c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mLastDataSampleIndex,
1185c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            (numSamples - 1) * numPointers * NUM_SAMPLE_DATA);
1195c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mLastEventTimeNanoSampleIndex,
1205c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            numSamples - 1);
12146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
12246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jintArray pointerIdentifierArray = jintArray(env->GetObjectField(eventObj,
12346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            gMotionEventClassInfo.mPointerIdentifiers));
12446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfloatArray dataSampleArray = jfloatArray(env->GetObjectField(eventObj,
12546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            gMotionEventClassInfo.mDataSamples));
1265c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jlongArray eventTimeNanoSampleArray = jlongArray(env->GetObjectField(eventObj,
1275c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            gMotionEventClassInfo.mEventTimeNanoSamples));
12846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
12946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint* pointerIdentifiers = (jint*)env->GetPrimitiveArrayCritical(pointerIdentifierArray, NULL);
13046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfloat* dataSamples = (jfloat*)env->GetPrimitiveArrayCritical(dataSampleArray, NULL);
1315c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jlong* eventTimeNanoSamples = (jlong*)env->GetPrimitiveArrayCritical(
1325c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            eventTimeNanoSampleArray, NULL);
13346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1345c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    const int32_t* srcPointerIdentifiers = event->getPointerIds();
1355c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jint* destPointerIdentifiers = pointerIdentifiers;
13646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    for (jint i = 0; i < numPointers; i++) {
1375c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        *(destPointerIdentifiers++) = *(srcPointerIdentifiers++);
13846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
13946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1405c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    const nsecs_t* srcSampleEventTimes = event->getSampleEventTimes();
1415c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jlong* destEventTimeNanoSamples = eventTimeNanoSamples;
1425c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    for (jint i = 0; i < numSamples; i++) {
1435c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        *(destEventTimeNanoSamples++) = *(srcSampleEventTimes++);
14446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
14546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1465c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    const PointerCoords* srcSamplePointerCoords = event->getSamplePointerCoords();
1475c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jfloat* destDataSamples = dataSamples;
1485c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jint numItems = numSamples * numPointers;
1495c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    for (jint i = 0; i < numItems; i++) {
1505c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        *(destDataSamples++) = srcSamplePointerCoords->x;
1515c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        *(destDataSamples++) = srcSamplePointerCoords->y;
1525c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        *(destDataSamples++) = srcSamplePointerCoords->pressure;
1535c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        *(destDataSamples++) = srcSamplePointerCoords->size;
154c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        *(destDataSamples++) = srcSamplePointerCoords->touchMajor;
155c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        *(destDataSamples++) = srcSamplePointerCoords->touchMinor;
156c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        *(destDataSamples++) = srcSamplePointerCoords->toolMajor;
157c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        *(destDataSamples++) = srcSamplePointerCoords->toolMinor;
158c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        *(destDataSamples++) = srcSamplePointerCoords->orientation;
1595c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        srcSamplePointerCoords += 1;
16046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
16146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
16246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->ReleasePrimitiveArrayCritical(pointerIdentifierArray, pointerIdentifiers, 0);
16346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->ReleasePrimitiveArrayCritical(dataSampleArray, dataSamples, 0);
1645c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    env->ReleasePrimitiveArrayCritical(eventTimeNanoSampleArray, eventTimeNanoSamples, 0);
16546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
16646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->DeleteLocalRef(pointerIdentifierArray);
16746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->DeleteLocalRef(dataSampleArray);
1685c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    env->DeleteLocalRef(eventTimeNanoSampleArray);
16946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return eventObj;
17046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
17146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1721f2451007c660091b7b090c1ea332f9044515d2dJeff Brownstatus_t android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj,
17346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        MotionEvent* event) {
174c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    jint deviceId = env->GetIntField(eventObj, gMotionEventClassInfo.mDeviceId);
175c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    jint source = env->GetIntField(eventObj, gMotionEventClassInfo.mSource);
1765c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jlong downTimeNano = env->GetLongField(eventObj, gMotionEventClassInfo.mDownTimeNano);
17746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint action = env->GetIntField(eventObj, gMotionEventClassInfo.mAction);
1785c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jfloat xOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mXOffset);
1795c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jfloat yOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mYOffset);
18046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfloat xPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mXPrecision);
18146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfloat yPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mYPrecision);
18246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint edgeFlags = env->GetIntField(eventObj, gMotionEventClassInfo.mEdgeFlags);
18346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint metaState = env->GetIntField(eventObj, gMotionEventClassInfo.mMetaState);
18485a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown    jint flags = env->GetIntField(eventObj, gMotionEventClassInfo.mFlags);
18546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint numPointers = env->GetIntField(eventObj, gMotionEventClassInfo.mNumPointers);
18646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint numSamples = env->GetIntField(eventObj, gMotionEventClassInfo.mNumSamples);
1871f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
1881f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    if (numPointers == 0) {
1891f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        LOGE("Malformed MotionEvent: mNumPointers was zero");
1901f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        return BAD_VALUE;
1911f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    }
1921f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    if (numSamples == 0) {
1931f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        LOGE("Malformed MotionEvent: mNumSamples was zero");
1941f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        return BAD_VALUE;
1951f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    }
1961f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
19746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jintArray pointerIdentifierArray = jintArray(env->GetObjectField(eventObj,
19846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            gMotionEventClassInfo.mPointerIdentifiers));
19946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfloatArray dataSampleArray = jfloatArray(env->GetObjectField(eventObj,
20046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            gMotionEventClassInfo.mDataSamples));
2015c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jlongArray eventTimeNanoSampleArray = jlongArray(env->GetObjectField(eventObj,
2025c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            gMotionEventClassInfo.mEventTimeNanoSamples));
20346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
20446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint* pointerIdentifiers = (jint*)env->GetPrimitiveArrayCritical(pointerIdentifierArray, NULL);
20546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfloat* dataSamples = (jfloat*)env->GetPrimitiveArrayCritical(dataSampleArray, NULL);
2065c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jlong* eventTimeNanoSamples = (jlong*)env->GetPrimitiveArrayCritical(
2075c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            eventTimeNanoSampleArray, NULL);
2085c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown
2095c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jfloat* srcDataSamples = dataSamples;
2105c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jlong* srcEventTimeNanoSamples = eventTimeNanoSamples;
21146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2125c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    jlong sampleEventTime = *(srcEventTimeNanoSamples++);
2135c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    PointerCoords samplePointerCoords[MAX_POINTERS];
21446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    for (jint j = 0; j < numPointers; j++) {
2155c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        samplePointerCoords[j].x = *(srcDataSamples++);
2165c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        samplePointerCoords[j].y = *(srcDataSamples++);
2175c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        samplePointerCoords[j].pressure = *(srcDataSamples++);
2185c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        samplePointerCoords[j].size = *(srcDataSamples++);
219c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        samplePointerCoords[j].touchMajor = *(srcDataSamples++);
220c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        samplePointerCoords[j].touchMinor = *(srcDataSamples++);
221c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        samplePointerCoords[j].toolMajor = *(srcDataSamples++);
222c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        samplePointerCoords[j].toolMinor = *(srcDataSamples++);
223c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        samplePointerCoords[j].orientation = *(srcDataSamples++);
22446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
22546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
22685a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown    event->initialize(deviceId, source, action, flags, edgeFlags, metaState,
2275c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            xOffset, yOffset, xPrecision, yPrecision, downTimeNano, sampleEventTime,
2285c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            numPointers, pointerIdentifiers, samplePointerCoords);
22946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2305c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    for (jint i = 1; i < numSamples; i++) {
2315c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        sampleEventTime = *(srcEventTimeNanoSamples++);
23246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        for (jint j = 0; j < numPointers; j++) {
2335c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            samplePointerCoords[j].x = *(srcDataSamples++);
2345c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            samplePointerCoords[j].y = *(srcDataSamples++);
2355c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            samplePointerCoords[j].pressure = *(srcDataSamples++);
2365c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            samplePointerCoords[j].size = *(srcDataSamples++);
237c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            samplePointerCoords[j].touchMajor = *(srcDataSamples++);
238c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            samplePointerCoords[j].touchMinor = *(srcDataSamples++);
239c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            samplePointerCoords[j].toolMajor = *(srcDataSamples++);
240c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            samplePointerCoords[j].toolMinor = *(srcDataSamples++);
241c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            samplePointerCoords[j].orientation = *(srcDataSamples++);
24246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
2435c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        event->addSample(sampleEventTime, samplePointerCoords);
24446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
24546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2465c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    env->ReleasePrimitiveArrayCritical(eventTimeNanoSampleArray, eventTimeNanoSamples, JNI_ABORT);
2471f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    env->ReleasePrimitiveArrayCritical(dataSampleArray, dataSamples, JNI_ABORT);
2481f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    env->ReleasePrimitiveArrayCritical(pointerIdentifierArray, pointerIdentifiers, JNI_ABORT);
24946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2505c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    env->DeleteLocalRef(eventTimeNanoSampleArray);
2511f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    env->DeleteLocalRef(dataSampleArray);
2521f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    env->DeleteLocalRef(pointerIdentifierArray);
2531f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    return OK;
25446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
25546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2561f2451007c660091b7b090c1ea332f9044515d2dJeff Brownstatus_t android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj) {
25746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->CallVoidMethod(eventObj, gMotionEventClassInfo.recycle);
25846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (env->ExceptionCheck()) {
25946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOGW("An exception occurred while recycling a motion event.");
26046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOGW_EX(env);
26146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        env->ExceptionClear();
2621f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        return UNKNOWN_ERROR;
26346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
2641f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    return OK;
26546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
26646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
26720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brownstatic inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
26820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
26920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    // Coordinate system: down is increasing Y, right is increasing X.
27020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    SkPoint vector;
27120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    vector.fX = SkFloatToScalar(sinf(angleRadians));
27220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    vector.fY = SkFloatToScalar(- cosf(angleRadians));
27320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    matrix->mapVectors(& vector, 1);
27420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
27520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    // Derive the transformed vector's clockwise angle from vertical.
27620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(- vector.fY));
27720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    if (result < - M_PI_2) {
27820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        result += M_PI;
27920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    } else if (result > M_PI_2) {
28020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        result -= M_PI;
28120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
28220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    return result;
28320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown}
28420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
28520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brownstatic void android_view_MotionEvent_nativeTransform(JNIEnv* env,
28620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        jobject eventObj, jobject matrixObj) {
28720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
28820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
28920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat oldXOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mXOffset);
29020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat oldYOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mYOffset);
29120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jint numPointers = env->GetIntField(eventObj, gMotionEventClassInfo.mNumPointers);
29220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jint numSamples = env->GetIntField(eventObj, gMotionEventClassInfo.mNumSamples);
29320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloatArray dataSampleArray = jfloatArray(env->GetObjectField(eventObj,
29420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            gMotionEventClassInfo.mDataSamples));
29520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat* dataSamples = (jfloat*)env->GetPrimitiveArrayCritical(dataSampleArray, NULL);
29620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
29720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    // The tricky part of this implementation is to preserve the value of
29820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    // rawX and rawY.  So we apply the transformation to the first point
29920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
30020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    SkPoint point;
30120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat rawX = dataSamples[SAMPLE_X];
30220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat rawY = dataSamples[SAMPLE_Y];
30320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
30420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            & point);
30520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat newX = SkScalarToFloat(point.fX);
30620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat newY = SkScalarToFloat(point.fY);
30720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat newXOffset = newX - rawX;
30820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat newYOffset = newY - rawY;
30920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
31020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    dataSamples[SAMPLE_ORIENTATION] = transformAngle(matrix, dataSamples[SAMPLE_ORIENTATION]);
31120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
31220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    // Apply the transformation to all samples.
31320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat* currentDataSample = dataSamples;
31420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    jfloat* endDataSample = dataSamples + numPointers * numSamples * NUM_SAMPLE_DATA;
31520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    for (;;) {
31620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        currentDataSample += NUM_SAMPLE_DATA;
31720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        if (currentDataSample == endDataSample) {
31820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            break;
31920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        }
32020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
32120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        jfloat x = currentDataSample[SAMPLE_X] + oldXOffset;
32220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        jfloat y = currentDataSample[SAMPLE_Y] + oldYOffset;
32320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), & point);
32420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        currentDataSample[SAMPLE_X] = SkScalarToFloat(point.fX) - newXOffset;
32520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        currentDataSample[SAMPLE_Y] = SkScalarToFloat(point.fY) - newYOffset;
32620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
32720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        currentDataSample[SAMPLE_ORIENTATION] = transformAngle(matrix,
32820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                currentDataSample[SAMPLE_ORIENTATION]);
32920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
33020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
33120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    env->ReleasePrimitiveArrayCritical(dataSampleArray, dataSamples, 0);
33220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
33320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    env->SetFloatField(eventObj, gMotionEventClassInfo.mXOffset, newXOffset);
33420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    env->SetFloatField(eventObj, gMotionEventClassInfo.mYOffset, newYOffset);
33520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
33620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    env->DeleteLocalRef(dataSampleArray);
33720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown}
33820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
33946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
34046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
34120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brownstatic JNINativeMethod gMotionEventMethods[] = {
34220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    /* name, signature, funcPtr */
34320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    { "nativeTransform",
34420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            "(Landroid/graphics/Matrix;)V",
34520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            (void*)android_view_MotionEvent_nativeTransform },
34620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown};
34720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
34846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define FIND_CLASS(var, className) \
34946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->FindClass(className); \
35046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find class " className); \
35146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = jclass(env->NewGlobalRef(var));
35246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
35346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
35446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
35546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find static method" methodName);
35646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
35746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
35846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
35946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find method" methodName);
36046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
36146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
36246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
36346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
36446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
36546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownint register_android_view_MotionEvent(JNIEnv* env) {
36620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    int res = jniRegisterNativeMethods(env, "android/view/MotionEvent",
36720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            gMotionEventMethods, NELEM(gMotionEventMethods));
36820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
36920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
37046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
37146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
37246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
37346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "obtain", "(II)Landroid/view/MotionEvent;");
37446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
37546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "recycle", "()V");
37646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
377c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mDeviceId, gMotionEventClassInfo.clazz,
378c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            "mDeviceId", "I");
379c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mSource, gMotionEventClassInfo.clazz,
380c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            "mSource", "I");
3815c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mDownTimeNano, gMotionEventClassInfo.clazz,
3825c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            "mDownTimeNano", "J");
38346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mAction, gMotionEventClassInfo.clazz,
38446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mAction", "I");
3855c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mXOffset, gMotionEventClassInfo.clazz,
3865c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            "mXOffset", "F");
3875c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mYOffset, gMotionEventClassInfo.clazz,
3885c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            "mYOffset", "F");
38946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mXPrecision, gMotionEventClassInfo.clazz,
39046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mXPrecision", "F");
39146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mYPrecision, gMotionEventClassInfo.clazz,
39246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mYPrecision", "F");
39346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mEdgeFlags, gMotionEventClassInfo.clazz,
39446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mEdgeFlags", "I");
39546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mMetaState, gMotionEventClassInfo.clazz,
39646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mMetaState", "I");
39785a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mFlags, gMotionEventClassInfo.clazz,
39885a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown            "mFlags", "I");
39946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mNumPointers, gMotionEventClassInfo.clazz,
40046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mNumPointers", "I");
40146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mNumSamples, gMotionEventClassInfo.clazz,
40246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mNumSamples", "I");
40346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mPointerIdentifiers, gMotionEventClassInfo.clazz,
40446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mPointerIdentifiers", "[I");
40546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mDataSamples, gMotionEventClassInfo.clazz,
40646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mDataSamples", "[F");
4075c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mEventTimeNanoSamples, gMotionEventClassInfo.clazz,
4085c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            "mEventTimeNanoSamples", "[J");
4095c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mLastDataSampleIndex, gMotionEventClassInfo.clazz,
4105c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            "mLastDataSampleIndex", "I");
4115c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mLastEventTimeNanoSampleIndex, gMotionEventClassInfo.clazz,
4125c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown            "mLastEventTimeNanoSampleIndex", "I");
41346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
41446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return 0;
41546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
41646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
41746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
418