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>
23b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopian#include <androidfw/Input.h>
24d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include "android_os_Parcel.h"
2546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_view_MotionEvent.h"
2691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include "android_util_Binder.h"
2720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#include "android/graphics/Matrix.h"
2820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
2920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#include "SkMatrix.h"
3020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
3120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android {
3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
3546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic struct {
3746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jclass clazz;
3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jmethodID obtain;
4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jmethodID recycle;
4146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID mNativePtr;
4346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} gMotionEventClassInfo;
4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic struct {
4691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID mPackedAxisBits;
4791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID mPackedAxisValues;
4891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID x;
4991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID y;
5091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID pressure;
5191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID size;
5291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID touchMajor;
5391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID touchMinor;
5491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID toolMajor;
5591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID toolMinor;
5691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID orientation;
5791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} gPointerCoordsClassInfo;
5891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
59fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic struct {
60fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    jfieldID id;
61fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    jfieldID toolType;
62fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown} gPointerPropertiesClassInfo;
63fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
6446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
6546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
662ed2462aa29c564f5231f317c27b3188da875e52Jeff BrownMotionEvent* android_view_MotionEvent_getNativePtr(JNIEnv* env, jobject eventObj) {
672ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (!eventObj) {
682ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        return NULL;
692ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
7091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return reinterpret_cast<MotionEvent*>(
7191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetIntField(eventObj, gMotionEventClassInfo.mNativePtr));
7291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
7346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_setNativePtr(JNIEnv* env, jobject eventObj,
7591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        MotionEvent* event) {
7691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mNativePtr,
7791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            reinterpret_cast<int>(event));
7891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
7991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
802ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownjobject android_view_MotionEvent_obtainAsCopy(JNIEnv* env, const MotionEvent* event) {
8146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jobject eventObj = env->CallStaticObjectMethod(gMotionEventClassInfo.clazz,
8291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            gMotionEventClassInfo.obtain);
832ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (env->ExceptionCheck() || !eventObj) {
843762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("An exception occurred while obtaining a motion event.");
8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOGE_EX(env);
8646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        env->ExceptionClear();
8746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return NULL;
8846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
8946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* destEvent = android_view_MotionEvent_getNativePtr(env, eventObj);
9191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!destEvent) {
9291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        destEvent = new MotionEvent();
9391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        android_view_MotionEvent_setNativePtr(env, eventObj, destEvent);
9491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
9591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
9691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    destEvent->copyFrom(event, true);
9746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return eventObj;
9846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
9946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatus_t android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj) {
10191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->CallVoidMethod(eventObj, gMotionEventClassInfo.recycle);
10291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (env->ExceptionCheck()) {
1038564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("An exception occurred while recycling a motion event.");
10491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        LOGW_EX(env);
10591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->ExceptionClear();
10691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return UNKNOWN_ERROR;
10791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
10891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return OK;
10991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
11091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
11191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown// ----------------------------------------------------------------------------
11291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
11391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic const jint HISTORY_CURRENT = -0x80000000;
11491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
11591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic bool validatePointerCount(JNIEnv* env, jint pointerCount) {
11691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (pointerCount < 1) {
11791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
11891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "pointerCount must be at least 1");
11991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
12091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
12191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
12291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
12391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
124fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic bool validatePointerPropertiesArray(JNIEnv* env, jobjectArray pointerPropertiesObjArray,
12591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t pointerCount) {
126fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!pointerPropertiesObjArray) {
12791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
128fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "pointerProperties array must not be null");
12991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
13091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
131fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    size_t length = size_t(env->GetArrayLength(pointerPropertiesObjArray));
13291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (length < pointerCount) {
13391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
134fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "pointerProperties array must be large enough to hold all pointers");
13591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
13691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
13791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
13891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
13991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
14091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic bool validatePointerCoordsObjArray(JNIEnv* env, jobjectArray pointerCoordsObjArray,
14191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t pointerCount) {
14291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!pointerCoordsObjArray) {
14391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
14491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "pointerCoords array must not be null");
14591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
14691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
14791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t length = size_t(env->GetArrayLength(pointerCoordsObjArray));
14891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (length < pointerCount) {
14991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
15091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "pointerCoords array must be large enough to hold all pointers");
15191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
15291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
15391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
15491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
15591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
15691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic bool validatePointerIndex(JNIEnv* env, jint pointerIndex, size_t pointerCount) {
15791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (pointerIndex < 0 || size_t(pointerIndex) >= pointerCount) {
15891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
15991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "pointerIndex out of range");
16091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
16191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
16291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
16391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
16491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
16591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic bool validateHistoryPos(JNIEnv* env, jint historyPos, size_t historySize) {
16691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (historyPos < 0 || size_t(historyPos) >= historySize) {
16791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
16891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "historyPos out of range");
16991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
17091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
17191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
17291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
17391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
17491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic bool validatePointerCoords(JNIEnv* env, jobject pointerCoordsObj) {
17591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!pointerCoordsObj) {
17691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
17791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "pointerCoords must not be null");
17891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
17991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
18091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
18191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
18291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
183fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic bool validatePointerProperties(JNIEnv* env, jobject pointerPropertiesObj) {
184fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!pointerPropertiesObj) {
185fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
186fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "pointerProperties must not be null");
187fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        return false;
188fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
189fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return true;
190fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
191fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
19291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj,
19391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        float xOffset, float yOffset, PointerCoords* outRawPointerCoords) {
19491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    outRawPointerCoords->clear();
195ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_X,
19691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.x) - xOffset);
197ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_Y,
19891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.y) - yOffset);
199ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
20091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.pressure));
201ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_SIZE,
20291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.size));
203ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
20491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMajor));
205ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR,
20691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMinor));
207ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR,
20891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMajor));
209ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR,
21091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMinor));
211ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
21291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.orientation));
21391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
2146f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    uint64_t bits = env->GetLongField(pointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits);
21591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (bits) {
21691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jfloatArray valuesArray = jfloatArray(env->GetObjectField(pointerCoordsObj,
21791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                gPointerCoordsClassInfo.mPackedAxisValues));
21891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (valuesArray) {
21991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            jfloat* values = static_cast<jfloat*>(
22091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                    env->GetPrimitiveArrayCritical(valuesArray, NULL));
22191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
22291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            uint32_t index = 0;
22391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            do {
224cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                uint32_t axis = __builtin_ctzll(bits);
2256f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                uint64_t axisBit = 1LL << axis;
22691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                bits &= ~axisBit;
22791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                outRawPointerCoords->setAxisValue(axis, values[index++]);
22891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            } while (bits);
22991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
23091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->ReleasePrimitiveArrayCritical(valuesArray, values, JNI_ABORT);
23191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->DeleteLocalRef(valuesArray);
23291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
23391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
23491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
23591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
23691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jfloatArray obtainPackedAxisValuesArray(JNIEnv* env, uint32_t minSize,
23791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jobject outPointerCoordsObj) {
23891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfloatArray outValuesArray = jfloatArray(env->GetObjectField(outPointerCoordsObj,
23991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            gPointerCoordsClassInfo.mPackedAxisValues));
24091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (outValuesArray) {
24191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        uint32_t size = env->GetArrayLength(outValuesArray);
24291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (minSize <= size) {
24391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return outValuesArray;
24491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
24591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->DeleteLocalRef(outValuesArray);
24691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
24791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    uint32_t size = 8;
24891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    while (size < minSize) {
24991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size *= 2;
25091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
25191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    outValuesArray = env->NewFloatArray(size);
25291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetObjectField(outPointerCoordsObj,
25391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            gPointerCoordsClassInfo.mPackedAxisValues, outValuesArray);
25491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return outValuesArray;
25591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
25691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
25791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointerCoords,
25891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        float xOffset, float yOffset, jobject outPointerCoordsObj) {
25991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x,
260ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset);
26191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y,
262ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset);
26391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.pressure,
264ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
26591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.size,
266ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_SIZE));
26791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMajor,
268ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR));
26991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMinor,
270ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR));
27191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMajor,
272ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR));
27391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMinor,
274ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR));
27591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.orientation,
276ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
27791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
2786f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    const uint64_t unpackedAxisBits = 0
2796f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_X)
2806f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_Y)
2816f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_PRESSURE)
2826f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_SIZE)
2836f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_TOUCH_MAJOR)
2846f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_TOUCH_MINOR)
2856f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_TOOL_MAJOR)
2866f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_TOOL_MINOR)
2876f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_ORIENTATION);
2886f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
2896f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    uint64_t outBits = 0;
2906f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    uint64_t remainingBits = rawPointerCoords->bits & ~unpackedAxisBits;
29191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (remainingBits) {
2926f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        uint32_t packedAxesCount = __builtin_popcountll(remainingBits);
29391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jfloatArray outValuesArray = obtainPackedAxisValuesArray(env, packedAxesCount,
29491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                outPointerCoordsObj);
29591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!outValuesArray) {
29691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return; // OOM
29791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
29891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
29991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jfloat* outValues = static_cast<jfloat*>(env->GetPrimitiveArrayCritical(
30091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                outValuesArray, NULL));
30191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
30291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        const float* values = rawPointerCoords->values;
30391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        uint32_t index = 0;
30491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        do {
305cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            uint32_t axis = __builtin_ctzll(remainingBits);
3066f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            uint64_t axisBit = 1LL << axis;
30791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            remainingBits &= ~axisBit;
30891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            outBits |= axisBit;
30991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            outValues[index++] = rawPointerCoords->getAxisValue(axis);
31091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        } while (remainingBits);
31191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
31291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->ReleasePrimitiveArrayCritical(outValuesArray, outValues, 0);
31391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->DeleteLocalRef(outValuesArray);
3141f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    }
3156f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    env->SetLongField(outPointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits, outBits);
31691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
3171f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
318fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic void pointerPropertiesToNative(JNIEnv* env, jobject pointerPropertiesObj,
319fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        PointerProperties* outPointerProperties) {
320fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    outPointerProperties->clear();
321fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    outPointerProperties->id = env->GetIntField(pointerPropertiesObj,
322fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            gPointerPropertiesClassInfo.id);
323fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    outPointerProperties->toolType = env->GetIntField(pointerPropertiesObj,
324fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            gPointerPropertiesClassInfo.toolType);
325fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
326fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
327fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic void pointerPropertiesFromNative(JNIEnv* env, const PointerProperties* pointerProperties,
328fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jobject outPointerPropertiesObj) {
329fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.id,
330fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            pointerProperties->id);
331fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.toolType,
332fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            pointerProperties->toolType);
333fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
334fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
33546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
33691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown// ----------------------------------------------------------------------------
3375c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown
33891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz,
33991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr,
340fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint deviceId, jint source, jint action, jint flags, jint edgeFlags,
341fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint metaState, jint buttonState,
34291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jfloat xOffset, jfloat yOffset, jfloat xPrecision, jfloat yPrecision,
34391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jlong downTimeNanos, jlong eventTimeNanos,
344fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint pointerCount, jobjectArray pointerPropertiesObjArray,
345fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jobjectArray pointerCoordsObjArray) {
34691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerCount(env, pointerCount)
347fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            || !validatePointerPropertiesArray(env, pointerPropertiesObjArray, pointerCount)
34891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            || !validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
34991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return 0;
35091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
35146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
35291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
35391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!event) {
35491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        event = new MotionEvent();
35546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
35646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
357fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    PointerProperties pointerProperties[pointerCount];
35891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    PointerCoords rawPointerCoords[pointerCount];
35991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
36091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (jint i = 0; i < pointerCount; i++) {
361fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jobject pointerPropertiesObj = env->GetObjectArrayElement(pointerPropertiesObjArray, i);
362fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (!pointerPropertiesObj) {
363fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            goto Error;
364fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        }
365fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        pointerPropertiesToNative(env, pointerPropertiesObj, &pointerProperties[i]);
366fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        env->DeleteLocalRef(pointerPropertiesObj);
367fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
36891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
36991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!pointerCoordsObj) {
37091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            jniThrowNullPointerException(env, "pointerCoords");
371fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            goto Error;
37291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
37391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        pointerCoordsToNative(env, pointerCoordsObj, xOffset, yOffset, &rawPointerCoords[i]);
37491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->DeleteLocalRef(pointerCoordsObj);
37591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
37691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
377fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    event->initialize(deviceId, source, action, flags, edgeFlags, metaState, buttonState,
37891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            xOffset, yOffset, xPrecision, yPrecision,
379fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords);
38091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
38191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return reinterpret_cast<jint>(event);
382fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
383fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff BrownError:
384fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!nativePtr) {
385fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        delete event;
386fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
387fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return 0;
38891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
38991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
39091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeCopy(JNIEnv* env, jclass clazz,
39191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint destNativePtr, jint sourceNativePtr, jboolean keepHistory) {
39291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* destEvent = reinterpret_cast<MotionEvent*>(destNativePtr);
39391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!destEvent) {
39491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        destEvent = new MotionEvent();
39591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
39691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* sourceEvent = reinterpret_cast<MotionEvent*>(sourceNativePtr);
39791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    destEvent->copyFrom(sourceEvent, keepHistory);
39891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return reinterpret_cast<jint>(destEvent);
39991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
40091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
40191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeDispose(JNIEnv* env, jclass clazz,
40291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
40391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
40491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    delete event;
40591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
40691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
40791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeAddBatch(JNIEnv* env, jclass clazz,
40891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jlong eventTimeNanos, jobjectArray pointerCoordsObjArray,
40991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint metaState) {
41091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
41191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = event->getPointerCount();
41291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
41391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return;
41491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
41591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
41691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    PointerCoords rawPointerCoords[pointerCount];
41791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
41891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (size_t i = 0; i < pointerCount; i++) {
41991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
42091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!pointerCoordsObj) {
42191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            jniThrowNullPointerException(env, "pointerCoords");
42291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return;
42346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
42491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        pointerCoordsToNative(env, pointerCoordsObj,
42591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                event->getXOffset(), event->getYOffset(), &rawPointerCoords[i]);
42691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->DeleteLocalRef(pointerCoordsObj);
42746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
42846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
42991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->addSample(eventTimeNanos, rawPointerCoords);
43091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->setMetaState(event->getMetaState() | metaState);
43191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
43246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
43391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetDeviceId(JNIEnv* env, jclass clazz,
43491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
43591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
43691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getDeviceId();
43746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
43846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
43991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetSource(JNIEnv* env, jclass clazz,
44091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
44191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
44291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getSource();
44391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
44491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
44591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeSetSource(JNIEnv* env, jclass clazz,
44691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint source) {
44791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
44891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->setSource(source);
44991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
45091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
45191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetAction(JNIEnv* env, jclass clazz,
45291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
45391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
45491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getAction();
45591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
45691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
45791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeSetAction(JNIEnv* env, jclass clazz,
45891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint action) {
45991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
46091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->setAction(action);
46191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
46291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
46356194ebec6212e229f4ccdaa4b187166d20013efJeff Brownstatic jboolean android_view_MotionEvent_nativeIsTouchEvent(JNIEnv* env, jclass clazz,
46456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        jint nativePtr) {
46556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
46656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    return event->isTouchEvent();
46756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown}
46856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
46991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetFlags(JNIEnv* env, jclass clazz,
47091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
47191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
47291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getFlags();
47391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
47491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
47521bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brownstatic void android_view_MotionEvent_nativeSetFlags(JNIEnv* env, jclass clazz,
47621bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown        jint nativePtr, jint flags) {
47721bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
47821bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown    event->setFlags(flags);
47921bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown}
48021bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown
48191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetEdgeFlags(JNIEnv* env, jclass clazz,
48291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
48391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
48491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getEdgeFlags();
48591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
48691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
48791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeSetEdgeFlags(JNIEnv* env, jclass clazz,
48891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint edgeFlags) {
48991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
49091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->setEdgeFlags(edgeFlags);
49191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
49291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
49391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetMetaState(JNIEnv* env, jclass clazz,
49491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
49591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
49691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getMetaState();
49791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
49891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
499fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic jint android_view_MotionEvent_nativeGetButtonState(JNIEnv* env, jclass clazz,
500fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr) {
501fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
502fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return event->getButtonState();
503fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
504fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
50591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeOffsetLocation(JNIEnv* env, jclass clazz,
50691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jfloat deltaX, jfloat deltaY) {
50791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
50891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->offsetLocation(deltaX, deltaY);
50991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
51091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
511fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic jfloat android_view_MotionEvent_nativeGetXOffset(JNIEnv* env, jclass clazz,
512fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr) {
513fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
514fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return event->getXOffset();
515fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
516fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
517fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic jfloat android_view_MotionEvent_nativeGetYOffset(JNIEnv* env, jclass clazz,
518fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr) {
519fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
520fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return event->getYOffset();
521fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
522fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
52391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jfloat android_view_MotionEvent_nativeGetXPrecision(JNIEnv* env, jclass clazz,
52491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
52591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
52691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getXPrecision();
52791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
52891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
52991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jfloat android_view_MotionEvent_nativeGetYPrecision(JNIEnv* env, jclass clazz,
53091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
53191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
53291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getYPrecision();
53391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
53491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
53591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jlong android_view_MotionEvent_nativeGetDownTimeNanos(JNIEnv* env, jclass clazz,
53691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
53791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
53891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getDownTime();
53991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
54091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
541fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic void android_view_MotionEvent_nativeSetDownTimeNanos(JNIEnv* env, jclass clazz,
542fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr, jlong downTimeNanos) {
543fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
544fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    event->setDownTime(downTimeNanos);
545fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
546fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
54791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetPointerCount(JNIEnv* env, jclass clazz,
54891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
54991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
55091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return jint(event->getPointerCount());
55191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
55291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
55391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetPointerId(JNIEnv* env, jclass clazz,
55491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint pointerIndex) {
55591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
55691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = event->getPointerCount();
55791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
55891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return -1;
55946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
56091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getPointerId(pointerIndex);
56146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
56246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
563fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic jint android_view_MotionEvent_nativeGetToolType(JNIEnv* env, jclass clazz,
564fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr, jint pointerIndex) {
565fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
566fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    size_t pointerCount = event->getPointerCount();
567fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
568fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        return -1;
569fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
570fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return event->getToolType(pointerIndex);
571fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
572fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
57391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeFindPointerIndex(JNIEnv* env, jclass clazz,
57491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint pointerId) {
57591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
5762ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    return jint(event->findPointerIndex(pointerId));
57791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
57891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
57991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetHistorySize(JNIEnv* env, jclass clazz,
58091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
58191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
58291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return jint(event->getHistorySize());
58391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
58420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
58591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jlong android_view_MotionEvent_nativeGetEventTimeNanos(JNIEnv* env, jclass clazz,
58691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint historyPos) {
58791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
58891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (historyPos == HISTORY_CURRENT) {
58991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getEventTime();
59091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    } else {
59191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historySize = event->getHistorySize();
59291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!validateHistoryPos(env, historyPos, historySize)) {
59391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return 0;
59491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
59591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getHistoricalEventTime(historyPos);
59620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
59720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown}
59820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
59991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jfloat android_view_MotionEvent_nativeGetRawAxisValue(JNIEnv* env, jclass clazz,
60091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
60191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
60291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = event->getPointerCount();
60391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
60491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return 0;
60591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
60620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
60791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (historyPos == HISTORY_CURRENT) {
60891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getRawAxisValue(axis, pointerIndex);
60991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    } else {
61091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historySize = event->getHistorySize();
61191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!validateHistoryPos(env, historyPos, historySize)) {
61291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return 0;
61320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        }
61491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getHistoricalRawAxisValue(axis, pointerIndex, historyPos);
61591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
61691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
61720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
61891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jfloat android_view_MotionEvent_nativeGetAxisValue(JNIEnv* env, jclass clazz,
61991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
62091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
62191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = event->getPointerCount();
62291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
62391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return 0;
62491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
62520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
62691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (historyPos == HISTORY_CURRENT) {
62791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getAxisValue(axis, pointerIndex);
62891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    } else {
62991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historySize = event->getHistorySize();
63091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!validateHistoryPos(env, historyPos, historySize)) {
63191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return 0;
63291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
63391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getHistoricalAxisValue(axis, pointerIndex, historyPos);
63420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
63591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
63620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
63791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass clazz,
63891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint pointerIndex, jint historyPos, jobject outPointerCoordsObj) {
63991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
64091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = event->getPointerCount();
64191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)
64291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            || !validatePointerCoords(env, outPointerCoordsObj)) {
64391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return;
64491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
64520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
64691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    const PointerCoords* rawPointerCoords;
64791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (historyPos == HISTORY_CURRENT) {
64891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        rawPointerCoords = event->getRawPointerCoords(pointerIndex);
64991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    } else {
65091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historySize = event->getHistorySize();
65191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!validateHistoryPos(env, historyPos, historySize)) {
65291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return;
65391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
65491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        rawPointerCoords = event->getHistoricalRawPointerCoords(pointerIndex, historyPos);
65591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
65691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    pointerCoordsFromNative(env, rawPointerCoords, event->getXOffset(), event->getYOffset(),
65791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            outPointerCoordsObj);
65891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
65991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
660fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic void android_view_MotionEvent_nativeGetPointerProperties(JNIEnv* env, jclass clazz,
661fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr, jint pointerIndex, jobject outPointerPropertiesObj) {
662fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
663fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    size_t pointerCount = event->getPointerCount();
664fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)
665fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            || !validatePointerProperties(env, outPointerPropertiesObj)) {
666fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        return;
667fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
668fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
669fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    const PointerProperties* pointerProperties = event->getPointerProperties(pointerIndex);
670fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    pointerPropertiesFromNative(env, pointerProperties, outPointerPropertiesObj);
671fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
672fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
67391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeScale(JNIEnv* env, jclass clazz,
67491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jfloat scale) {
67591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
67691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->scale(scale);
67791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
67891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
67991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeTransform(JNIEnv* env, jclass clazz,
68091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jobject matrixObj) {
68191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
68291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
68391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->transform(matrix);
68491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
68591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
68691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeReadFromParcel(JNIEnv* env, jclass clazz,
68791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jobject parcelObj) {
68891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
68991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!event) {
69091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        event = new MotionEvent();
69191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
69291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
69391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    Parcel* parcel = parcelForJavaObject(env, parcelObj);
69420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
69591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    status_t status = event->readFromParcel(parcel);
696ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    if (status) {
69791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!nativePtr) {
69891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            delete event;
69991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
70091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowRuntimeException(env, "Failed to read MotionEvent parcel.");
70191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return 0;
70291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
70391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return reinterpret_cast<jint>(event);
70491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
70591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
70691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeWriteToParcel(JNIEnv* env, jclass clazz,
70791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jobject parcelObj) {
70891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
70991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    Parcel* parcel = parcelForJavaObject(env, parcelObj);
71091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
71191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    status_t status = event->writeToParcel(parcel);
712ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    if (status) {
71391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowRuntimeException(env, "Failed to write MotionEvent parcel.");
71491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
71520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown}
71620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
71746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
71846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
71920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brownstatic JNINativeMethod gMotionEventMethods[] = {
72020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    /* name, signature, funcPtr */
72191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeInitialize",
722fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(IIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;"
723fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    "[Landroid/view/MotionEvent$PointerCoords;)I",
72491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeInitialize },
72591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeCopy",
72691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IIZ)I",
72791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeCopy },
72891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeDispose",
72991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)V",
73091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeDispose },
73191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeAddBatch",
73291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IJ[Landroid/view/MotionEvent$PointerCoords;I)V",
73391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeAddBatch },
73491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetDeviceId",
73591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
73691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetDeviceId },
73791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetSource",
73891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
73991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetSource },
74091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeSetSource",
74191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)I",
74291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeSetSource },
74391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetAction",
74491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
74591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetAction },
74691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeSetAction",
74791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)V",
74891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeSetAction },
74956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    { "nativeIsTouchEvent",
75056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown            "(I)Z",
75156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown            (void*)android_view_MotionEvent_nativeIsTouchEvent },
75291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetFlags",
75391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
75491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetFlags },
75521bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown    { "nativeSetFlags",
75621bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown            "(II)V",
75721bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown            (void*)android_view_MotionEvent_nativeSetFlags },
75891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetEdgeFlags",
75991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
76091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetEdgeFlags },
76191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeSetEdgeFlags",
76291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)V",
76391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeSetEdgeFlags },
76491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetMetaState",
76591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
76691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetMetaState },
767fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeGetButtonState",
768fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(I)I",
769fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeGetButtonState },
77091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeOffsetLocation",
77191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IFF)V",
77291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeOffsetLocation },
773fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeGetXOffset",
774fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(I)F",
775fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeGetXOffset },
776fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeGetYOffset",
777fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(I)F",
778fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeGetYOffset },
77991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetXPrecision",
78091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)F",
78191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetXPrecision },
78291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetYPrecision",
78391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)F",
78491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetYPrecision },
78591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetDownTimeNanos",
78691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)J",
78791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetDownTimeNanos },
788fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeSetDownTimeNanos",
789fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(IJ)V",
790fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeSetDownTimeNanos },
79191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetPointerCount",
79291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
79391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetPointerCount },
79491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetPointerId",
79591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)I",
79691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetPointerId },
797fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeGetToolType",
798fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(II)I",
799fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeGetToolType },
80091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeFindPointerIndex",
80191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)I",
80291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeFindPointerIndex },
80391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetHistorySize",
80491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
80591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetHistorySize },
80691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetEventTimeNanos",
80791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)J",
80891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetEventTimeNanos },
80991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetRawAxisValue",
81091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IIII)F",
81191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetRawAxisValue },
81291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetAxisValue",
81391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IIII)F",
81491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetAxisValue },
81591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetPointerCoords",
81691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IIILandroid/view/MotionEvent$PointerCoords;)V",
81791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetPointerCoords },
818fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeGetPointerProperties",
819fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(IILandroid/view/MotionEvent$PointerProperties;)V",
820fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeGetPointerProperties },
82191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeScale",
82291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IF)V",
82391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeScale },
82420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    { "nativeTransform",
82591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(ILandroid/graphics/Matrix;)V",
82620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            (void*)android_view_MotionEvent_nativeTransform },
82791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeReadFromParcel",
82891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(ILandroid/os/Parcel;)I",
82991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeReadFromParcel },
83091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeWriteToParcel",
83191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(ILandroid/os/Parcel;)V",
83291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeWriteToParcel },
83320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown};
83420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
83546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define FIND_CLASS(var, className) \
83646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->FindClass(className); \
83717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro        LOG_FATAL_IF(! var, "Unable to find class " className);
83846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
83946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
84046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
84146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find static method" methodName);
84246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
84346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
84446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
84546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find method" methodName);
84646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
84746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
84846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
84946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
85046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
85146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownint register_android_view_MotionEvent(JNIEnv* env) {
85220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    int res = jniRegisterNativeMethods(env, "android/view/MotionEvent",
85320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            gMotionEventMethods, NELEM(gMotionEventMethods));
85420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
85520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
85646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
85717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
85846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
85946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
86091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "obtain", "()Landroid/view/MotionEvent;");
86146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
86246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "recycle", "()V");
86391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mNativePtr, gMotionEventClassInfo.clazz,
86491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "mNativePtr", "I");
86591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
86617cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    jclass clazz;
86717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    FIND_CLASS(clazz, "android/view/MotionEvent$PointerCoords");
86891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
86917cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, clazz,
8706f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            "mPackedAxisBits", "J");
87117cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, clazz,
87291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "mPackedAxisValues", "[F");
87317cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.x, clazz,
87491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "x", "F");
87517cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.y, clazz,
87691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "y", "F");
87717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.pressure, clazz,
87891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "pressure", "F");
87917cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.size, clazz,
88091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "size", "F");
88117cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.touchMajor, clazz,
88291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "touchMajor", "F");
88317cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.touchMinor, clazz,
88491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "touchMinor", "F");
88517cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.toolMajor, clazz,
88691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "toolMajor", "F");
88717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.toolMinor, clazz,
88891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "toolMinor", "F");
88917cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.orientation, clazz,
89091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "orientation", "F");
89146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
892fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    FIND_CLASS(clazz, "android/view/MotionEvent$PointerProperties");
893fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
894fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    GET_FIELD_ID(gPointerPropertiesClassInfo.id, clazz,
895fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "id", "I");
896fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    GET_FIELD_ID(gPointerPropertiesClassInfo.toolType, clazz,
897fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "toolType", "I");
898fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
89946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return 0;
90046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
90146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
90246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
903