blob: e69fb74ecf1641c23f40770d868d66c9e072dc47 [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
21#include <android_runtime/AndroidRuntime.h>
22#include <utils/Log.h>
Mathias Agopianb93a03f82012-02-17 15:34:57 -080023#include <androidfw/Input.h>
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080024#include "android_os_Parcel.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070025#include "android_view_MotionEvent.h"
Jeff Brown91c69ab2011-02-14 17:03:18 -080026#include "android_util_Binder.h"
Jeff Brown20e987b2010-08-23 12:01:02 -070027#include "android/graphics/Matrix.h"
28
Jeff Brown20e987b2010-08-23 12:01:02 -070029#include "SkMatrix.h"
Jeff Brown20e987b2010-08-23 12:01:02 -070030
31
Jeff Brown46b9ac02010-04-22 18:58:52 -070032namespace android {
33
34// ----------------------------------------------------------------------------
35
36static struct {
37 jclass clazz;
38
39 jmethodID obtain;
40 jmethodID recycle;
41
Jeff Brown91c69ab2011-02-14 17:03:18 -080042 jfieldID mNativePtr;
Jeff Brown46b9ac02010-04-22 18:58:52 -070043} gMotionEventClassInfo;
44
Jeff Brown91c69ab2011-02-14 17:03:18 -080045static struct {
Jeff Brown91c69ab2011-02-14 17:03:18 -080046 jfieldID mPackedAxisBits;
47 jfieldID mPackedAxisValues;
48 jfieldID x;
49 jfieldID y;
50 jfieldID pressure;
51 jfieldID size;
52 jfieldID touchMajor;
53 jfieldID touchMinor;
54 jfieldID toolMajor;
55 jfieldID toolMinor;
56 jfieldID orientation;
57} gPointerCoordsClassInfo;
58
Jeff Brownfe9f8ab2011-05-06 18:20:01 -070059static struct {
60 jfieldID id;
61 jfieldID toolType;
62} gPointerPropertiesClassInfo;
63
Jeff Brown46b9ac02010-04-22 18:58:52 -070064// ----------------------------------------------------------------------------
65
Jeff Brown2ed24622011-03-14 19:39:54 -070066MotionEvent* android_view_MotionEvent_getNativePtr(JNIEnv* env, jobject eventObj) {
67 if (!eventObj) {
68 return NULL;
69 }
Jeff Brown91c69ab2011-02-14 17:03:18 -080070 return reinterpret_cast<MotionEvent*>(
71 env->GetIntField(eventObj, gMotionEventClassInfo.mNativePtr));
72}
Jeff Brown46b9ac02010-04-22 18:58:52 -070073
Jeff Brown91c69ab2011-02-14 17:03:18 -080074static void android_view_MotionEvent_setNativePtr(JNIEnv* env, jobject eventObj,
75 MotionEvent* event) {
76 env->SetIntField(eventObj, gMotionEventClassInfo.mNativePtr,
77 reinterpret_cast<int>(event));
78}
79
Jeff Brown2ed24622011-03-14 19:39:54 -070080jobject android_view_MotionEvent_obtainAsCopy(JNIEnv* env, const MotionEvent* event) {
Jeff Brown46b9ac02010-04-22 18:58:52 -070081 jobject eventObj = env->CallStaticObjectMethod(gMotionEventClassInfo.clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -080082 gMotionEventClassInfo.obtain);
Jeff Brown2ed24622011-03-14 19:39:54 -070083 if (env->ExceptionCheck() || !eventObj) {
Steve Block3762c312012-01-06 19:20:56 +000084 ALOGE("An exception occurred while obtaining a motion event.");
Jeff Brown46b9ac02010-04-22 18:58:52 -070085 LOGE_EX(env);
86 env->ExceptionClear();
87 return NULL;
88 }
89
Jeff Brown91c69ab2011-02-14 17:03:18 -080090 MotionEvent* destEvent = android_view_MotionEvent_getNativePtr(env, eventObj);
91 if (!destEvent) {
92 destEvent = new MotionEvent();
93 android_view_MotionEvent_setNativePtr(env, eventObj, destEvent);
Jeff Brown46b9ac02010-04-22 18:58:52 -070094 }
95
Jeff Brown91c69ab2011-02-14 17:03:18 -080096 destEvent->copyFrom(event, true);
Jeff Brown46b9ac02010-04-22 18:58:52 -070097 return eventObj;
98}
99
Jeff Brown1f245102010-11-18 20:53:46 -0800100status_t android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700101 env->CallVoidMethod(eventObj, gMotionEventClassInfo.recycle);
102 if (env->ExceptionCheck()) {
Steve Block8564c8d2012-01-05 23:22:43 +0000103 ALOGW("An exception occurred while recycling a motion event.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700104 LOGW_EX(env);
105 env->ExceptionClear();
Jeff Brown1f245102010-11-18 20:53:46 -0800106 return UNKNOWN_ERROR;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700107 }
Jeff Brown1f245102010-11-18 20:53:46 -0800108 return OK;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700109}
110
Jeff Brown91c69ab2011-02-14 17:03:18 -0800111// ----------------------------------------------------------------------------
Jeff Brown20e987b2010-08-23 12:01:02 -0700112
Jeff Brown91c69ab2011-02-14 17:03:18 -0800113static const jint HISTORY_CURRENT = -0x80000000;
114
115static bool validatePointerCount(JNIEnv* env, jint pointerCount) {
116 if (pointerCount < 1) {
117 jniThrowException(env, "java/lang/IllegalArgumentException",
118 "pointerCount must be at least 1");
119 return false;
Jeff Brown20e987b2010-08-23 12:01:02 -0700120 }
Jeff Brown91c69ab2011-02-14 17:03:18 -0800121 return true;
Jeff Brown20e987b2010-08-23 12:01:02 -0700122}
123
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700124static bool validatePointerPropertiesArray(JNIEnv* env, jobjectArray pointerPropertiesObjArray,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800125 size_t pointerCount) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700126 if (!pointerPropertiesObjArray) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800127 jniThrowException(env, "java/lang/IllegalArgumentException",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700128 "pointerProperties array must not be null");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800129 return false;
130 }
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700131 size_t length = size_t(env->GetArrayLength(pointerPropertiesObjArray));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800132 if (length < pointerCount) {
133 jniThrowException(env, "java/lang/IllegalArgumentException",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700134 "pointerProperties array must be large enough to hold all pointers");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800135 return false;
136 }
137 return true;
138}
Jeff Brown20e987b2010-08-23 12:01:02 -0700139
Jeff Brown91c69ab2011-02-14 17:03:18 -0800140static bool validatePointerCoordsObjArray(JNIEnv* env, jobjectArray pointerCoordsObjArray,
141 size_t pointerCount) {
142 if (!pointerCoordsObjArray) {
143 jniThrowException(env, "java/lang/IllegalArgumentException",
144 "pointerCoords array must not be null");
145 return false;
146 }
147 size_t length = size_t(env->GetArrayLength(pointerCoordsObjArray));
148 if (length < pointerCount) {
149 jniThrowException(env, "java/lang/IllegalArgumentException",
150 "pointerCoords array must be large enough to hold all pointers");
151 return false;
152 }
153 return true;
154}
Jeff Brown20e987b2010-08-23 12:01:02 -0700155
Jeff Brown91c69ab2011-02-14 17:03:18 -0800156static bool validatePointerIndex(JNIEnv* env, jint pointerIndex, size_t pointerCount) {
157 if (pointerIndex < 0 || size_t(pointerIndex) >= pointerCount) {
158 jniThrowException(env, "java/lang/IllegalArgumentException",
159 "pointerIndex out of range");
160 return false;
161 }
162 return true;
163}
Jeff Brown20e987b2010-08-23 12:01:02 -0700164
Jeff Brown91c69ab2011-02-14 17:03:18 -0800165static bool validateHistoryPos(JNIEnv* env, jint historyPos, size_t historySize) {
166 if (historyPos < 0 || size_t(historyPos) >= historySize) {
167 jniThrowException(env, "java/lang/IllegalArgumentException",
168 "historyPos out of range");
169 return false;
170 }
171 return true;
172}
Jeff Brown20e987b2010-08-23 12:01:02 -0700173
Jeff Brown91c69ab2011-02-14 17:03:18 -0800174static bool validatePointerCoords(JNIEnv* env, jobject pointerCoordsObj) {
175 if (!pointerCoordsObj) {
176 jniThrowException(env, "java/lang/IllegalArgumentException",
177 "pointerCoords must not be null");
178 return false;
179 }
180 return true;
181}
182
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700183static bool validatePointerProperties(JNIEnv* env, jobject pointerPropertiesObj) {
184 if (!pointerPropertiesObj) {
185 jniThrowException(env, "java/lang/IllegalArgumentException",
186 "pointerProperties must not be null");
187 return false;
188 }
189 return true;
190}
191
Jeff Brown91c69ab2011-02-14 17:03:18 -0800192static void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj,
193 float xOffset, float yOffset, PointerCoords* outRawPointerCoords) {
194 outRawPointerCoords->clear();
Jeff Brownebbd5d12011-02-17 13:01:34 -0800195 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_X,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800196 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.x) - xOffset);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800197 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_Y,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800198 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.y) - yOffset);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800199 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800200 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.pressure));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800201 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_SIZE,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800202 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.size));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800203 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800204 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMajor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800205 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800206 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMinor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800207 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800208 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMajor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800209 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800210 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMinor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800211 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800212 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.orientation));
213
Jeff Brown6f2fba42011-02-19 01:08:02 -0800214 uint64_t bits = env->GetLongField(pointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800215 if (bits) {
216 jfloatArray valuesArray = jfloatArray(env->GetObjectField(pointerCoordsObj,
217 gPointerCoordsClassInfo.mPackedAxisValues));
218 if (valuesArray) {
219 jfloat* values = static_cast<jfloat*>(
220 env->GetPrimitiveArrayCritical(valuesArray, NULL));
221
222 uint32_t index = 0;
223 do {
Jeff Browncc0c1592011-02-19 05:07:28 -0800224 uint32_t axis = __builtin_ctzll(bits);
Jeff Brown6f2fba42011-02-19 01:08:02 -0800225 uint64_t axisBit = 1LL << axis;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800226 bits &= ~axisBit;
227 outRawPointerCoords->setAxisValue(axis, values[index++]);
228 } while (bits);
229
230 env->ReleasePrimitiveArrayCritical(valuesArray, values, JNI_ABORT);
231 env->DeleteLocalRef(valuesArray);
232 }
233 }
234}
235
236static jfloatArray obtainPackedAxisValuesArray(JNIEnv* env, uint32_t minSize,
237 jobject outPointerCoordsObj) {
238 jfloatArray outValuesArray = jfloatArray(env->GetObjectField(outPointerCoordsObj,
239 gPointerCoordsClassInfo.mPackedAxisValues));
240 if (outValuesArray) {
241 uint32_t size = env->GetArrayLength(outValuesArray);
242 if (minSize <= size) {
243 return outValuesArray;
244 }
245 env->DeleteLocalRef(outValuesArray);
246 }
247 uint32_t size = 8;
248 while (size < minSize) {
249 size *= 2;
250 }
251 outValuesArray = env->NewFloatArray(size);
252 env->SetObjectField(outPointerCoordsObj,
253 gPointerCoordsClassInfo.mPackedAxisValues, outValuesArray);
254 return outValuesArray;
255}
256
257static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointerCoords,
258 float xOffset, float yOffset, jobject outPointerCoordsObj) {
259 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800260 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800261 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800262 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800263 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.pressure,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800264 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800265 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.size,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800266 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_SIZE));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800267 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMajor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800268 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800269 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMinor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800270 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800271 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMajor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800272 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800273 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMinor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800274 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800275 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.orientation,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800276 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800277
Jeff Brown6f2fba42011-02-19 01:08:02 -0800278 const uint64_t unpackedAxisBits = 0
279 | (1LL << AMOTION_EVENT_AXIS_X)
280 | (1LL << AMOTION_EVENT_AXIS_Y)
281 | (1LL << AMOTION_EVENT_AXIS_PRESSURE)
282 | (1LL << AMOTION_EVENT_AXIS_SIZE)
283 | (1LL << AMOTION_EVENT_AXIS_TOUCH_MAJOR)
284 | (1LL << AMOTION_EVENT_AXIS_TOUCH_MINOR)
285 | (1LL << AMOTION_EVENT_AXIS_TOOL_MAJOR)
286 | (1LL << AMOTION_EVENT_AXIS_TOOL_MINOR)
287 | (1LL << AMOTION_EVENT_AXIS_ORIENTATION);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800288
Jeff Brown6f2fba42011-02-19 01:08:02 -0800289 uint64_t outBits = 0;
290 uint64_t remainingBits = rawPointerCoords->bits & ~unpackedAxisBits;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800291 if (remainingBits) {
Jeff Brown6f2fba42011-02-19 01:08:02 -0800292 uint32_t packedAxesCount = __builtin_popcountll(remainingBits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800293 jfloatArray outValuesArray = obtainPackedAxisValuesArray(env, packedAxesCount,
294 outPointerCoordsObj);
295 if (!outValuesArray) {
296 return; // OOM
Jeff Brown20e987b2010-08-23 12:01:02 -0700297 }
298
Jeff Brown91c69ab2011-02-14 17:03:18 -0800299 jfloat* outValues = static_cast<jfloat*>(env->GetPrimitiveArrayCritical(
300 outValuesArray, NULL));
Jeff Brown20e987b2010-08-23 12:01:02 -0700301
Jeff Brown91c69ab2011-02-14 17:03:18 -0800302 const float* values = rawPointerCoords->values;
303 uint32_t index = 0;
304 do {
Jeff Browncc0c1592011-02-19 05:07:28 -0800305 uint32_t axis = __builtin_ctzll(remainingBits);
Jeff Brown6f2fba42011-02-19 01:08:02 -0800306 uint64_t axisBit = 1LL << axis;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800307 remainingBits &= ~axisBit;
308 outBits |= axisBit;
309 outValues[index++] = rawPointerCoords->getAxisValue(axis);
310 } while (remainingBits);
311
312 env->ReleasePrimitiveArrayCritical(outValuesArray, outValues, 0);
313 env->DeleteLocalRef(outValuesArray);
314 }
Jeff Brown6f2fba42011-02-19 01:08:02 -0800315 env->SetLongField(outPointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits, outBits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800316}
317
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700318static void pointerPropertiesToNative(JNIEnv* env, jobject pointerPropertiesObj,
319 PointerProperties* outPointerProperties) {
320 outPointerProperties->clear();
321 outPointerProperties->id = env->GetIntField(pointerPropertiesObj,
322 gPointerPropertiesClassInfo.id);
323 outPointerProperties->toolType = env->GetIntField(pointerPropertiesObj,
324 gPointerPropertiesClassInfo.toolType);
325}
326
327static void pointerPropertiesFromNative(JNIEnv* env, const PointerProperties* pointerProperties,
328 jobject outPointerPropertiesObj) {
329 env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.id,
330 pointerProperties->id);
331 env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.toolType,
332 pointerProperties->toolType);
333}
334
Jeff Brown91c69ab2011-02-14 17:03:18 -0800335
336// ----------------------------------------------------------------------------
337
338static jint android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz,
339 jint nativePtr,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700340 jint deviceId, jint source, jint action, jint flags, jint edgeFlags,
341 jint metaState, jint buttonState,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800342 jfloat xOffset, jfloat yOffset, jfloat xPrecision, jfloat yPrecision,
343 jlong downTimeNanos, jlong eventTimeNanos,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700344 jint pointerCount, jobjectArray pointerPropertiesObjArray,
345 jobjectArray pointerCoordsObjArray) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800346 if (!validatePointerCount(env, pointerCount)
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700347 || !validatePointerPropertiesArray(env, pointerPropertiesObjArray, pointerCount)
Jeff Brown91c69ab2011-02-14 17:03:18 -0800348 || !validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
349 return 0;
Jeff Brown20e987b2010-08-23 12:01:02 -0700350 }
351
Jeff Brown91c69ab2011-02-14 17:03:18 -0800352 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
353 if (!event) {
354 event = new MotionEvent();
355 }
Jeff Brown20e987b2010-08-23 12:01:02 -0700356
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700357 PointerProperties pointerProperties[pointerCount];
Jeff Brown91c69ab2011-02-14 17:03:18 -0800358 PointerCoords rawPointerCoords[pointerCount];
Jeff Brown20e987b2010-08-23 12:01:02 -0700359
Jeff Brown91c69ab2011-02-14 17:03:18 -0800360 for (jint i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700361 jobject pointerPropertiesObj = env->GetObjectArrayElement(pointerPropertiesObjArray, i);
362 if (!pointerPropertiesObj) {
363 goto Error;
364 }
365 pointerPropertiesToNative(env, pointerPropertiesObj, &pointerProperties[i]);
366 env->DeleteLocalRef(pointerPropertiesObj);
367
Jeff Brown91c69ab2011-02-14 17:03:18 -0800368 jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
369 if (!pointerCoordsObj) {
370 jniThrowNullPointerException(env, "pointerCoords");
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700371 goto Error;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800372 }
373 pointerCoordsToNative(env, pointerCoordsObj, xOffset, yOffset, &rawPointerCoords[i]);
374 env->DeleteLocalRef(pointerCoordsObj);
375 }
376
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700377 event->initialize(deviceId, source, action, flags, edgeFlags, metaState, buttonState,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800378 xOffset, yOffset, xPrecision, yPrecision,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700379 downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800380
Jeff Brown91c69ab2011-02-14 17:03:18 -0800381 return reinterpret_cast<jint>(event);
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700382
383Error:
384 if (!nativePtr) {
385 delete event;
386 }
387 return 0;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800388}
389
390static jint android_view_MotionEvent_nativeCopy(JNIEnv* env, jclass clazz,
391 jint destNativePtr, jint sourceNativePtr, jboolean keepHistory) {
392 MotionEvent* destEvent = reinterpret_cast<MotionEvent*>(destNativePtr);
393 if (!destEvent) {
394 destEvent = new MotionEvent();
395 }
396 MotionEvent* sourceEvent = reinterpret_cast<MotionEvent*>(sourceNativePtr);
397 destEvent->copyFrom(sourceEvent, keepHistory);
398 return reinterpret_cast<jint>(destEvent);
399}
400
401static void android_view_MotionEvent_nativeDispose(JNIEnv* env, jclass clazz,
402 jint nativePtr) {
403 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
404 delete event;
405}
406
407static void android_view_MotionEvent_nativeAddBatch(JNIEnv* env, jclass clazz,
408 jint nativePtr, jlong eventTimeNanos, jobjectArray pointerCoordsObjArray,
409 jint metaState) {
410 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
411 size_t pointerCount = event->getPointerCount();
412 if (!validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
413 return;
414 }
415
416 PointerCoords rawPointerCoords[pointerCount];
417
418 for (size_t i = 0; i < pointerCount; i++) {
419 jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
420 if (!pointerCoordsObj) {
421 jniThrowNullPointerException(env, "pointerCoords");
422 return;
423 }
424 pointerCoordsToNative(env, pointerCoordsObj,
425 event->getXOffset(), event->getYOffset(), &rawPointerCoords[i]);
426 env->DeleteLocalRef(pointerCoordsObj);
427 }
428
429 event->addSample(eventTimeNanos, rawPointerCoords);
430 event->setMetaState(event->getMetaState() | metaState);
431}
432
433static jint android_view_MotionEvent_nativeGetDeviceId(JNIEnv* env, jclass clazz,
434 jint nativePtr) {
435 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
436 return event->getDeviceId();
437}
438
439static jint android_view_MotionEvent_nativeGetSource(JNIEnv* env, jclass clazz,
440 jint nativePtr) {
441 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
442 return event->getSource();
443}
444
445static void android_view_MotionEvent_nativeSetSource(JNIEnv* env, jclass clazz,
446 jint nativePtr, jint source) {
447 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
448 event->setSource(source);
449}
450
451static jint android_view_MotionEvent_nativeGetAction(JNIEnv* env, jclass clazz,
452 jint nativePtr) {
453 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
454 return event->getAction();
455}
456
457static void android_view_MotionEvent_nativeSetAction(JNIEnv* env, jclass clazz,
458 jint nativePtr, jint action) {
459 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
460 event->setAction(action);
461}
462
Jeff Brown56194eb2011-03-02 19:23:13 -0800463static jboolean android_view_MotionEvent_nativeIsTouchEvent(JNIEnv* env, jclass clazz,
464 jint nativePtr) {
465 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
466 return event->isTouchEvent();
467}
468
Jeff Brown91c69ab2011-02-14 17:03:18 -0800469static jint android_view_MotionEvent_nativeGetFlags(JNIEnv* env, jclass clazz,
470 jint nativePtr) {
471 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
472 return event->getFlags();
473}
474
Jeff Brown21bc5c92011-02-28 18:27:14 -0800475static void android_view_MotionEvent_nativeSetFlags(JNIEnv* env, jclass clazz,
476 jint nativePtr, jint flags) {
477 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
478 event->setFlags(flags);
479}
480
Jeff Brown91c69ab2011-02-14 17:03:18 -0800481static jint android_view_MotionEvent_nativeGetEdgeFlags(JNIEnv* env, jclass clazz,
482 jint nativePtr) {
483 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
484 return event->getEdgeFlags();
485}
486
487static void android_view_MotionEvent_nativeSetEdgeFlags(JNIEnv* env, jclass clazz,
488 jint nativePtr, jint edgeFlags) {
489 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
490 event->setEdgeFlags(edgeFlags);
491}
492
493static jint android_view_MotionEvent_nativeGetMetaState(JNIEnv* env, jclass clazz,
494 jint nativePtr) {
495 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
496 return event->getMetaState();
497}
498
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700499static jint android_view_MotionEvent_nativeGetButtonState(JNIEnv* env, jclass clazz,
500 jint nativePtr) {
501 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
502 return event->getButtonState();
503}
504
Jeff Brown91c69ab2011-02-14 17:03:18 -0800505static void android_view_MotionEvent_nativeOffsetLocation(JNIEnv* env, jclass clazz,
506 jint nativePtr, jfloat deltaX, jfloat deltaY) {
507 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
508 return event->offsetLocation(deltaX, deltaY);
509}
510
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700511static jfloat android_view_MotionEvent_nativeGetXOffset(JNIEnv* env, jclass clazz,
512 jint nativePtr) {
513 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
514 return event->getXOffset();
515}
516
517static jfloat android_view_MotionEvent_nativeGetYOffset(JNIEnv* env, jclass clazz,
518 jint nativePtr) {
519 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
520 return event->getYOffset();
521}
522
Jeff Brown91c69ab2011-02-14 17:03:18 -0800523static jfloat android_view_MotionEvent_nativeGetXPrecision(JNIEnv* env, jclass clazz,
524 jint nativePtr) {
525 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
526 return event->getXPrecision();
527}
528
529static jfloat android_view_MotionEvent_nativeGetYPrecision(JNIEnv* env, jclass clazz,
530 jint nativePtr) {
531 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
532 return event->getYPrecision();
533}
534
535static jlong android_view_MotionEvent_nativeGetDownTimeNanos(JNIEnv* env, jclass clazz,
536 jint nativePtr) {
537 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
538 return event->getDownTime();
539}
540
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700541static void android_view_MotionEvent_nativeSetDownTimeNanos(JNIEnv* env, jclass clazz,
542 jint nativePtr, jlong downTimeNanos) {
543 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
544 event->setDownTime(downTimeNanos);
545}
546
Jeff Brown91c69ab2011-02-14 17:03:18 -0800547static jint android_view_MotionEvent_nativeGetPointerCount(JNIEnv* env, jclass clazz,
548 jint nativePtr) {
549 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
550 return jint(event->getPointerCount());
551}
552
553static jint android_view_MotionEvent_nativeGetPointerId(JNIEnv* env, jclass clazz,
554 jint nativePtr, jint pointerIndex) {
555 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
556 size_t pointerCount = event->getPointerCount();
557 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
558 return -1;
559 }
560 return event->getPointerId(pointerIndex);
561}
562
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700563static jint android_view_MotionEvent_nativeGetToolType(JNIEnv* env, jclass clazz,
564 jint nativePtr, jint pointerIndex) {
565 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
566 size_t pointerCount = event->getPointerCount();
567 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
568 return -1;
569 }
570 return event->getToolType(pointerIndex);
571}
572
Jeff Brown91c69ab2011-02-14 17:03:18 -0800573static jint android_view_MotionEvent_nativeFindPointerIndex(JNIEnv* env, jclass clazz,
574 jint nativePtr, jint pointerId) {
575 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
Jeff Brown2ed24622011-03-14 19:39:54 -0700576 return jint(event->findPointerIndex(pointerId));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800577}
578
579static jint android_view_MotionEvent_nativeGetHistorySize(JNIEnv* env, jclass clazz,
580 jint nativePtr) {
581 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
582 return jint(event->getHistorySize());
583}
584
585static jlong android_view_MotionEvent_nativeGetEventTimeNanos(JNIEnv* env, jclass clazz,
586 jint nativePtr, jint historyPos) {
587 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
588 if (historyPos == HISTORY_CURRENT) {
589 return event->getEventTime();
590 } else {
591 size_t historySize = event->getHistorySize();
592 if (!validateHistoryPos(env, historyPos, historySize)) {
593 return 0;
594 }
595 return event->getHistoricalEventTime(historyPos);
596 }
597}
598
599static jfloat android_view_MotionEvent_nativeGetRawAxisValue(JNIEnv* env, jclass clazz,
600 jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
601 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
602 size_t pointerCount = event->getPointerCount();
603 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
604 return 0;
605 }
606
607 if (historyPos == HISTORY_CURRENT) {
608 return event->getRawAxisValue(axis, pointerIndex);
609 } else {
610 size_t historySize = event->getHistorySize();
611 if (!validateHistoryPos(env, historyPos, historySize)) {
612 return 0;
613 }
614 return event->getHistoricalRawAxisValue(axis, pointerIndex, historyPos);
615 }
616}
617
618static jfloat android_view_MotionEvent_nativeGetAxisValue(JNIEnv* env, jclass clazz,
619 jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
620 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
621 size_t pointerCount = event->getPointerCount();
622 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
623 return 0;
624 }
625
626 if (historyPos == HISTORY_CURRENT) {
627 return event->getAxisValue(axis, pointerIndex);
628 } else {
629 size_t historySize = event->getHistorySize();
630 if (!validateHistoryPos(env, historyPos, historySize)) {
631 return 0;
632 }
633 return event->getHistoricalAxisValue(axis, pointerIndex, historyPos);
634 }
635}
636
637static void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass clazz,
638 jint nativePtr, jint pointerIndex, jint historyPos, jobject outPointerCoordsObj) {
639 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
640 size_t pointerCount = event->getPointerCount();
641 if (!validatePointerIndex(env, pointerIndex, pointerCount)
642 || !validatePointerCoords(env, outPointerCoordsObj)) {
643 return;
644 }
645
646 const PointerCoords* rawPointerCoords;
647 if (historyPos == HISTORY_CURRENT) {
648 rawPointerCoords = event->getRawPointerCoords(pointerIndex);
649 } else {
650 size_t historySize = event->getHistorySize();
651 if (!validateHistoryPos(env, historyPos, historySize)) {
652 return;
653 }
654 rawPointerCoords = event->getHistoricalRawPointerCoords(pointerIndex, historyPos);
655 }
656 pointerCoordsFromNative(env, rawPointerCoords, event->getXOffset(), event->getYOffset(),
657 outPointerCoordsObj);
658}
659
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700660static void android_view_MotionEvent_nativeGetPointerProperties(JNIEnv* env, jclass clazz,
661 jint nativePtr, jint pointerIndex, jobject outPointerPropertiesObj) {
662 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
663 size_t pointerCount = event->getPointerCount();
664 if (!validatePointerIndex(env, pointerIndex, pointerCount)
665 || !validatePointerProperties(env, outPointerPropertiesObj)) {
666 return;
667 }
668
669 const PointerProperties* pointerProperties = event->getPointerProperties(pointerIndex);
670 pointerPropertiesFromNative(env, pointerProperties, outPointerPropertiesObj);
671}
672
Jeff Brown91c69ab2011-02-14 17:03:18 -0800673static void android_view_MotionEvent_nativeScale(JNIEnv* env, jclass clazz,
674 jint nativePtr, jfloat scale) {
675 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
676 event->scale(scale);
677}
678
679static void android_view_MotionEvent_nativeTransform(JNIEnv* env, jclass clazz,
680 jint nativePtr, jobject matrixObj) {
681 SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
682 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
683 event->transform(matrix);
684}
685
686static jint android_view_MotionEvent_nativeReadFromParcel(JNIEnv* env, jclass clazz,
687 jint nativePtr, jobject parcelObj) {
688 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
689 if (!event) {
690 event = new MotionEvent();
691 }
692
693 Parcel* parcel = parcelForJavaObject(env, parcelObj);
694
695 status_t status = event->readFromParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800696 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800697 if (!nativePtr) {
698 delete event;
699 }
700 jniThrowRuntimeException(env, "Failed to read MotionEvent parcel.");
701 return 0;
702 }
703 return reinterpret_cast<jint>(event);
704}
705
706static void android_view_MotionEvent_nativeWriteToParcel(JNIEnv* env, jclass clazz,
707 jint nativePtr, jobject parcelObj) {
708 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
709 Parcel* parcel = parcelForJavaObject(env, parcelObj);
710
711 status_t status = event->writeToParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800712 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800713 jniThrowRuntimeException(env, "Failed to write MotionEvent parcel.");
714 }
Jeff Brown20e987b2010-08-23 12:01:02 -0700715}
716
Jeff Brown46b9ac02010-04-22 18:58:52 -0700717// ----------------------------------------------------------------------------
718
Jeff Brown20e987b2010-08-23 12:01:02 -0700719static JNINativeMethod gMotionEventMethods[] = {
720 /* name, signature, funcPtr */
Jeff Brown91c69ab2011-02-14 17:03:18 -0800721 { "nativeInitialize",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700722 "(IIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;"
723 "[Landroid/view/MotionEvent$PointerCoords;)I",
Jeff Brown91c69ab2011-02-14 17:03:18 -0800724 (void*)android_view_MotionEvent_nativeInitialize },
725 { "nativeCopy",
726 "(IIZ)I",
727 (void*)android_view_MotionEvent_nativeCopy },
728 { "nativeDispose",
729 "(I)V",
730 (void*)android_view_MotionEvent_nativeDispose },
731 { "nativeAddBatch",
732 "(IJ[Landroid/view/MotionEvent$PointerCoords;I)V",
733 (void*)android_view_MotionEvent_nativeAddBatch },
734 { "nativeGetDeviceId",
735 "(I)I",
736 (void*)android_view_MotionEvent_nativeGetDeviceId },
737 { "nativeGetSource",
738 "(I)I",
739 (void*)android_view_MotionEvent_nativeGetSource },
740 { "nativeSetSource",
741 "(II)I",
742 (void*)android_view_MotionEvent_nativeSetSource },
743 { "nativeGetAction",
744 "(I)I",
745 (void*)android_view_MotionEvent_nativeGetAction },
746 { "nativeSetAction",
747 "(II)V",
748 (void*)android_view_MotionEvent_nativeSetAction },
Jeff Brown56194eb2011-03-02 19:23:13 -0800749 { "nativeIsTouchEvent",
750 "(I)Z",
751 (void*)android_view_MotionEvent_nativeIsTouchEvent },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800752 { "nativeGetFlags",
753 "(I)I",
754 (void*)android_view_MotionEvent_nativeGetFlags },
Jeff Brown21bc5c92011-02-28 18:27:14 -0800755 { "nativeSetFlags",
756 "(II)V",
757 (void*)android_view_MotionEvent_nativeSetFlags },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800758 { "nativeGetEdgeFlags",
759 "(I)I",
760 (void*)android_view_MotionEvent_nativeGetEdgeFlags },
761 { "nativeSetEdgeFlags",
762 "(II)V",
763 (void*)android_view_MotionEvent_nativeSetEdgeFlags },
764 { "nativeGetMetaState",
765 "(I)I",
766 (void*)android_view_MotionEvent_nativeGetMetaState },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700767 { "nativeGetButtonState",
768 "(I)I",
769 (void*)android_view_MotionEvent_nativeGetButtonState },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800770 { "nativeOffsetLocation",
771 "(IFF)V",
772 (void*)android_view_MotionEvent_nativeOffsetLocation },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700773 { "nativeGetXOffset",
774 "(I)F",
775 (void*)android_view_MotionEvent_nativeGetXOffset },
776 { "nativeGetYOffset",
777 "(I)F",
778 (void*)android_view_MotionEvent_nativeGetYOffset },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800779 { "nativeGetXPrecision",
780 "(I)F",
781 (void*)android_view_MotionEvent_nativeGetXPrecision },
782 { "nativeGetYPrecision",
783 "(I)F",
784 (void*)android_view_MotionEvent_nativeGetYPrecision },
785 { "nativeGetDownTimeNanos",
786 "(I)J",
787 (void*)android_view_MotionEvent_nativeGetDownTimeNanos },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700788 { "nativeSetDownTimeNanos",
789 "(IJ)V",
790 (void*)android_view_MotionEvent_nativeSetDownTimeNanos },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800791 { "nativeGetPointerCount",
792 "(I)I",
793 (void*)android_view_MotionEvent_nativeGetPointerCount },
794 { "nativeGetPointerId",
795 "(II)I",
796 (void*)android_view_MotionEvent_nativeGetPointerId },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700797 { "nativeGetToolType",
798 "(II)I",
799 (void*)android_view_MotionEvent_nativeGetToolType },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800800 { "nativeFindPointerIndex",
801 "(II)I",
802 (void*)android_view_MotionEvent_nativeFindPointerIndex },
803 { "nativeGetHistorySize",
804 "(I)I",
805 (void*)android_view_MotionEvent_nativeGetHistorySize },
806 { "nativeGetEventTimeNanos",
807 "(II)J",
808 (void*)android_view_MotionEvent_nativeGetEventTimeNanos },
809 { "nativeGetRawAxisValue",
810 "(IIII)F",
811 (void*)android_view_MotionEvent_nativeGetRawAxisValue },
812 { "nativeGetAxisValue",
813 "(IIII)F",
814 (void*)android_view_MotionEvent_nativeGetAxisValue },
815 { "nativeGetPointerCoords",
816 "(IIILandroid/view/MotionEvent$PointerCoords;)V",
817 (void*)android_view_MotionEvent_nativeGetPointerCoords },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700818 { "nativeGetPointerProperties",
819 "(IILandroid/view/MotionEvent$PointerProperties;)V",
820 (void*)android_view_MotionEvent_nativeGetPointerProperties },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800821 { "nativeScale",
822 "(IF)V",
823 (void*)android_view_MotionEvent_nativeScale },
Jeff Brown20e987b2010-08-23 12:01:02 -0700824 { "nativeTransform",
Jeff Brown91c69ab2011-02-14 17:03:18 -0800825 "(ILandroid/graphics/Matrix;)V",
Jeff Brown20e987b2010-08-23 12:01:02 -0700826 (void*)android_view_MotionEvent_nativeTransform },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800827 { "nativeReadFromParcel",
828 "(ILandroid/os/Parcel;)I",
829 (void*)android_view_MotionEvent_nativeReadFromParcel },
830 { "nativeWriteToParcel",
831 "(ILandroid/os/Parcel;)V",
832 (void*)android_view_MotionEvent_nativeWriteToParcel },
Jeff Brown20e987b2010-08-23 12:01:02 -0700833};
834
Jeff Brown46b9ac02010-04-22 18:58:52 -0700835#define FIND_CLASS(var, className) \
836 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800837 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700838
839#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
840 var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
841 LOG_FATAL_IF(! var, "Unable to find static method" methodName);
842
843#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
844 var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
845 LOG_FATAL_IF(! var, "Unable to find method" methodName);
846
847#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
848 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
849 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
850
851int register_android_view_MotionEvent(JNIEnv* env) {
Jeff Brown20e987b2010-08-23 12:01:02 -0700852 int res = jniRegisterNativeMethods(env, "android/view/MotionEvent",
853 gMotionEventMethods, NELEM(gMotionEventMethods));
854 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
855
Jeff Brown46b9ac02010-04-22 18:58:52 -0700856 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800857 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown46b9ac02010-04-22 18:58:52 -0700858
859 GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800860 "obtain", "()Landroid/view/MotionEvent;");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700861 GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
862 "recycle", "()V");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800863 GET_FIELD_ID(gMotionEventClassInfo.mNativePtr, gMotionEventClassInfo.clazz,
864 "mNativePtr", "I");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700865
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800866 jclass clazz;
867 FIND_CLASS(clazz, "android/view/MotionEvent$PointerCoords");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800868
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800869 GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, clazz,
Jeff Brown6f2fba42011-02-19 01:08:02 -0800870 "mPackedAxisBits", "J");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800871 GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800872 "mPackedAxisValues", "[F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800873 GET_FIELD_ID(gPointerCoordsClassInfo.x, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800874 "x", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800875 GET_FIELD_ID(gPointerCoordsClassInfo.y, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800876 "y", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800877 GET_FIELD_ID(gPointerCoordsClassInfo.pressure, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800878 "pressure", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800879 GET_FIELD_ID(gPointerCoordsClassInfo.size, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800880 "size", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800881 GET_FIELD_ID(gPointerCoordsClassInfo.touchMajor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800882 "touchMajor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800883 GET_FIELD_ID(gPointerCoordsClassInfo.touchMinor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800884 "touchMinor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800885 GET_FIELD_ID(gPointerCoordsClassInfo.toolMajor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800886 "toolMajor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800887 GET_FIELD_ID(gPointerCoordsClassInfo.toolMinor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800888 "toolMinor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800889 GET_FIELD_ID(gPointerCoordsClassInfo.orientation, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800890 "orientation", "F");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700891
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700892 FIND_CLASS(clazz, "android/view/MotionEvent$PointerProperties");
893
894 GET_FIELD_ID(gPointerPropertiesClassInfo.id, clazz,
895 "id", "I");
896 GET_FIELD_ID(gPointerPropertiesClassInfo.toolType, clazz,
897 "toolType", "I");
898
Jeff Brown46b9ac02010-04-22 18:58:52 -0700899 return 0;
900}
901
902} // namespace android