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
2148a3d98d1ff9c07dc5bf446fa50899ac6017b7a0Jeff Brown#include <SkMatrix.h>
2246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <android_runtime/AndroidRuntime.h>
2387eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include <android_runtime/Log.h>
2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <utils/Log.h>
259d3b1a424c5c61e24e9659d15fb353026a00d925Jeff Brown#include <input/Input.h>
26d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include "android_os_Parcel.h"
2746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_view_MotionEvent.h"
2891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include "android_util_Binder.h"
2920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown#include "android/graphics/Matrix.h"
3020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android {
3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
3446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic struct {
3646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jclass clazz;
3746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jmethodID obtain;
3946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jmethodID recycle;
4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID mNativePtr;
4246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} gMotionEventClassInfo;
4346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic struct {
4591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID mPackedAxisBits;
4691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID mPackedAxisValues;
4791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID x;
4891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID y;
4991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID pressure;
5091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID size;
5191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID touchMajor;
5291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID touchMinor;
5391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID toolMajor;
5491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID toolMinor;
5591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfieldID orientation;
5691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} gPointerCoordsClassInfo;
5791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
58fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic struct {
59fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    jfieldID id;
60fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    jfieldID toolType;
61fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown} gPointerPropertiesClassInfo;
62fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
6346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
6446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
652ed2462aa29c564f5231f317c27b3188da875e52Jeff BrownMotionEvent* android_view_MotionEvent_getNativePtr(JNIEnv* env, jobject eventObj) {
662ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (!eventObj) {
672ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        return NULL;
682ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
6991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return reinterpret_cast<MotionEvent*>(
7091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetIntField(eventObj, gMotionEventClassInfo.mNativePtr));
7191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
7246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_setNativePtr(JNIEnv* env, jobject eventObj,
7491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        MotionEvent* event) {
7591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetIntField(eventObj, gMotionEventClassInfo.mNativePtr,
7691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            reinterpret_cast<int>(event));
7791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
7891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
792ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownjobject android_view_MotionEvent_obtainAsCopy(JNIEnv* env, const MotionEvent* event) {
8046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jobject eventObj = env->CallStaticObjectMethod(gMotionEventClassInfo.clazz,
8191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            gMotionEventClassInfo.obtain);
822ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (env->ExceptionCheck() || !eventObj) {
833762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("An exception occurred while obtaining a motion event.");
8446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOGE_EX(env);
8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        env->ExceptionClear();
8646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return NULL;
8746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
8846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* destEvent = android_view_MotionEvent_getNativePtr(env, eventObj);
9091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!destEvent) {
9191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        destEvent = new MotionEvent();
9291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        android_view_MotionEvent_setNativePtr(env, eventObj, destEvent);
9391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
9491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
9591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    destEvent->copyFrom(event, true);
9646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return eventObj;
9746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
9846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatus_t android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj) {
10091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->CallVoidMethod(eventObj, gMotionEventClassInfo.recycle);
10191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (env->ExceptionCheck()) {
1028564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("An exception occurred while recycling a motion event.");
10391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        LOGW_EX(env);
10491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->ExceptionClear();
10591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return UNKNOWN_ERROR;
10691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
10791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return OK;
10891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
10991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
11091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown// ----------------------------------------------------------------------------
11191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
11291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic const jint HISTORY_CURRENT = -0x80000000;
11391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
11491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic bool validatePointerCount(JNIEnv* env, jint pointerCount) {
11591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (pointerCount < 1) {
11691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
11791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "pointerCount must be at least 1");
11891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
11991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
12091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
12191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
12291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
123fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic bool validatePointerPropertiesArray(JNIEnv* env, jobjectArray pointerPropertiesObjArray,
12491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t pointerCount) {
125fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!pointerPropertiesObjArray) {
12691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
127fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "pointerProperties array must not be null");
12891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
12991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
130fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    size_t length = size_t(env->GetArrayLength(pointerPropertiesObjArray));
13191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (length < pointerCount) {
13291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
133fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "pointerProperties array must be large enough to hold all pointers");
13491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
13591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
13691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
13791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
13891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
13991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic bool validatePointerCoordsObjArray(JNIEnv* env, jobjectArray pointerCoordsObjArray,
14091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t pointerCount) {
14191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!pointerCoordsObjArray) {
14291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
14391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "pointerCoords array must not be null");
14491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
14591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
14691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t length = size_t(env->GetArrayLength(pointerCoordsObjArray));
14791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (length < pointerCount) {
14891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
14991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "pointerCoords array must be large enough to hold all pointers");
15091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
15191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
15291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
15391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
15491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
15591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic bool validatePointerIndex(JNIEnv* env, jint pointerIndex, size_t pointerCount) {
15691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (pointerIndex < 0 || size_t(pointerIndex) >= pointerCount) {
15791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
15891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "pointerIndex out of range");
15991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
16091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
16191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
16291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
16391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
16491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic bool validateHistoryPos(JNIEnv* env, jint historyPos, size_t historySize) {
16591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (historyPos < 0 || size_t(historyPos) >= historySize) {
16691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
16791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "historyPos out of range");
16891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
16991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
17091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
17191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
17291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
17391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic bool validatePointerCoords(JNIEnv* env, jobject pointerCoordsObj) {
17491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!pointerCoordsObj) {
17591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
17691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                "pointerCoords must not be null");
17791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return false;
17891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
17991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return true;
18091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
18191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
182fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic bool validatePointerProperties(JNIEnv* env, jobject pointerPropertiesObj) {
183fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!pointerPropertiesObj) {
184fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jniThrowException(env, "java/lang/IllegalArgumentException",
185fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "pointerProperties must not be null");
186fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        return false;
187fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
188fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return true;
189fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
190fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
19191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj,
19291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        float xOffset, float yOffset, PointerCoords* outRawPointerCoords) {
19391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    outRawPointerCoords->clear();
194ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_X,
19591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.x) - xOffset);
196ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_Y,
19791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.y) - yOffset);
198ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
19991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.pressure));
200ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_SIZE,
20191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.size));
202ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
20391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMajor));
204ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR,
20591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMinor));
206ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR,
20791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMajor));
208ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR,
20991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMinor));
210ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
21191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.orientation));
21291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
2136f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    uint64_t bits = env->GetLongField(pointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits);
21491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (bits) {
21591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jfloatArray valuesArray = jfloatArray(env->GetObjectField(pointerCoordsObj,
21691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                gPointerCoordsClassInfo.mPackedAxisValues));
21791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (valuesArray) {
21891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            jfloat* values = static_cast<jfloat*>(
21991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                    env->GetPrimitiveArrayCritical(valuesArray, NULL));
22091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
22191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            uint32_t index = 0;
22291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            do {
223cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                uint32_t axis = __builtin_ctzll(bits);
2246f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                uint64_t axisBit = 1LL << axis;
22591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                bits &= ~axisBit;
22691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                outRawPointerCoords->setAxisValue(axis, values[index++]);
22791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            } while (bits);
22891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
22991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->ReleasePrimitiveArrayCritical(valuesArray, values, JNI_ABORT);
23091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            env->DeleteLocalRef(valuesArray);
23191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
23291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
23391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
23491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
23591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jfloatArray obtainPackedAxisValuesArray(JNIEnv* env, uint32_t minSize,
23691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jobject outPointerCoordsObj) {
23791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    jfloatArray outValuesArray = jfloatArray(env->GetObjectField(outPointerCoordsObj,
23891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            gPointerCoordsClassInfo.mPackedAxisValues));
23991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (outValuesArray) {
24091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        uint32_t size = env->GetArrayLength(outValuesArray);
24191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (minSize <= size) {
24291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return outValuesArray;
24391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
24491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->DeleteLocalRef(outValuesArray);
24591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
24691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    uint32_t size = 8;
24791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    while (size < minSize) {
24891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size *= 2;
24991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
25091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    outValuesArray = env->NewFloatArray(size);
25191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetObjectField(outPointerCoordsObj,
25291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            gPointerCoordsClassInfo.mPackedAxisValues, outValuesArray);
25391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return outValuesArray;
25491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
25591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
25691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointerCoords,
25791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        float xOffset, float yOffset, jobject outPointerCoordsObj) {
25891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x,
259ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset);
26091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y,
261ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset);
26291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.pressure,
263ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
26491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.size,
265ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_SIZE));
26691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMajor,
267ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR));
26891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMinor,
269ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR));
27091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMajor,
271ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR));
27291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMinor,
273ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR));
27491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.orientation,
275ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
27691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
2776f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    const uint64_t unpackedAxisBits = 0
2786f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_X)
2796f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_Y)
2806f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_PRESSURE)
2816f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_SIZE)
2826f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_TOUCH_MAJOR)
2836f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_TOUCH_MINOR)
2846f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_TOOL_MAJOR)
2856f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_TOOL_MINOR)
2866f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            | (1LL << AMOTION_EVENT_AXIS_ORIENTATION);
2876f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
2886f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    uint64_t outBits = 0;
2896f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    uint64_t remainingBits = rawPointerCoords->bits & ~unpackedAxisBits;
29091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (remainingBits) {
2916f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        uint32_t packedAxesCount = __builtin_popcountll(remainingBits);
29291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jfloatArray outValuesArray = obtainPackedAxisValuesArray(env, packedAxesCount,
29391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                outPointerCoordsObj);
29491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!outValuesArray) {
29591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return; // OOM
29691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
29791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
29891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jfloat* outValues = static_cast<jfloat*>(env->GetPrimitiveArrayCritical(
29991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                outValuesArray, NULL));
30091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
30191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        const float* values = rawPointerCoords->values;
30291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        uint32_t index = 0;
30391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        do {
304cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            uint32_t axis = __builtin_ctzll(remainingBits);
3056f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            uint64_t axisBit = 1LL << axis;
30691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            remainingBits &= ~axisBit;
30791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            outBits |= axisBit;
30891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            outValues[index++] = rawPointerCoords->getAxisValue(axis);
30991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        } while (remainingBits);
31091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
31191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->ReleasePrimitiveArrayCritical(outValuesArray, outValues, 0);
31291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->DeleteLocalRef(outValuesArray);
3131f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    }
3146f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    env->SetLongField(outPointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits, outBits);
31591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
3161f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
317fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic void pointerPropertiesToNative(JNIEnv* env, jobject pointerPropertiesObj,
318fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        PointerProperties* outPointerProperties) {
319fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    outPointerProperties->clear();
320fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    outPointerProperties->id = env->GetIntField(pointerPropertiesObj,
321fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            gPointerPropertiesClassInfo.id);
322fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    outPointerProperties->toolType = env->GetIntField(pointerPropertiesObj,
323fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            gPointerPropertiesClassInfo.toolType);
324fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
325fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
326fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic void pointerPropertiesFromNative(JNIEnv* env, const PointerProperties* pointerProperties,
327fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jobject outPointerPropertiesObj) {
328fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.id,
329fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            pointerProperties->id);
330fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.toolType,
331fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            pointerProperties->toolType);
332fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
333fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
33446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
33591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown// ----------------------------------------------------------------------------
3365c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown
33791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz,
33891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr,
339fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint deviceId, jint source, jint action, jint flags, jint edgeFlags,
340fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint metaState, jint buttonState,
34191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jfloat xOffset, jfloat yOffset, jfloat xPrecision, jfloat yPrecision,
34291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jlong downTimeNanos, jlong eventTimeNanos,
343fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint pointerCount, jobjectArray pointerPropertiesObjArray,
344fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jobjectArray pointerCoordsObjArray) {
34591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerCount(env, pointerCount)
346fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            || !validatePointerPropertiesArray(env, pointerPropertiesObjArray, pointerCount)
34791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            || !validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
34891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return 0;
34991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
35046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
35191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
35291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!event) {
35391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        event = new MotionEvent();
35446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
35546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
356fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    PointerProperties pointerProperties[pointerCount];
35791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    PointerCoords rawPointerCoords[pointerCount];
35891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
35991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (jint i = 0; i < pointerCount; i++) {
360fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jobject pointerPropertiesObj = env->GetObjectArrayElement(pointerPropertiesObjArray, i);
361fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (!pointerPropertiesObj) {
362fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            goto Error;
363fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        }
364fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        pointerPropertiesToNative(env, pointerPropertiesObj, &pointerProperties[i]);
365fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        env->DeleteLocalRef(pointerPropertiesObj);
366fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
36791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
36891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!pointerCoordsObj) {
36991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            jniThrowNullPointerException(env, "pointerCoords");
370fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            goto Error;
37191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
37291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        pointerCoordsToNative(env, pointerCoordsObj, xOffset, yOffset, &rawPointerCoords[i]);
37391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->DeleteLocalRef(pointerCoordsObj);
37491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
37591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
376fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    event->initialize(deviceId, source, action, flags, edgeFlags, metaState, buttonState,
37791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            xOffset, yOffset, xPrecision, yPrecision,
378fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords);
37991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
38091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return reinterpret_cast<jint>(event);
381fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
382fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff BrownError:
383fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!nativePtr) {
384fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        delete event;
385fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
386fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return 0;
38791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
38891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
38991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeCopy(JNIEnv* env, jclass clazz,
39091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint destNativePtr, jint sourceNativePtr, jboolean keepHistory) {
39191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* destEvent = reinterpret_cast<MotionEvent*>(destNativePtr);
39291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!destEvent) {
39391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        destEvent = new MotionEvent();
39491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
39591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* sourceEvent = reinterpret_cast<MotionEvent*>(sourceNativePtr);
39691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    destEvent->copyFrom(sourceEvent, keepHistory);
39791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return reinterpret_cast<jint>(destEvent);
39891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
39991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
40091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeDispose(JNIEnv* env, jclass clazz,
40191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
40291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
40391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    delete event;
40491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
40591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
40691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeAddBatch(JNIEnv* env, jclass clazz,
40791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jlong eventTimeNanos, jobjectArray pointerCoordsObjArray,
40891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint metaState) {
40991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
41091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = event->getPointerCount();
41191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
41291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return;
41391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
41491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
41591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    PointerCoords rawPointerCoords[pointerCount];
41691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
41791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (size_t i = 0; i < pointerCount; i++) {
41891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
41991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!pointerCoordsObj) {
42091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            jniThrowNullPointerException(env, "pointerCoords");
42191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return;
42246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
42391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        pointerCoordsToNative(env, pointerCoordsObj,
42491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                event->getXOffset(), event->getYOffset(), &rawPointerCoords[i]);
42591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        env->DeleteLocalRef(pointerCoordsObj);
42646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
42746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
42891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->addSample(eventTimeNanos, rawPointerCoords);
42991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->setMetaState(event->getMetaState() | metaState);
43091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
43146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
43291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetDeviceId(JNIEnv* env, jclass clazz,
43391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
43491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
43591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getDeviceId();
43646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
43746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
43891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetSource(JNIEnv* env, jclass clazz,
43991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
44091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
44191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getSource();
44291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
44391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
44491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeSetSource(JNIEnv* env, jclass clazz,
44591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint source) {
44691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
44791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->setSource(source);
44891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
44991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
45091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetAction(JNIEnv* env, jclass clazz,
45191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
45291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
45391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getAction();
45491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
45591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
45691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeSetAction(JNIEnv* env, jclass clazz,
45791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint action) {
45891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
45991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->setAction(action);
46091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
46191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
46256194ebec6212e229f4ccdaa4b187166d20013efJeff Brownstatic jboolean android_view_MotionEvent_nativeIsTouchEvent(JNIEnv* env, jclass clazz,
46356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        jint nativePtr) {
46456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
46556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    return event->isTouchEvent();
46656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown}
46756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
46891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetFlags(JNIEnv* env, jclass clazz,
46991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
47091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
47191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getFlags();
47291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
47391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
47421bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brownstatic void android_view_MotionEvent_nativeSetFlags(JNIEnv* env, jclass clazz,
47521bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown        jint nativePtr, jint flags) {
47621bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
47721bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown    event->setFlags(flags);
47821bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown}
47921bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown
48091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetEdgeFlags(JNIEnv* env, jclass clazz,
48191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
48291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
48391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getEdgeFlags();
48491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
48591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
48691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeSetEdgeFlags(JNIEnv* env, jclass clazz,
48791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint edgeFlags) {
48891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
48991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->setEdgeFlags(edgeFlags);
49091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
49191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
49291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetMetaState(JNIEnv* env, jclass clazz,
49391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
49491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
49591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getMetaState();
49691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
49791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
498fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic jint android_view_MotionEvent_nativeGetButtonState(JNIEnv* env, jclass clazz,
499fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr) {
500fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
501fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return event->getButtonState();
502fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
503fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
50491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeOffsetLocation(JNIEnv* env, jclass clazz,
50591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jfloat deltaX, jfloat deltaY) {
50691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
50791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->offsetLocation(deltaX, deltaY);
50891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
50991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
510fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic jfloat android_view_MotionEvent_nativeGetXOffset(JNIEnv* env, jclass clazz,
511fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr) {
512fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
513fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return event->getXOffset();
514fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
515fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
516fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic jfloat android_view_MotionEvent_nativeGetYOffset(JNIEnv* env, jclass clazz,
517fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr) {
518fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
519fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return event->getYOffset();
520fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
521fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
52291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jfloat android_view_MotionEvent_nativeGetXPrecision(JNIEnv* env, jclass clazz,
52391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
52491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
52591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getXPrecision();
52691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
52791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
52891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jfloat android_view_MotionEvent_nativeGetYPrecision(JNIEnv* env, jclass clazz,
52991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
53091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
53191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getYPrecision();
53291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
53391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
53491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jlong android_view_MotionEvent_nativeGetDownTimeNanos(JNIEnv* env, jclass clazz,
53591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
53691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
53791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getDownTime();
53891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
53991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
540fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic void android_view_MotionEvent_nativeSetDownTimeNanos(JNIEnv* env, jclass clazz,
541fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr, jlong downTimeNanos) {
542fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
543fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    event->setDownTime(downTimeNanos);
544fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
545fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
54691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetPointerCount(JNIEnv* env, jclass clazz,
54791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
54891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
54991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return jint(event->getPointerCount());
55091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
55191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
55291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetPointerId(JNIEnv* env, jclass clazz,
55391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint pointerIndex) {
55491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
55591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = event->getPointerCount();
55691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
55791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return -1;
55846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
55991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return event->getPointerId(pointerIndex);
56046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
56146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
562fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic jint android_view_MotionEvent_nativeGetToolType(JNIEnv* env, jclass clazz,
563fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr, jint pointerIndex) {
564fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
565fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    size_t pointerCount = event->getPointerCount();
566fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
567fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        return -1;
568fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
569fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return event->getToolType(pointerIndex);
570fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
571fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
57291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeFindPointerIndex(JNIEnv* env, jclass clazz,
57391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint pointerId) {
57491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
5752ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    return jint(event->findPointerIndex(pointerId));
57691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
57791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
57891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeGetHistorySize(JNIEnv* env, jclass clazz,
57991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr) {
58091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
58191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return jint(event->getHistorySize());
58291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
58320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
58491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jlong android_view_MotionEvent_nativeGetEventTimeNanos(JNIEnv* env, jclass clazz,
58591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint historyPos) {
58691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
58791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (historyPos == HISTORY_CURRENT) {
58891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getEventTime();
58991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    } else {
59091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historySize = event->getHistorySize();
59191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!validateHistoryPos(env, historyPos, historySize)) {
59291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return 0;
59391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
59491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getHistoricalEventTime(historyPos);
59520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
59620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown}
59720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
59891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jfloat android_view_MotionEvent_nativeGetRawAxisValue(JNIEnv* env, jclass clazz,
59991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
60091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
60191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = event->getPointerCount();
60291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
60391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return 0;
60491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
60520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
60691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (historyPos == HISTORY_CURRENT) {
60791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getRawAxisValue(axis, pointerIndex);
60891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    } else {
60991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historySize = event->getHistorySize();
61091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!validateHistoryPos(env, historyPos, historySize)) {
61191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return 0;
61220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        }
61391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getHistoricalRawAxisValue(axis, pointerIndex, historyPos);
61491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
61591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
61620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
61791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jfloat android_view_MotionEvent_nativeGetAxisValue(JNIEnv* env, jclass clazz,
61891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
61991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
62091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = event->getPointerCount();
62191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
62291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return 0;
62391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
62420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
62591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (historyPos == HISTORY_CURRENT) {
62691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getAxisValue(axis, pointerIndex);
62791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    } else {
62891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historySize = event->getHistorySize();
62991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!validateHistoryPos(env, historyPos, historySize)) {
63091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return 0;
63191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
63291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return event->getHistoricalAxisValue(axis, pointerIndex, historyPos);
63320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
63491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
63520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
63691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass clazz,
63791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jint pointerIndex, jint historyPos, jobject outPointerCoordsObj) {
63891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
63991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = event->getPointerCount();
64091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)
64191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            || !validatePointerCoords(env, outPointerCoordsObj)) {
64291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return;
64391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
64420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
64591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    const PointerCoords* rawPointerCoords;
64691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (historyPos == HISTORY_CURRENT) {
64791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        rawPointerCoords = event->getRawPointerCoords(pointerIndex);
64891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    } else {
64991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historySize = event->getHistorySize();
65091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!validateHistoryPos(env, historyPos, historySize)) {
65191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            return;
65291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
65391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        rawPointerCoords = event->getHistoricalRawPointerCoords(pointerIndex, historyPos);
65491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
65591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    pointerCoordsFromNative(env, rawPointerCoords, event->getXOffset(), event->getYOffset(),
65691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            outPointerCoordsObj);
65791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
65891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
659fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic void android_view_MotionEvent_nativeGetPointerProperties(JNIEnv* env, jclass clazz,
660fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        jint nativePtr, jint pointerIndex, jobject outPointerPropertiesObj) {
661fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
662fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    size_t pointerCount = event->getPointerCount();
663fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!validatePointerIndex(env, pointerIndex, pointerCount)
664fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            || !validatePointerProperties(env, outPointerPropertiesObj)) {
665fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        return;
666fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
667fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
668fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    const PointerProperties* pointerProperties = event->getPointerProperties(pointerIndex);
669fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    pointerPropertiesFromNative(env, pointerProperties, outPointerPropertiesObj);
670fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
671fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
67291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeScale(JNIEnv* env, jclass clazz,
67391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jfloat scale) {
67491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
67591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    event->scale(scale);
67691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
67791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
67891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeTransform(JNIEnv* env, jclass clazz,
67991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jobject matrixObj) {
68091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
68191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
68211093285c2af1d0842009079c7bd68478566b5e4Jeff Brown
68311093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    float m[9];
68411093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    m[0] = SkScalarToFloat(matrix->get(SkMatrix::kMScaleX));
68511093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    m[1] = SkScalarToFloat(matrix->get(SkMatrix::kMSkewX));
68611093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    m[2] = SkScalarToFloat(matrix->get(SkMatrix::kMTransX));
68711093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    m[3] = SkScalarToFloat(matrix->get(SkMatrix::kMSkewY));
68811093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    m[4] = SkScalarToFloat(matrix->get(SkMatrix::kMScaleY));
68911093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    m[5] = SkScalarToFloat(matrix->get(SkMatrix::kMTransY));
69011093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    m[6] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp0));
69111093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    m[7] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp1));
69211093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    m[8] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp2));
69311093285c2af1d0842009079c7bd68478566b5e4Jeff Brown    event->transform(m);
69491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
69591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
69691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic jint android_view_MotionEvent_nativeReadFromParcel(JNIEnv* env, jclass clazz,
69791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jobject parcelObj) {
69891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
69991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (!event) {
70091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        event = new MotionEvent();
70191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
70291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
70391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    Parcel* parcel = parcelForJavaObject(env, parcelObj);
70420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
70591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    status_t status = event->readFromParcel(parcel);
706ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    if (status) {
70791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (!nativePtr) {
70891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            delete event;
70991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
71091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowRuntimeException(env, "Failed to read MotionEvent parcel.");
71191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return 0;
71291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
71391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return reinterpret_cast<jint>(event);
71491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
71591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
71691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic void android_view_MotionEvent_nativeWriteToParcel(JNIEnv* env, jclass clazz,
71791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jint nativePtr, jobject parcelObj) {
71891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
71991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    Parcel* parcel = parcelForJavaObject(env, parcelObj);
72091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
72191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    status_t status = event->writeToParcel(parcel);
722ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    if (status) {
72391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        jniThrowRuntimeException(env, "Failed to write MotionEvent parcel.");
72491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
72520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown}
72620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
72746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
72846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
72920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brownstatic JNINativeMethod gMotionEventMethods[] = {
73020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    /* name, signature, funcPtr */
73191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeInitialize",
732fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(IIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;"
733fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    "[Landroid/view/MotionEvent$PointerCoords;)I",
73491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeInitialize },
73591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeCopy",
73691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IIZ)I",
73791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeCopy },
73891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeDispose",
73991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)V",
74091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeDispose },
74191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeAddBatch",
74291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IJ[Landroid/view/MotionEvent$PointerCoords;I)V",
74391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeAddBatch },
74491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetDeviceId",
74591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
74691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetDeviceId },
74791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetSource",
74891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
74991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetSource },
75091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeSetSource",
75191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)I",
75291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeSetSource },
75391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetAction",
75491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
75591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetAction },
75691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeSetAction",
75791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)V",
75891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeSetAction },
75956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    { "nativeIsTouchEvent",
76056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown            "(I)Z",
76156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown            (void*)android_view_MotionEvent_nativeIsTouchEvent },
76291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetFlags",
76391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
76491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetFlags },
76521bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown    { "nativeSetFlags",
76621bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown            "(II)V",
76721bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown            (void*)android_view_MotionEvent_nativeSetFlags },
76891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetEdgeFlags",
76991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
77091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetEdgeFlags },
77191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeSetEdgeFlags",
77291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)V",
77391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeSetEdgeFlags },
77491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetMetaState",
77591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
77691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetMetaState },
777fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeGetButtonState",
778fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(I)I",
779fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeGetButtonState },
78091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeOffsetLocation",
78191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IFF)V",
78291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeOffsetLocation },
783fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeGetXOffset",
784fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(I)F",
785fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeGetXOffset },
786fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeGetYOffset",
787fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(I)F",
788fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeGetYOffset },
78991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetXPrecision",
79091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)F",
79191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetXPrecision },
79291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetYPrecision",
79391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)F",
79491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetYPrecision },
79591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetDownTimeNanos",
79691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)J",
79791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetDownTimeNanos },
798fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeSetDownTimeNanos",
799fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(IJ)V",
800fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeSetDownTimeNanos },
80191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetPointerCount",
80291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
80391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetPointerCount },
80491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetPointerId",
80591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)I",
80691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetPointerId },
807fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeGetToolType",
808fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(II)I",
809fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeGetToolType },
81091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeFindPointerIndex",
81191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)I",
81291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeFindPointerIndex },
81391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetHistorySize",
81491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(I)I",
81591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetHistorySize },
81691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetEventTimeNanos",
81791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(II)J",
81891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetEventTimeNanos },
81991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetRawAxisValue",
82091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IIII)F",
82191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetRawAxisValue },
82291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetAxisValue",
82391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IIII)F",
82491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetAxisValue },
82591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeGetPointerCoords",
82691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IIILandroid/view/MotionEvent$PointerCoords;)V",
82791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeGetPointerCoords },
828fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    { "nativeGetPointerProperties",
829fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "(IILandroid/view/MotionEvent$PointerProperties;)V",
830fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (void*)android_view_MotionEvent_nativeGetPointerProperties },
83191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeScale",
83291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(IF)V",
83391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeScale },
83420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    { "nativeTransform",
83591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(ILandroid/graphics/Matrix;)V",
83620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            (void*)android_view_MotionEvent_nativeTransform },
83791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeReadFromParcel",
83891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(ILandroid/os/Parcel;)I",
83991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeReadFromParcel },
84091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    { "nativeWriteToParcel",
84191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "(ILandroid/os/Parcel;)V",
84291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            (void*)android_view_MotionEvent_nativeWriteToParcel },
84320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown};
84420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
84546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define FIND_CLASS(var, className) \
84646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->FindClass(className); \
84717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro        LOG_FATAL_IF(! var, "Unable to find class " className);
84846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
84946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
85046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
85146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find static method" methodName);
85246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
85346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
85446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
85546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find method" methodName);
85646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
85746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
85846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
85946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
86046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
86146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownint register_android_view_MotionEvent(JNIEnv* env) {
86220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    int res = jniRegisterNativeMethods(env, "android/view/MotionEvent",
86320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            gMotionEventMethods, NELEM(gMotionEventMethods));
86420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
86520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
86646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
86717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
86846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
86946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
87091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "obtain", "()Landroid/view/MotionEvent;");
87146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
87246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "recycle", "()V");
87391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    GET_FIELD_ID(gMotionEventClassInfo.mNativePtr, gMotionEventClassInfo.clazz,
87491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "mNativePtr", "I");
87591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
87617cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    jclass clazz;
87717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    FIND_CLASS(clazz, "android/view/MotionEvent$PointerCoords");
87891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
87917cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, clazz,
8806f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            "mPackedAxisBits", "J");
88117cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, clazz,
88291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "mPackedAxisValues", "[F");
88317cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.x, clazz,
88491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "x", "F");
88517cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.y, clazz,
88691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "y", "F");
88717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.pressure, clazz,
88891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "pressure", "F");
88917cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.size, clazz,
89091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "size", "F");
89117cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.touchMajor, clazz,
89291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "touchMajor", "F");
89317cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.touchMinor, clazz,
89491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "touchMinor", "F");
89517cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.toolMajor, clazz,
89691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "toolMajor", "F");
89717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.toolMinor, clazz,
89891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "toolMinor", "F");
89917cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gPointerCoordsClassInfo.orientation, clazz,
90091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "orientation", "F");
90146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
902fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    FIND_CLASS(clazz, "android/view/MotionEvent$PointerProperties");
903fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
904fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    GET_FIELD_ID(gPointerPropertiesClassInfo.id, clazz,
905fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "id", "I");
906fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    GET_FIELD_ID(gPointerPropertiesClassInfo.toolType, clazz,
907fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "toolType", "I");
908fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
90946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return 0;
91046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
91146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
91246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
913