blob: ad6c0f26975aa60d0d0f996131d91adc8e2595db [file] [log] [blame]
Jeff Brown46b9ac02010-04-22 18:58:52 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "MotionEvent-JNI"
18
19#include "JNIHelp.h"
20
Jeff Brown48a3d982013-07-15 17:31:32 -070021#include <SkMatrix.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070022#include <android_runtime/AndroidRuntime.h>
23#include <utils/Log.h>
Jeff Brown9d3b1a42013-07-01 19:07:15 -070024#include <input/Input.h>
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080025#include "android_os_Parcel.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070026#include "android_view_MotionEvent.h"
Jeff Brown91c69ab2011-02-14 17:03:18 -080027#include "android_util_Binder.h"
Jeff Brown20e987b2010-08-23 12:01:02 -070028#include "android/graphics/Matrix.h"
29
Jeff Brown46b9ac02010-04-22 18:58:52 -070030namespace android {
31
32// ----------------------------------------------------------------------------
33
34static struct {
35 jclass clazz;
36
37 jmethodID obtain;
38 jmethodID recycle;
39
Jeff Brown91c69ab2011-02-14 17:03:18 -080040 jfieldID mNativePtr;
Jeff Brown46b9ac02010-04-22 18:58:52 -070041} gMotionEventClassInfo;
42
Jeff Brown91c69ab2011-02-14 17:03:18 -080043static struct {
Jeff Brown91c69ab2011-02-14 17:03:18 -080044 jfieldID mPackedAxisBits;
45 jfieldID mPackedAxisValues;
46 jfieldID x;
47 jfieldID y;
48 jfieldID pressure;
49 jfieldID size;
50 jfieldID touchMajor;
51 jfieldID touchMinor;
52 jfieldID toolMajor;
53 jfieldID toolMinor;
54 jfieldID orientation;
55} gPointerCoordsClassInfo;
56
Jeff Brownfe9f8ab2011-05-06 18:20:01 -070057static struct {
58 jfieldID id;
59 jfieldID toolType;
60} gPointerPropertiesClassInfo;
61
Jeff Brown46b9ac02010-04-22 18:58:52 -070062// ----------------------------------------------------------------------------
63
Jeff Brown2ed24622011-03-14 19:39:54 -070064MotionEvent* android_view_MotionEvent_getNativePtr(JNIEnv* env, jobject eventObj) {
65 if (!eventObj) {
66 return NULL;
67 }
Jeff Brown91c69ab2011-02-14 17:03:18 -080068 return reinterpret_cast<MotionEvent*>(
69 env->GetIntField(eventObj, gMotionEventClassInfo.mNativePtr));
70}
Jeff Brown46b9ac02010-04-22 18:58:52 -070071
Jeff Brown91c69ab2011-02-14 17:03:18 -080072static void android_view_MotionEvent_setNativePtr(JNIEnv* env, jobject eventObj,
73 MotionEvent* event) {
74 env->SetIntField(eventObj, gMotionEventClassInfo.mNativePtr,
75 reinterpret_cast<int>(event));
76}
77
Jeff Brown2ed24622011-03-14 19:39:54 -070078jobject android_view_MotionEvent_obtainAsCopy(JNIEnv* env, const MotionEvent* event) {
Jeff Brown46b9ac02010-04-22 18:58:52 -070079 jobject eventObj = env->CallStaticObjectMethod(gMotionEventClassInfo.clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -080080 gMotionEventClassInfo.obtain);
Jeff Brown2ed24622011-03-14 19:39:54 -070081 if (env->ExceptionCheck() || !eventObj) {
Steve Block3762c312012-01-06 19:20:56 +000082 ALOGE("An exception occurred while obtaining a motion event.");
Jeff Brown46b9ac02010-04-22 18:58:52 -070083 LOGE_EX(env);
84 env->ExceptionClear();
85 return NULL;
86 }
87
Jeff Brown91c69ab2011-02-14 17:03:18 -080088 MotionEvent* destEvent = android_view_MotionEvent_getNativePtr(env, eventObj);
89 if (!destEvent) {
90 destEvent = new MotionEvent();
91 android_view_MotionEvent_setNativePtr(env, eventObj, destEvent);
Jeff Brown46b9ac02010-04-22 18:58:52 -070092 }
93
Jeff Brown91c69ab2011-02-14 17:03:18 -080094 destEvent->copyFrom(event, true);
Jeff Brown46b9ac02010-04-22 18:58:52 -070095 return eventObj;
96}
97
Jeff Brown1f245102010-11-18 20:53:46 -080098status_t android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj) {
Jeff Brown46b9ac02010-04-22 18:58:52 -070099 env->CallVoidMethod(eventObj, gMotionEventClassInfo.recycle);
100 if (env->ExceptionCheck()) {
Steve Block8564c8d2012-01-05 23:22:43 +0000101 ALOGW("An exception occurred while recycling a motion event.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700102 LOGW_EX(env);
103 env->ExceptionClear();
Jeff Brown1f245102010-11-18 20:53:46 -0800104 return UNKNOWN_ERROR;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700105 }
Jeff Brown1f245102010-11-18 20:53:46 -0800106 return OK;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700107}
108
Jeff Brown91c69ab2011-02-14 17:03:18 -0800109// ----------------------------------------------------------------------------
Jeff Brown20e987b2010-08-23 12:01:02 -0700110
Jeff Brown91c69ab2011-02-14 17:03:18 -0800111static const jint HISTORY_CURRENT = -0x80000000;
112
113static bool validatePointerCount(JNIEnv* env, jint pointerCount) {
114 if (pointerCount < 1) {
115 jniThrowException(env, "java/lang/IllegalArgumentException",
116 "pointerCount must be at least 1");
117 return false;
Jeff Brown20e987b2010-08-23 12:01:02 -0700118 }
Jeff Brown91c69ab2011-02-14 17:03:18 -0800119 return true;
Jeff Brown20e987b2010-08-23 12:01:02 -0700120}
121
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700122static bool validatePointerPropertiesArray(JNIEnv* env, jobjectArray pointerPropertiesObjArray,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800123 size_t pointerCount) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700124 if (!pointerPropertiesObjArray) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800125 jniThrowException(env, "java/lang/IllegalArgumentException",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700126 "pointerProperties array must not be null");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800127 return false;
128 }
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700129 size_t length = size_t(env->GetArrayLength(pointerPropertiesObjArray));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800130 if (length < pointerCount) {
131 jniThrowException(env, "java/lang/IllegalArgumentException",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700132 "pointerProperties array must be large enough to hold all pointers");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800133 return false;
134 }
135 return true;
136}
Jeff Brown20e987b2010-08-23 12:01:02 -0700137
Jeff Brown91c69ab2011-02-14 17:03:18 -0800138static bool validatePointerCoordsObjArray(JNIEnv* env, jobjectArray pointerCoordsObjArray,
139 size_t pointerCount) {
140 if (!pointerCoordsObjArray) {
141 jniThrowException(env, "java/lang/IllegalArgumentException",
142 "pointerCoords array must not be null");
143 return false;
144 }
145 size_t length = size_t(env->GetArrayLength(pointerCoordsObjArray));
146 if (length < pointerCount) {
147 jniThrowException(env, "java/lang/IllegalArgumentException",
148 "pointerCoords array must be large enough to hold all pointers");
149 return false;
150 }
151 return true;
152}
Jeff Brown20e987b2010-08-23 12:01:02 -0700153
Jeff Brown91c69ab2011-02-14 17:03:18 -0800154static bool validatePointerIndex(JNIEnv* env, jint pointerIndex, size_t pointerCount) {
155 if (pointerIndex < 0 || size_t(pointerIndex) >= pointerCount) {
156 jniThrowException(env, "java/lang/IllegalArgumentException",
157 "pointerIndex out of range");
158 return false;
159 }
160 return true;
161}
Jeff Brown20e987b2010-08-23 12:01:02 -0700162
Jeff Brown91c69ab2011-02-14 17:03:18 -0800163static bool validateHistoryPos(JNIEnv* env, jint historyPos, size_t historySize) {
164 if (historyPos < 0 || size_t(historyPos) >= historySize) {
165 jniThrowException(env, "java/lang/IllegalArgumentException",
166 "historyPos out of range");
167 return false;
168 }
169 return true;
170}
Jeff Brown20e987b2010-08-23 12:01:02 -0700171
Jeff Brown91c69ab2011-02-14 17:03:18 -0800172static bool validatePointerCoords(JNIEnv* env, jobject pointerCoordsObj) {
173 if (!pointerCoordsObj) {
174 jniThrowException(env, "java/lang/IllegalArgumentException",
175 "pointerCoords must not be null");
176 return false;
177 }
178 return true;
179}
180
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700181static bool validatePointerProperties(JNIEnv* env, jobject pointerPropertiesObj) {
182 if (!pointerPropertiesObj) {
183 jniThrowException(env, "java/lang/IllegalArgumentException",
184 "pointerProperties must not be null");
185 return false;
186 }
187 return true;
188}
189
Jeff Brown91c69ab2011-02-14 17:03:18 -0800190static void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj,
191 float xOffset, float yOffset, PointerCoords* outRawPointerCoords) {
192 outRawPointerCoords->clear();
Jeff Brownebbd5d12011-02-17 13:01:34 -0800193 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_X,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800194 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.x) - xOffset);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800195 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_Y,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800196 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.y) - yOffset);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800197 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800198 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.pressure));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800199 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_SIZE,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800200 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.size));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800201 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800202 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMajor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800203 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800204 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMinor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800205 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800206 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMajor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800207 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800208 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMinor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800209 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800210 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.orientation));
211
Jeff Brown6f2fba42011-02-19 01:08:02 -0800212 uint64_t bits = env->GetLongField(pointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800213 if (bits) {
214 jfloatArray valuesArray = jfloatArray(env->GetObjectField(pointerCoordsObj,
215 gPointerCoordsClassInfo.mPackedAxisValues));
216 if (valuesArray) {
217 jfloat* values = static_cast<jfloat*>(
218 env->GetPrimitiveArrayCritical(valuesArray, NULL));
219
220 uint32_t index = 0;
221 do {
Jeff Browncc0c1592011-02-19 05:07:28 -0800222 uint32_t axis = __builtin_ctzll(bits);
Jeff Brown6f2fba42011-02-19 01:08:02 -0800223 uint64_t axisBit = 1LL << axis;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800224 bits &= ~axisBit;
225 outRawPointerCoords->setAxisValue(axis, values[index++]);
226 } while (bits);
227
228 env->ReleasePrimitiveArrayCritical(valuesArray, values, JNI_ABORT);
229 env->DeleteLocalRef(valuesArray);
230 }
231 }
232}
233
234static jfloatArray obtainPackedAxisValuesArray(JNIEnv* env, uint32_t minSize,
235 jobject outPointerCoordsObj) {
236 jfloatArray outValuesArray = jfloatArray(env->GetObjectField(outPointerCoordsObj,
237 gPointerCoordsClassInfo.mPackedAxisValues));
238 if (outValuesArray) {
239 uint32_t size = env->GetArrayLength(outValuesArray);
240 if (minSize <= size) {
241 return outValuesArray;
242 }
243 env->DeleteLocalRef(outValuesArray);
244 }
245 uint32_t size = 8;
246 while (size < minSize) {
247 size *= 2;
248 }
249 outValuesArray = env->NewFloatArray(size);
250 env->SetObjectField(outPointerCoordsObj,
251 gPointerCoordsClassInfo.mPackedAxisValues, outValuesArray);
252 return outValuesArray;
253}
254
255static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointerCoords,
256 float xOffset, float yOffset, jobject outPointerCoordsObj) {
257 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800258 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800259 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800260 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800261 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.pressure,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800262 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800263 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.size,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800264 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_SIZE));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800265 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMajor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800266 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800267 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMinor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800268 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800269 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMajor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800270 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800271 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMinor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800272 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800273 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.orientation,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800274 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800275
Jeff Brown6f2fba42011-02-19 01:08:02 -0800276 const uint64_t unpackedAxisBits = 0
277 | (1LL << AMOTION_EVENT_AXIS_X)
278 | (1LL << AMOTION_EVENT_AXIS_Y)
279 | (1LL << AMOTION_EVENT_AXIS_PRESSURE)
280 | (1LL << AMOTION_EVENT_AXIS_SIZE)
281 | (1LL << AMOTION_EVENT_AXIS_TOUCH_MAJOR)
282 | (1LL << AMOTION_EVENT_AXIS_TOUCH_MINOR)
283 | (1LL << AMOTION_EVENT_AXIS_TOOL_MAJOR)
284 | (1LL << AMOTION_EVENT_AXIS_TOOL_MINOR)
285 | (1LL << AMOTION_EVENT_AXIS_ORIENTATION);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800286
Jeff Brown6f2fba42011-02-19 01:08:02 -0800287 uint64_t outBits = 0;
288 uint64_t remainingBits = rawPointerCoords->bits & ~unpackedAxisBits;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800289 if (remainingBits) {
Jeff Brown6f2fba42011-02-19 01:08:02 -0800290 uint32_t packedAxesCount = __builtin_popcountll(remainingBits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800291 jfloatArray outValuesArray = obtainPackedAxisValuesArray(env, packedAxesCount,
292 outPointerCoordsObj);
293 if (!outValuesArray) {
294 return; // OOM
Jeff Brown20e987b2010-08-23 12:01:02 -0700295 }
296
Jeff Brown91c69ab2011-02-14 17:03:18 -0800297 jfloat* outValues = static_cast<jfloat*>(env->GetPrimitiveArrayCritical(
298 outValuesArray, NULL));
Jeff Brown20e987b2010-08-23 12:01:02 -0700299
Jeff Brown91c69ab2011-02-14 17:03:18 -0800300 const float* values = rawPointerCoords->values;
301 uint32_t index = 0;
302 do {
Jeff Browncc0c1592011-02-19 05:07:28 -0800303 uint32_t axis = __builtin_ctzll(remainingBits);
Jeff Brown6f2fba42011-02-19 01:08:02 -0800304 uint64_t axisBit = 1LL << axis;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800305 remainingBits &= ~axisBit;
306 outBits |= axisBit;
307 outValues[index++] = rawPointerCoords->getAxisValue(axis);
308 } while (remainingBits);
309
310 env->ReleasePrimitiveArrayCritical(outValuesArray, outValues, 0);
311 env->DeleteLocalRef(outValuesArray);
312 }
Jeff Brown6f2fba42011-02-19 01:08:02 -0800313 env->SetLongField(outPointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits, outBits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800314}
315
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700316static void pointerPropertiesToNative(JNIEnv* env, jobject pointerPropertiesObj,
317 PointerProperties* outPointerProperties) {
318 outPointerProperties->clear();
319 outPointerProperties->id = env->GetIntField(pointerPropertiesObj,
320 gPointerPropertiesClassInfo.id);
321 outPointerProperties->toolType = env->GetIntField(pointerPropertiesObj,
322 gPointerPropertiesClassInfo.toolType);
323}
324
325static void pointerPropertiesFromNative(JNIEnv* env, const PointerProperties* pointerProperties,
326 jobject outPointerPropertiesObj) {
327 env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.id,
328 pointerProperties->id);
329 env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.toolType,
330 pointerProperties->toolType);
331}
332
Jeff Brown91c69ab2011-02-14 17:03:18 -0800333
334// ----------------------------------------------------------------------------
335
336static jint android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz,
337 jint nativePtr,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700338 jint deviceId, jint source, jint action, jint flags, jint edgeFlags,
339 jint metaState, jint buttonState,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800340 jfloat xOffset, jfloat yOffset, jfloat xPrecision, jfloat yPrecision,
341 jlong downTimeNanos, jlong eventTimeNanos,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700342 jint pointerCount, jobjectArray pointerPropertiesObjArray,
343 jobjectArray pointerCoordsObjArray) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800344 if (!validatePointerCount(env, pointerCount)
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700345 || !validatePointerPropertiesArray(env, pointerPropertiesObjArray, pointerCount)
Jeff Brown91c69ab2011-02-14 17:03:18 -0800346 || !validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
347 return 0;
Jeff Brown20e987b2010-08-23 12:01:02 -0700348 }
349
Jeff Brown91c69ab2011-02-14 17:03:18 -0800350 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
351 if (!event) {
352 event = new MotionEvent();
353 }
Jeff Brown20e987b2010-08-23 12:01:02 -0700354
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700355 PointerProperties pointerProperties[pointerCount];
Jeff Brown91c69ab2011-02-14 17:03:18 -0800356 PointerCoords rawPointerCoords[pointerCount];
Jeff Brown20e987b2010-08-23 12:01:02 -0700357
Jeff Brown91c69ab2011-02-14 17:03:18 -0800358 for (jint i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700359 jobject pointerPropertiesObj = env->GetObjectArrayElement(pointerPropertiesObjArray, i);
360 if (!pointerPropertiesObj) {
361 goto Error;
362 }
363 pointerPropertiesToNative(env, pointerPropertiesObj, &pointerProperties[i]);
364 env->DeleteLocalRef(pointerPropertiesObj);
365
Jeff Brown91c69ab2011-02-14 17:03:18 -0800366 jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
367 if (!pointerCoordsObj) {
368 jniThrowNullPointerException(env, "pointerCoords");
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700369 goto Error;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800370 }
371 pointerCoordsToNative(env, pointerCoordsObj, xOffset, yOffset, &rawPointerCoords[i]);
372 env->DeleteLocalRef(pointerCoordsObj);
373 }
374
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700375 event->initialize(deviceId, source, action, flags, edgeFlags, metaState, buttonState,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800376 xOffset, yOffset, xPrecision, yPrecision,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700377 downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800378
Jeff Brown91c69ab2011-02-14 17:03:18 -0800379 return reinterpret_cast<jint>(event);
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700380
381Error:
382 if (!nativePtr) {
383 delete event;
384 }
385 return 0;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800386}
387
388static jint android_view_MotionEvent_nativeCopy(JNIEnv* env, jclass clazz,
389 jint destNativePtr, jint sourceNativePtr, jboolean keepHistory) {
390 MotionEvent* destEvent = reinterpret_cast<MotionEvent*>(destNativePtr);
391 if (!destEvent) {
392 destEvent = new MotionEvent();
393 }
394 MotionEvent* sourceEvent = reinterpret_cast<MotionEvent*>(sourceNativePtr);
395 destEvent->copyFrom(sourceEvent, keepHistory);
396 return reinterpret_cast<jint>(destEvent);
397}
398
399static void android_view_MotionEvent_nativeDispose(JNIEnv* env, jclass clazz,
400 jint nativePtr) {
401 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
402 delete event;
403}
404
405static void android_view_MotionEvent_nativeAddBatch(JNIEnv* env, jclass clazz,
406 jint nativePtr, jlong eventTimeNanos, jobjectArray pointerCoordsObjArray,
407 jint metaState) {
408 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
409 size_t pointerCount = event->getPointerCount();
410 if (!validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
411 return;
412 }
413
414 PointerCoords rawPointerCoords[pointerCount];
415
416 for (size_t i = 0; i < pointerCount; i++) {
417 jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
418 if (!pointerCoordsObj) {
419 jniThrowNullPointerException(env, "pointerCoords");
420 return;
421 }
422 pointerCoordsToNative(env, pointerCoordsObj,
423 event->getXOffset(), event->getYOffset(), &rawPointerCoords[i]);
424 env->DeleteLocalRef(pointerCoordsObj);
425 }
426
427 event->addSample(eventTimeNanos, rawPointerCoords);
428 event->setMetaState(event->getMetaState() | metaState);
429}
430
431static jint android_view_MotionEvent_nativeGetDeviceId(JNIEnv* env, jclass clazz,
432 jint nativePtr) {
433 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
434 return event->getDeviceId();
435}
436
437static jint android_view_MotionEvent_nativeGetSource(JNIEnv* env, jclass clazz,
438 jint nativePtr) {
439 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
440 return event->getSource();
441}
442
443static void android_view_MotionEvent_nativeSetSource(JNIEnv* env, jclass clazz,
444 jint nativePtr, jint source) {
445 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
446 event->setSource(source);
447}
448
449static jint android_view_MotionEvent_nativeGetAction(JNIEnv* env, jclass clazz,
450 jint nativePtr) {
451 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
452 return event->getAction();
453}
454
455static void android_view_MotionEvent_nativeSetAction(JNIEnv* env, jclass clazz,
456 jint nativePtr, jint action) {
457 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
458 event->setAction(action);
459}
460
Jeff Brown56194eb2011-03-02 19:23:13 -0800461static jboolean android_view_MotionEvent_nativeIsTouchEvent(JNIEnv* env, jclass clazz,
462 jint nativePtr) {
463 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
464 return event->isTouchEvent();
465}
466
Jeff Brown91c69ab2011-02-14 17:03:18 -0800467static jint android_view_MotionEvent_nativeGetFlags(JNIEnv* env, jclass clazz,
468 jint nativePtr) {
469 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
470 return event->getFlags();
471}
472
Jeff Brown21bc5c92011-02-28 18:27:14 -0800473static void android_view_MotionEvent_nativeSetFlags(JNIEnv* env, jclass clazz,
474 jint nativePtr, jint flags) {
475 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
476 event->setFlags(flags);
477}
478
Jeff Brown91c69ab2011-02-14 17:03:18 -0800479static jint android_view_MotionEvent_nativeGetEdgeFlags(JNIEnv* env, jclass clazz,
480 jint nativePtr) {
481 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
482 return event->getEdgeFlags();
483}
484
485static void android_view_MotionEvent_nativeSetEdgeFlags(JNIEnv* env, jclass clazz,
486 jint nativePtr, jint edgeFlags) {
487 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
488 event->setEdgeFlags(edgeFlags);
489}
490
491static jint android_view_MotionEvent_nativeGetMetaState(JNIEnv* env, jclass clazz,
492 jint nativePtr) {
493 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
494 return event->getMetaState();
495}
496
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700497static jint android_view_MotionEvent_nativeGetButtonState(JNIEnv* env, jclass clazz,
498 jint nativePtr) {
499 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
500 return event->getButtonState();
501}
502
Jeff Brown91c69ab2011-02-14 17:03:18 -0800503static void android_view_MotionEvent_nativeOffsetLocation(JNIEnv* env, jclass clazz,
504 jint nativePtr, jfloat deltaX, jfloat deltaY) {
505 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
506 return event->offsetLocation(deltaX, deltaY);
507}
508
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700509static jfloat android_view_MotionEvent_nativeGetXOffset(JNIEnv* env, jclass clazz,
510 jint nativePtr) {
511 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
512 return event->getXOffset();
513}
514
515static jfloat android_view_MotionEvent_nativeGetYOffset(JNIEnv* env, jclass clazz,
516 jint nativePtr) {
517 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
518 return event->getYOffset();
519}
520
Jeff Brown91c69ab2011-02-14 17:03:18 -0800521static jfloat android_view_MotionEvent_nativeGetXPrecision(JNIEnv* env, jclass clazz,
522 jint nativePtr) {
523 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
524 return event->getXPrecision();
525}
526
527static jfloat android_view_MotionEvent_nativeGetYPrecision(JNIEnv* env, jclass clazz,
528 jint nativePtr) {
529 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
530 return event->getYPrecision();
531}
532
533static jlong android_view_MotionEvent_nativeGetDownTimeNanos(JNIEnv* env, jclass clazz,
534 jint nativePtr) {
535 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
536 return event->getDownTime();
537}
538
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700539static void android_view_MotionEvent_nativeSetDownTimeNanos(JNIEnv* env, jclass clazz,
540 jint nativePtr, jlong downTimeNanos) {
541 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
542 event->setDownTime(downTimeNanos);
543}
544
Jeff Brown91c69ab2011-02-14 17:03:18 -0800545static jint android_view_MotionEvent_nativeGetPointerCount(JNIEnv* env, jclass clazz,
546 jint nativePtr) {
547 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
548 return jint(event->getPointerCount());
549}
550
551static jint android_view_MotionEvent_nativeGetPointerId(JNIEnv* env, jclass clazz,
552 jint nativePtr, jint pointerIndex) {
553 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
554 size_t pointerCount = event->getPointerCount();
555 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
556 return -1;
557 }
558 return event->getPointerId(pointerIndex);
559}
560
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700561static jint android_view_MotionEvent_nativeGetToolType(JNIEnv* env, jclass clazz,
562 jint nativePtr, jint pointerIndex) {
563 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
564 size_t pointerCount = event->getPointerCount();
565 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
566 return -1;
567 }
568 return event->getToolType(pointerIndex);
569}
570
Jeff Brown91c69ab2011-02-14 17:03:18 -0800571static jint android_view_MotionEvent_nativeFindPointerIndex(JNIEnv* env, jclass clazz,
572 jint nativePtr, jint pointerId) {
573 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
Jeff Brown2ed24622011-03-14 19:39:54 -0700574 return jint(event->findPointerIndex(pointerId));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800575}
576
577static jint android_view_MotionEvent_nativeGetHistorySize(JNIEnv* env, jclass clazz,
578 jint nativePtr) {
579 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
580 return jint(event->getHistorySize());
581}
582
583static jlong android_view_MotionEvent_nativeGetEventTimeNanos(JNIEnv* env, jclass clazz,
584 jint nativePtr, jint historyPos) {
585 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
586 if (historyPos == HISTORY_CURRENT) {
587 return event->getEventTime();
588 } else {
589 size_t historySize = event->getHistorySize();
590 if (!validateHistoryPos(env, historyPos, historySize)) {
591 return 0;
592 }
593 return event->getHistoricalEventTime(historyPos);
594 }
595}
596
597static jfloat android_view_MotionEvent_nativeGetRawAxisValue(JNIEnv* env, jclass clazz,
598 jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
599 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
600 size_t pointerCount = event->getPointerCount();
601 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
602 return 0;
603 }
604
605 if (historyPos == HISTORY_CURRENT) {
606 return event->getRawAxisValue(axis, pointerIndex);
607 } else {
608 size_t historySize = event->getHistorySize();
609 if (!validateHistoryPos(env, historyPos, historySize)) {
610 return 0;
611 }
612 return event->getHistoricalRawAxisValue(axis, pointerIndex, historyPos);
613 }
614}
615
616static jfloat android_view_MotionEvent_nativeGetAxisValue(JNIEnv* env, jclass clazz,
617 jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
618 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
619 size_t pointerCount = event->getPointerCount();
620 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
621 return 0;
622 }
623
624 if (historyPos == HISTORY_CURRENT) {
625 return event->getAxisValue(axis, pointerIndex);
626 } else {
627 size_t historySize = event->getHistorySize();
628 if (!validateHistoryPos(env, historyPos, historySize)) {
629 return 0;
630 }
631 return event->getHistoricalAxisValue(axis, pointerIndex, historyPos);
632 }
633}
634
635static void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass clazz,
636 jint nativePtr, jint pointerIndex, jint historyPos, jobject outPointerCoordsObj) {
637 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
638 size_t pointerCount = event->getPointerCount();
639 if (!validatePointerIndex(env, pointerIndex, pointerCount)
640 || !validatePointerCoords(env, outPointerCoordsObj)) {
641 return;
642 }
643
644 const PointerCoords* rawPointerCoords;
645 if (historyPos == HISTORY_CURRENT) {
646 rawPointerCoords = event->getRawPointerCoords(pointerIndex);
647 } else {
648 size_t historySize = event->getHistorySize();
649 if (!validateHistoryPos(env, historyPos, historySize)) {
650 return;
651 }
652 rawPointerCoords = event->getHistoricalRawPointerCoords(pointerIndex, historyPos);
653 }
654 pointerCoordsFromNative(env, rawPointerCoords, event->getXOffset(), event->getYOffset(),
655 outPointerCoordsObj);
656}
657
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700658static void android_view_MotionEvent_nativeGetPointerProperties(JNIEnv* env, jclass clazz,
659 jint nativePtr, jint pointerIndex, jobject outPointerPropertiesObj) {
660 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
661 size_t pointerCount = event->getPointerCount();
662 if (!validatePointerIndex(env, pointerIndex, pointerCount)
663 || !validatePointerProperties(env, outPointerPropertiesObj)) {
664 return;
665 }
666
667 const PointerProperties* pointerProperties = event->getPointerProperties(pointerIndex);
668 pointerPropertiesFromNative(env, pointerProperties, outPointerPropertiesObj);
669}
670
Jeff Brown91c69ab2011-02-14 17:03:18 -0800671static void android_view_MotionEvent_nativeScale(JNIEnv* env, jclass clazz,
672 jint nativePtr, jfloat scale) {
673 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
674 event->scale(scale);
675}
676
677static void android_view_MotionEvent_nativeTransform(JNIEnv* env, jclass clazz,
678 jint nativePtr, jobject matrixObj) {
679 SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
680 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
Jeff Brown11093282013-07-15 18:05:59 -0700681
682 float m[9];
683 m[0] = SkScalarToFloat(matrix->get(SkMatrix::kMScaleX));
684 m[1] = SkScalarToFloat(matrix->get(SkMatrix::kMSkewX));
685 m[2] = SkScalarToFloat(matrix->get(SkMatrix::kMTransX));
686 m[3] = SkScalarToFloat(matrix->get(SkMatrix::kMSkewY));
687 m[4] = SkScalarToFloat(matrix->get(SkMatrix::kMScaleY));
688 m[5] = SkScalarToFloat(matrix->get(SkMatrix::kMTransY));
689 m[6] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp0));
690 m[7] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp1));
691 m[8] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp2));
692 event->transform(m);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800693}
694
695static jint android_view_MotionEvent_nativeReadFromParcel(JNIEnv* env, jclass clazz,
696 jint nativePtr, jobject parcelObj) {
697 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
698 if (!event) {
699 event = new MotionEvent();
700 }
701
702 Parcel* parcel = parcelForJavaObject(env, parcelObj);
703
704 status_t status = event->readFromParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800705 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800706 if (!nativePtr) {
707 delete event;
708 }
709 jniThrowRuntimeException(env, "Failed to read MotionEvent parcel.");
710 return 0;
711 }
712 return reinterpret_cast<jint>(event);
713}
714
715static void android_view_MotionEvent_nativeWriteToParcel(JNIEnv* env, jclass clazz,
716 jint nativePtr, jobject parcelObj) {
717 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
718 Parcel* parcel = parcelForJavaObject(env, parcelObj);
719
720 status_t status = event->writeToParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800721 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800722 jniThrowRuntimeException(env, "Failed to write MotionEvent parcel.");
723 }
Jeff Brown20e987b2010-08-23 12:01:02 -0700724}
725
Jeff Brown46b9ac02010-04-22 18:58:52 -0700726// ----------------------------------------------------------------------------
727
Jeff Brown20e987b2010-08-23 12:01:02 -0700728static JNINativeMethod gMotionEventMethods[] = {
729 /* name, signature, funcPtr */
Jeff Brown91c69ab2011-02-14 17:03:18 -0800730 { "nativeInitialize",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700731 "(IIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;"
732 "[Landroid/view/MotionEvent$PointerCoords;)I",
Jeff Brown91c69ab2011-02-14 17:03:18 -0800733 (void*)android_view_MotionEvent_nativeInitialize },
734 { "nativeCopy",
735 "(IIZ)I",
736 (void*)android_view_MotionEvent_nativeCopy },
737 { "nativeDispose",
738 "(I)V",
739 (void*)android_view_MotionEvent_nativeDispose },
740 { "nativeAddBatch",
741 "(IJ[Landroid/view/MotionEvent$PointerCoords;I)V",
742 (void*)android_view_MotionEvent_nativeAddBatch },
743 { "nativeGetDeviceId",
744 "(I)I",
745 (void*)android_view_MotionEvent_nativeGetDeviceId },
746 { "nativeGetSource",
747 "(I)I",
748 (void*)android_view_MotionEvent_nativeGetSource },
749 { "nativeSetSource",
750 "(II)I",
751 (void*)android_view_MotionEvent_nativeSetSource },
752 { "nativeGetAction",
753 "(I)I",
754 (void*)android_view_MotionEvent_nativeGetAction },
755 { "nativeSetAction",
756 "(II)V",
757 (void*)android_view_MotionEvent_nativeSetAction },
Jeff Brown56194eb2011-03-02 19:23:13 -0800758 { "nativeIsTouchEvent",
759 "(I)Z",
760 (void*)android_view_MotionEvent_nativeIsTouchEvent },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800761 { "nativeGetFlags",
762 "(I)I",
763 (void*)android_view_MotionEvent_nativeGetFlags },
Jeff Brown21bc5c92011-02-28 18:27:14 -0800764 { "nativeSetFlags",
765 "(II)V",
766 (void*)android_view_MotionEvent_nativeSetFlags },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800767 { "nativeGetEdgeFlags",
768 "(I)I",
769 (void*)android_view_MotionEvent_nativeGetEdgeFlags },
770 { "nativeSetEdgeFlags",
771 "(II)V",
772 (void*)android_view_MotionEvent_nativeSetEdgeFlags },
773 { "nativeGetMetaState",
774 "(I)I",
775 (void*)android_view_MotionEvent_nativeGetMetaState },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700776 { "nativeGetButtonState",
777 "(I)I",
778 (void*)android_view_MotionEvent_nativeGetButtonState },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800779 { "nativeOffsetLocation",
780 "(IFF)V",
781 (void*)android_view_MotionEvent_nativeOffsetLocation },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700782 { "nativeGetXOffset",
783 "(I)F",
784 (void*)android_view_MotionEvent_nativeGetXOffset },
785 { "nativeGetYOffset",
786 "(I)F",
787 (void*)android_view_MotionEvent_nativeGetYOffset },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800788 { "nativeGetXPrecision",
789 "(I)F",
790 (void*)android_view_MotionEvent_nativeGetXPrecision },
791 { "nativeGetYPrecision",
792 "(I)F",
793 (void*)android_view_MotionEvent_nativeGetYPrecision },
794 { "nativeGetDownTimeNanos",
795 "(I)J",
796 (void*)android_view_MotionEvent_nativeGetDownTimeNanos },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700797 { "nativeSetDownTimeNanos",
798 "(IJ)V",
799 (void*)android_view_MotionEvent_nativeSetDownTimeNanos },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800800 { "nativeGetPointerCount",
801 "(I)I",
802 (void*)android_view_MotionEvent_nativeGetPointerCount },
803 { "nativeGetPointerId",
804 "(II)I",
805 (void*)android_view_MotionEvent_nativeGetPointerId },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700806 { "nativeGetToolType",
807 "(II)I",
808 (void*)android_view_MotionEvent_nativeGetToolType },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800809 { "nativeFindPointerIndex",
810 "(II)I",
811 (void*)android_view_MotionEvent_nativeFindPointerIndex },
812 { "nativeGetHistorySize",
813 "(I)I",
814 (void*)android_view_MotionEvent_nativeGetHistorySize },
815 { "nativeGetEventTimeNanos",
816 "(II)J",
817 (void*)android_view_MotionEvent_nativeGetEventTimeNanos },
818 { "nativeGetRawAxisValue",
819 "(IIII)F",
820 (void*)android_view_MotionEvent_nativeGetRawAxisValue },
821 { "nativeGetAxisValue",
822 "(IIII)F",
823 (void*)android_view_MotionEvent_nativeGetAxisValue },
824 { "nativeGetPointerCoords",
825 "(IIILandroid/view/MotionEvent$PointerCoords;)V",
826 (void*)android_view_MotionEvent_nativeGetPointerCoords },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700827 { "nativeGetPointerProperties",
828 "(IILandroid/view/MotionEvent$PointerProperties;)V",
829 (void*)android_view_MotionEvent_nativeGetPointerProperties },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800830 { "nativeScale",
831 "(IF)V",
832 (void*)android_view_MotionEvent_nativeScale },
Jeff Brown20e987b2010-08-23 12:01:02 -0700833 { "nativeTransform",
Jeff Brown91c69ab2011-02-14 17:03:18 -0800834 "(ILandroid/graphics/Matrix;)V",
Jeff Brown20e987b2010-08-23 12:01:02 -0700835 (void*)android_view_MotionEvent_nativeTransform },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800836 { "nativeReadFromParcel",
837 "(ILandroid/os/Parcel;)I",
838 (void*)android_view_MotionEvent_nativeReadFromParcel },
839 { "nativeWriteToParcel",
840 "(ILandroid/os/Parcel;)V",
841 (void*)android_view_MotionEvent_nativeWriteToParcel },
Jeff Brown20e987b2010-08-23 12:01:02 -0700842};
843
Jeff Brown46b9ac02010-04-22 18:58:52 -0700844#define FIND_CLASS(var, className) \
845 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800846 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700847
848#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
849 var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
850 LOG_FATAL_IF(! var, "Unable to find static method" methodName);
851
852#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
853 var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
854 LOG_FATAL_IF(! var, "Unable to find method" methodName);
855
856#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
857 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
858 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
859
860int register_android_view_MotionEvent(JNIEnv* env) {
Jeff Brown20e987b2010-08-23 12:01:02 -0700861 int res = jniRegisterNativeMethods(env, "android/view/MotionEvent",
862 gMotionEventMethods, NELEM(gMotionEventMethods));
863 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
864
Jeff Brown46b9ac02010-04-22 18:58:52 -0700865 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800866 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown46b9ac02010-04-22 18:58:52 -0700867
868 GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800869 "obtain", "()Landroid/view/MotionEvent;");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700870 GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
871 "recycle", "()V");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800872 GET_FIELD_ID(gMotionEventClassInfo.mNativePtr, gMotionEventClassInfo.clazz,
873 "mNativePtr", "I");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700874
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800875 jclass clazz;
876 FIND_CLASS(clazz, "android/view/MotionEvent$PointerCoords");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800877
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800878 GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, clazz,
Jeff Brown6f2fba42011-02-19 01:08:02 -0800879 "mPackedAxisBits", "J");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800880 GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800881 "mPackedAxisValues", "[F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800882 GET_FIELD_ID(gPointerCoordsClassInfo.x, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800883 "x", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800884 GET_FIELD_ID(gPointerCoordsClassInfo.y, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800885 "y", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800886 GET_FIELD_ID(gPointerCoordsClassInfo.pressure, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800887 "pressure", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800888 GET_FIELD_ID(gPointerCoordsClassInfo.size, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800889 "size", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800890 GET_FIELD_ID(gPointerCoordsClassInfo.touchMajor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800891 "touchMajor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800892 GET_FIELD_ID(gPointerCoordsClassInfo.touchMinor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800893 "touchMinor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800894 GET_FIELD_ID(gPointerCoordsClassInfo.toolMajor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800895 "toolMajor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800896 GET_FIELD_ID(gPointerCoordsClassInfo.toolMinor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800897 "toolMinor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800898 GET_FIELD_ID(gPointerCoordsClassInfo.orientation, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800899 "orientation", "F");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700900
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700901 FIND_CLASS(clazz, "android/view/MotionEvent$PointerProperties");
902
903 GET_FIELD_ID(gPointerPropertiesClassInfo.id, clazz,
904 "id", "I");
905 GET_FIELD_ID(gPointerPropertiesClassInfo.toolType, clazz,
906 "toolType", "I");
907
Jeff Brown46b9ac02010-04-22 18:58:52 -0700908 return 0;
909}
910
911} // namespace android