blob: fef06b2561c6dc69660eec86cb12ed73c4769483 [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>
23#include <ui/Input.h>
24#include "android_view_MotionEvent.h"
Jeff Brown91c69ab2011-02-14 17:03:18 -080025#include "android_util_Binder.h"
Jeff Brown20e987b2010-08-23 12:01:02 -070026#include "android/graphics/Matrix.h"
27
Jeff Brown20e987b2010-08-23 12:01:02 -070028#include "SkMatrix.h"
Jeff Brown20e987b2010-08-23 12:01:02 -070029
30
Jeff Brown46b9ac02010-04-22 18:58:52 -070031namespace android {
32
33// ----------------------------------------------------------------------------
34
35static struct {
36 jclass clazz;
37
38 jmethodID obtain;
39 jmethodID recycle;
40
Jeff Brown91c69ab2011-02-14 17:03:18 -080041 jfieldID mNativePtr;
Jeff Brown46b9ac02010-04-22 18:58:52 -070042} gMotionEventClassInfo;
43
Jeff Brown91c69ab2011-02-14 17:03:18 -080044static struct {
Jeff Brown91c69ab2011-02-14 17:03:18 -080045 jfieldID mPackedAxisBits;
46 jfieldID mPackedAxisValues;
47 jfieldID x;
48 jfieldID y;
49 jfieldID pressure;
50 jfieldID size;
51 jfieldID touchMajor;
52 jfieldID touchMinor;
53 jfieldID toolMajor;
54 jfieldID toolMinor;
55 jfieldID orientation;
56} gPointerCoordsClassInfo;
57
Jeff Brownfe9f8ab2011-05-06 18:20:01 -070058static struct {
59 jfieldID id;
60 jfieldID toolType;
61} gPointerPropertiesClassInfo;
62
Jeff Brown46b9ac02010-04-22 18:58:52 -070063// ----------------------------------------------------------------------------
64
Jeff Brown2ed24622011-03-14 19:39:54 -070065MotionEvent* android_view_MotionEvent_getNativePtr(JNIEnv* env, jobject eventObj) {
66 if (!eventObj) {
67 return NULL;
68 }
Jeff Brown91c69ab2011-02-14 17:03:18 -080069 return reinterpret_cast<MotionEvent*>(
70 env->GetIntField(eventObj, gMotionEventClassInfo.mNativePtr));
71}
Jeff Brown46b9ac02010-04-22 18:58:52 -070072
Jeff Brown91c69ab2011-02-14 17:03:18 -080073static void android_view_MotionEvent_setNativePtr(JNIEnv* env, jobject eventObj,
74 MotionEvent* event) {
75 env->SetIntField(eventObj, gMotionEventClassInfo.mNativePtr,
76 reinterpret_cast<int>(event));
77}
78
Jeff Brown2ed24622011-03-14 19:39:54 -070079jobject android_view_MotionEvent_obtainAsCopy(JNIEnv* env, const MotionEvent* event) {
Jeff Brown46b9ac02010-04-22 18:58:52 -070080 jobject eventObj = env->CallStaticObjectMethod(gMotionEventClassInfo.clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -080081 gMotionEventClassInfo.obtain);
Jeff Brown2ed24622011-03-14 19:39:54 -070082 if (env->ExceptionCheck() || !eventObj) {
Jeff Brown46b9ac02010-04-22 18:58:52 -070083 LOGE("An exception occurred while obtaining a motion event.");
84 LOGE_EX(env);
85 env->ExceptionClear();
86 return NULL;
87 }
88
Jeff Brown91c69ab2011-02-14 17:03:18 -080089 MotionEvent* destEvent = android_view_MotionEvent_getNativePtr(env, eventObj);
90 if (!destEvent) {
91 destEvent = new MotionEvent();
92 android_view_MotionEvent_setNativePtr(env, eventObj, destEvent);
Jeff Brown46b9ac02010-04-22 18:58:52 -070093 }
94
Jeff Brown91c69ab2011-02-14 17:03:18 -080095 destEvent->copyFrom(event, true);
Jeff Brown46b9ac02010-04-22 18:58:52 -070096 return eventObj;
97}
98
Jeff Brown1f245102010-11-18 20:53:46 -080099status_t android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700100 env->CallVoidMethod(eventObj, gMotionEventClassInfo.recycle);
101 if (env->ExceptionCheck()) {
102 LOGW("An exception occurred while recycling a motion event.");
103 LOGW_EX(env);
104 env->ExceptionClear();
Jeff Brown1f245102010-11-18 20:53:46 -0800105 return UNKNOWN_ERROR;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700106 }
Jeff Brown1f245102010-11-18 20:53:46 -0800107 return OK;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700108}
109
Jeff Brown91c69ab2011-02-14 17:03:18 -0800110// ----------------------------------------------------------------------------
Jeff Brown20e987b2010-08-23 12:01:02 -0700111
Jeff Brown91c69ab2011-02-14 17:03:18 -0800112static const jint HISTORY_CURRENT = -0x80000000;
113
114static bool validatePointerCount(JNIEnv* env, jint pointerCount) {
115 if (pointerCount < 1) {
116 jniThrowException(env, "java/lang/IllegalArgumentException",
117 "pointerCount must be at least 1");
118 return false;
Jeff Brown20e987b2010-08-23 12:01:02 -0700119 }
Jeff Brown91c69ab2011-02-14 17:03:18 -0800120 return true;
Jeff Brown20e987b2010-08-23 12:01:02 -0700121}
122
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700123static bool validatePointerPropertiesArray(JNIEnv* env, jobjectArray pointerPropertiesObjArray,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800124 size_t pointerCount) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700125 if (!pointerPropertiesObjArray) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800126 jniThrowException(env, "java/lang/IllegalArgumentException",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700127 "pointerProperties array must not be null");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800128 return false;
129 }
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700130 size_t length = size_t(env->GetArrayLength(pointerPropertiesObjArray));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800131 if (length < pointerCount) {
132 jniThrowException(env, "java/lang/IllegalArgumentException",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700133 "pointerProperties array must be large enough to hold all pointers");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800134 return false;
135 }
136 return true;
137}
Jeff Brown20e987b2010-08-23 12:01:02 -0700138
Jeff Brown91c69ab2011-02-14 17:03:18 -0800139static bool validatePointerCoordsObjArray(JNIEnv* env, jobjectArray pointerCoordsObjArray,
140 size_t pointerCount) {
141 if (!pointerCoordsObjArray) {
142 jniThrowException(env, "java/lang/IllegalArgumentException",
143 "pointerCoords array must not be null");
144 return false;
145 }
146 size_t length = size_t(env->GetArrayLength(pointerCoordsObjArray));
147 if (length < pointerCount) {
148 jniThrowException(env, "java/lang/IllegalArgumentException",
149 "pointerCoords array must be large enough to hold all pointers");
150 return false;
151 }
152 return true;
153}
Jeff Brown20e987b2010-08-23 12:01:02 -0700154
Jeff Brown91c69ab2011-02-14 17:03:18 -0800155static bool validatePointerIndex(JNIEnv* env, jint pointerIndex, size_t pointerCount) {
156 if (pointerIndex < 0 || size_t(pointerIndex) >= pointerCount) {
157 jniThrowException(env, "java/lang/IllegalArgumentException",
158 "pointerIndex out of range");
159 return false;
160 }
161 return true;
162}
Jeff Brown20e987b2010-08-23 12:01:02 -0700163
Jeff Brown91c69ab2011-02-14 17:03:18 -0800164static bool validateHistoryPos(JNIEnv* env, jint historyPos, size_t historySize) {
165 if (historyPos < 0 || size_t(historyPos) >= historySize) {
166 jniThrowException(env, "java/lang/IllegalArgumentException",
167 "historyPos out of range");
168 return false;
169 }
170 return true;
171}
Jeff Brown20e987b2010-08-23 12:01:02 -0700172
Jeff Brown91c69ab2011-02-14 17:03:18 -0800173static bool validatePointerCoords(JNIEnv* env, jobject pointerCoordsObj) {
174 if (!pointerCoordsObj) {
175 jniThrowException(env, "java/lang/IllegalArgumentException",
176 "pointerCoords must not be null");
177 return false;
178 }
179 return true;
180}
181
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700182static bool validatePointerProperties(JNIEnv* env, jobject pointerPropertiesObj) {
183 if (!pointerPropertiesObj) {
184 jniThrowException(env, "java/lang/IllegalArgumentException",
185 "pointerProperties must not be null");
186 return false;
187 }
188 return true;
189}
190
Jeff Brown91c69ab2011-02-14 17:03:18 -0800191static void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj,
192 float xOffset, float yOffset, PointerCoords* outRawPointerCoords) {
193 outRawPointerCoords->clear();
Jeff Brownebbd5d12011-02-17 13:01:34 -0800194 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_X,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800195 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.x) - xOffset);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800196 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_Y,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800197 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.y) - yOffset);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800198 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800199 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.pressure));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800200 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_SIZE,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800201 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.size));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800202 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800203 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMajor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800204 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800205 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMinor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800206 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800207 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMajor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800208 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800209 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMinor));
Jeff Brownebbd5d12011-02-17 13:01:34 -0800210 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800211 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.orientation));
212
Jeff Brown6f2fba42011-02-19 01:08:02 -0800213 uint64_t bits = env->GetLongField(pointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800214 if (bits) {
215 jfloatArray valuesArray = jfloatArray(env->GetObjectField(pointerCoordsObj,
216 gPointerCoordsClassInfo.mPackedAxisValues));
217 if (valuesArray) {
218 jfloat* values = static_cast<jfloat*>(
219 env->GetPrimitiveArrayCritical(valuesArray, NULL));
220
221 uint32_t index = 0;
222 do {
Jeff Browncc0c1592011-02-19 05:07:28 -0800223 uint32_t axis = __builtin_ctzll(bits);
Jeff Brown6f2fba42011-02-19 01:08:02 -0800224 uint64_t axisBit = 1LL << axis;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800225 bits &= ~axisBit;
226 outRawPointerCoords->setAxisValue(axis, values[index++]);
227 } while (bits);
228
229 env->ReleasePrimitiveArrayCritical(valuesArray, values, JNI_ABORT);
230 env->DeleteLocalRef(valuesArray);
231 }
232 }
233}
234
235static jfloatArray obtainPackedAxisValuesArray(JNIEnv* env, uint32_t minSize,
236 jobject outPointerCoordsObj) {
237 jfloatArray outValuesArray = jfloatArray(env->GetObjectField(outPointerCoordsObj,
238 gPointerCoordsClassInfo.mPackedAxisValues));
239 if (outValuesArray) {
240 uint32_t size = env->GetArrayLength(outValuesArray);
241 if (minSize <= size) {
242 return outValuesArray;
243 }
244 env->DeleteLocalRef(outValuesArray);
245 }
246 uint32_t size = 8;
247 while (size < minSize) {
248 size *= 2;
249 }
250 outValuesArray = env->NewFloatArray(size);
251 env->SetObjectField(outPointerCoordsObj,
252 gPointerCoordsClassInfo.mPackedAxisValues, outValuesArray);
253 return outValuesArray;
254}
255
256static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointerCoords,
257 float xOffset, float yOffset, jobject outPointerCoordsObj) {
258 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800259 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800260 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800261 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800262 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.pressure,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800263 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800264 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.size,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800265 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_SIZE));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800266 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMajor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800267 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800268 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMinor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800269 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800270 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMajor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800271 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800272 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMinor,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800273 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800274 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.orientation,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800275 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800276
Jeff Brown6f2fba42011-02-19 01:08:02 -0800277 const uint64_t unpackedAxisBits = 0
278 | (1LL << AMOTION_EVENT_AXIS_X)
279 | (1LL << AMOTION_EVENT_AXIS_Y)
280 | (1LL << AMOTION_EVENT_AXIS_PRESSURE)
281 | (1LL << AMOTION_EVENT_AXIS_SIZE)
282 | (1LL << AMOTION_EVENT_AXIS_TOUCH_MAJOR)
283 | (1LL << AMOTION_EVENT_AXIS_TOUCH_MINOR)
284 | (1LL << AMOTION_EVENT_AXIS_TOOL_MAJOR)
285 | (1LL << AMOTION_EVENT_AXIS_TOOL_MINOR)
286 | (1LL << AMOTION_EVENT_AXIS_ORIENTATION);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800287
Jeff Brown6f2fba42011-02-19 01:08:02 -0800288 uint64_t outBits = 0;
289 uint64_t remainingBits = rawPointerCoords->bits & ~unpackedAxisBits;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800290 if (remainingBits) {
Jeff Brown6f2fba42011-02-19 01:08:02 -0800291 uint32_t packedAxesCount = __builtin_popcountll(remainingBits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800292 jfloatArray outValuesArray = obtainPackedAxisValuesArray(env, packedAxesCount,
293 outPointerCoordsObj);
294 if (!outValuesArray) {
295 return; // OOM
Jeff Brown20e987b2010-08-23 12:01:02 -0700296 }
297
Jeff Brown91c69ab2011-02-14 17:03:18 -0800298 jfloat* outValues = static_cast<jfloat*>(env->GetPrimitiveArrayCritical(
299 outValuesArray, NULL));
Jeff Brown20e987b2010-08-23 12:01:02 -0700300
Jeff Brown91c69ab2011-02-14 17:03:18 -0800301 const float* values = rawPointerCoords->values;
302 uint32_t index = 0;
303 do {
Jeff Browncc0c1592011-02-19 05:07:28 -0800304 uint32_t axis = __builtin_ctzll(remainingBits);
Jeff Brown6f2fba42011-02-19 01:08:02 -0800305 uint64_t axisBit = 1LL << axis;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800306 remainingBits &= ~axisBit;
307 outBits |= axisBit;
308 outValues[index++] = rawPointerCoords->getAxisValue(axis);
309 } while (remainingBits);
310
311 env->ReleasePrimitiveArrayCritical(outValuesArray, outValues, 0);
312 env->DeleteLocalRef(outValuesArray);
313 }
Jeff Brown6f2fba42011-02-19 01:08:02 -0800314 env->SetLongField(outPointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits, outBits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800315}
316
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700317static void pointerPropertiesToNative(JNIEnv* env, jobject pointerPropertiesObj,
318 PointerProperties* outPointerProperties) {
319 outPointerProperties->clear();
320 outPointerProperties->id = env->GetIntField(pointerPropertiesObj,
321 gPointerPropertiesClassInfo.id);
322 outPointerProperties->toolType = env->GetIntField(pointerPropertiesObj,
323 gPointerPropertiesClassInfo.toolType);
324}
325
326static void pointerPropertiesFromNative(JNIEnv* env, const PointerProperties* pointerProperties,
327 jobject outPointerPropertiesObj) {
328 env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.id,
329 pointerProperties->id);
330 env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.toolType,
331 pointerProperties->toolType);
332}
333
Jeff Brown91c69ab2011-02-14 17:03:18 -0800334
335// ----------------------------------------------------------------------------
336
337static jint android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz,
338 jint nativePtr,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700339 jint deviceId, jint source, jint action, jint flags, jint edgeFlags,
340 jint metaState, jint buttonState,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800341 jfloat xOffset, jfloat yOffset, jfloat xPrecision, jfloat yPrecision,
342 jlong downTimeNanos, jlong eventTimeNanos,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700343 jint pointerCount, jobjectArray pointerPropertiesObjArray,
344 jobjectArray pointerCoordsObjArray) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800345 if (!validatePointerCount(env, pointerCount)
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700346 || !validatePointerPropertiesArray(env, pointerPropertiesObjArray, pointerCount)
Jeff Brown91c69ab2011-02-14 17:03:18 -0800347 || !validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
348 return 0;
Jeff Brown20e987b2010-08-23 12:01:02 -0700349 }
350
Jeff Brown91c69ab2011-02-14 17:03:18 -0800351 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
352 if (!event) {
353 event = new MotionEvent();
354 }
Jeff Brown20e987b2010-08-23 12:01:02 -0700355
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700356 PointerProperties pointerProperties[pointerCount];
Jeff Brown91c69ab2011-02-14 17:03:18 -0800357 PointerCoords rawPointerCoords[pointerCount];
Jeff Brown20e987b2010-08-23 12:01:02 -0700358
Jeff Brown91c69ab2011-02-14 17:03:18 -0800359 for (jint i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700360 jobject pointerPropertiesObj = env->GetObjectArrayElement(pointerPropertiesObjArray, i);
361 if (!pointerPropertiesObj) {
362 goto Error;
363 }
364 pointerPropertiesToNative(env, pointerPropertiesObj, &pointerProperties[i]);
365 env->DeleteLocalRef(pointerPropertiesObj);
366
Jeff Brown91c69ab2011-02-14 17:03:18 -0800367 jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
368 if (!pointerCoordsObj) {
369 jniThrowNullPointerException(env, "pointerCoords");
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700370 goto Error;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800371 }
372 pointerCoordsToNative(env, pointerCoordsObj, xOffset, yOffset, &rawPointerCoords[i]);
373 env->DeleteLocalRef(pointerCoordsObj);
374 }
375
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700376 event->initialize(deviceId, source, action, flags, edgeFlags, metaState, buttonState,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800377 xOffset, yOffset, xPrecision, yPrecision,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700378 downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800379
Jeff Brown91c69ab2011-02-14 17:03:18 -0800380 return reinterpret_cast<jint>(event);
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700381
382Error:
383 if (!nativePtr) {
384 delete event;
385 }
386 return 0;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800387}
388
389static jint android_view_MotionEvent_nativeCopy(JNIEnv* env, jclass clazz,
390 jint destNativePtr, jint sourceNativePtr, jboolean keepHistory) {
391 MotionEvent* destEvent = reinterpret_cast<MotionEvent*>(destNativePtr);
392 if (!destEvent) {
393 destEvent = new MotionEvent();
394 }
395 MotionEvent* sourceEvent = reinterpret_cast<MotionEvent*>(sourceNativePtr);
396 destEvent->copyFrom(sourceEvent, keepHistory);
397 return reinterpret_cast<jint>(destEvent);
398}
399
400static void android_view_MotionEvent_nativeDispose(JNIEnv* env, jclass clazz,
401 jint nativePtr) {
402 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
403 delete event;
404}
405
406static void android_view_MotionEvent_nativeAddBatch(JNIEnv* env, jclass clazz,
407 jint nativePtr, jlong eventTimeNanos, jobjectArray pointerCoordsObjArray,
408 jint metaState) {
409 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
410 size_t pointerCount = event->getPointerCount();
411 if (!validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
412 return;
413 }
414
415 PointerCoords rawPointerCoords[pointerCount];
416
417 for (size_t i = 0; i < pointerCount; i++) {
418 jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
419 if (!pointerCoordsObj) {
420 jniThrowNullPointerException(env, "pointerCoords");
421 return;
422 }
423 pointerCoordsToNative(env, pointerCoordsObj,
424 event->getXOffset(), event->getYOffset(), &rawPointerCoords[i]);
425 env->DeleteLocalRef(pointerCoordsObj);
426 }
427
428 event->addSample(eventTimeNanos, rawPointerCoords);
429 event->setMetaState(event->getMetaState() | metaState);
430}
431
432static jint android_view_MotionEvent_nativeGetDeviceId(JNIEnv* env, jclass clazz,
433 jint nativePtr) {
434 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
435 return event->getDeviceId();
436}
437
438static jint android_view_MotionEvent_nativeGetSource(JNIEnv* env, jclass clazz,
439 jint nativePtr) {
440 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
441 return event->getSource();
442}
443
444static void android_view_MotionEvent_nativeSetSource(JNIEnv* env, jclass clazz,
445 jint nativePtr, jint source) {
446 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
447 event->setSource(source);
448}
449
450static jint android_view_MotionEvent_nativeGetAction(JNIEnv* env, jclass clazz,
451 jint nativePtr) {
452 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
453 return event->getAction();
454}
455
456static void android_view_MotionEvent_nativeSetAction(JNIEnv* env, jclass clazz,
457 jint nativePtr, jint action) {
458 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
459 event->setAction(action);
460}
461
Jeff Brown56194eb2011-03-02 19:23:13 -0800462static jboolean android_view_MotionEvent_nativeIsTouchEvent(JNIEnv* env, jclass clazz,
463 jint nativePtr) {
464 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
465 return event->isTouchEvent();
466}
467
Jeff Brown91c69ab2011-02-14 17:03:18 -0800468static jint android_view_MotionEvent_nativeGetFlags(JNIEnv* env, jclass clazz,
469 jint nativePtr) {
470 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
471 return event->getFlags();
472}
473
Jeff Brown21bc5c92011-02-28 18:27:14 -0800474static void android_view_MotionEvent_nativeSetFlags(JNIEnv* env, jclass clazz,
475 jint nativePtr, jint flags) {
476 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
477 event->setFlags(flags);
478}
479
Jeff Brown91c69ab2011-02-14 17:03:18 -0800480static jint android_view_MotionEvent_nativeGetEdgeFlags(JNIEnv* env, jclass clazz,
481 jint nativePtr) {
482 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
483 return event->getEdgeFlags();
484}
485
486static void android_view_MotionEvent_nativeSetEdgeFlags(JNIEnv* env, jclass clazz,
487 jint nativePtr, jint edgeFlags) {
488 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
489 event->setEdgeFlags(edgeFlags);
490}
491
492static jint android_view_MotionEvent_nativeGetMetaState(JNIEnv* env, jclass clazz,
493 jint nativePtr) {
494 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
495 return event->getMetaState();
496}
497
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700498static jint android_view_MotionEvent_nativeGetButtonState(JNIEnv* env, jclass clazz,
499 jint nativePtr) {
500 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
501 return event->getButtonState();
502}
503
Jeff Brown91c69ab2011-02-14 17:03:18 -0800504static void android_view_MotionEvent_nativeOffsetLocation(JNIEnv* env, jclass clazz,
505 jint nativePtr, jfloat deltaX, jfloat deltaY) {
506 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
507 return event->offsetLocation(deltaX, deltaY);
508}
509
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700510static jfloat android_view_MotionEvent_nativeGetXOffset(JNIEnv* env, jclass clazz,
511 jint nativePtr) {
512 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
513 return event->getXOffset();
514}
515
516static jfloat android_view_MotionEvent_nativeGetYOffset(JNIEnv* env, jclass clazz,
517 jint nativePtr) {
518 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
519 return event->getYOffset();
520}
521
Jeff Brown91c69ab2011-02-14 17:03:18 -0800522static jfloat android_view_MotionEvent_nativeGetXPrecision(JNIEnv* env, jclass clazz,
523 jint nativePtr) {
524 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
525 return event->getXPrecision();
526}
527
528static jfloat android_view_MotionEvent_nativeGetYPrecision(JNIEnv* env, jclass clazz,
529 jint nativePtr) {
530 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
531 return event->getYPrecision();
532}
533
534static jlong android_view_MotionEvent_nativeGetDownTimeNanos(JNIEnv* env, jclass clazz,
535 jint nativePtr) {
536 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
537 return event->getDownTime();
538}
539
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700540static void android_view_MotionEvent_nativeSetDownTimeNanos(JNIEnv* env, jclass clazz,
541 jint nativePtr, jlong downTimeNanos) {
542 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
543 event->setDownTime(downTimeNanos);
544}
545
Jeff Brown91c69ab2011-02-14 17:03:18 -0800546static jint android_view_MotionEvent_nativeGetPointerCount(JNIEnv* env, jclass clazz,
547 jint nativePtr) {
548 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
549 return jint(event->getPointerCount());
550}
551
552static jint android_view_MotionEvent_nativeGetPointerId(JNIEnv* env, jclass clazz,
553 jint nativePtr, jint pointerIndex) {
554 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
555 size_t pointerCount = event->getPointerCount();
556 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
557 return -1;
558 }
559 return event->getPointerId(pointerIndex);
560}
561
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700562static jint android_view_MotionEvent_nativeGetToolType(JNIEnv* env, jclass clazz,
563 jint nativePtr, jint pointerIndex) {
564 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
565 size_t pointerCount = event->getPointerCount();
566 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
567 return -1;
568 }
569 return event->getToolType(pointerIndex);
570}
571
Jeff Brown91c69ab2011-02-14 17:03:18 -0800572static jint android_view_MotionEvent_nativeFindPointerIndex(JNIEnv* env, jclass clazz,
573 jint nativePtr, jint pointerId) {
574 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
Jeff Brown2ed24622011-03-14 19:39:54 -0700575 return jint(event->findPointerIndex(pointerId));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800576}
577
578static jint android_view_MotionEvent_nativeGetHistorySize(JNIEnv* env, jclass clazz,
579 jint nativePtr) {
580 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
581 return jint(event->getHistorySize());
582}
583
584static jlong android_view_MotionEvent_nativeGetEventTimeNanos(JNIEnv* env, jclass clazz,
585 jint nativePtr, jint historyPos) {
586 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
587 if (historyPos == HISTORY_CURRENT) {
588 return event->getEventTime();
589 } else {
590 size_t historySize = event->getHistorySize();
591 if (!validateHistoryPos(env, historyPos, historySize)) {
592 return 0;
593 }
594 return event->getHistoricalEventTime(historyPos);
595 }
596}
597
598static jfloat android_view_MotionEvent_nativeGetRawAxisValue(JNIEnv* env, jclass clazz,
599 jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
600 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
601 size_t pointerCount = event->getPointerCount();
602 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
603 return 0;
604 }
605
606 if (historyPos == HISTORY_CURRENT) {
607 return event->getRawAxisValue(axis, pointerIndex);
608 } else {
609 size_t historySize = event->getHistorySize();
610 if (!validateHistoryPos(env, historyPos, historySize)) {
611 return 0;
612 }
613 return event->getHistoricalRawAxisValue(axis, pointerIndex, historyPos);
614 }
615}
616
617static jfloat android_view_MotionEvent_nativeGetAxisValue(JNIEnv* env, jclass clazz,
618 jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
619 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
620 size_t pointerCount = event->getPointerCount();
621 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
622 return 0;
623 }
624
625 if (historyPos == HISTORY_CURRENT) {
626 return event->getAxisValue(axis, pointerIndex);
627 } else {
628 size_t historySize = event->getHistorySize();
629 if (!validateHistoryPos(env, historyPos, historySize)) {
630 return 0;
631 }
632 return event->getHistoricalAxisValue(axis, pointerIndex, historyPos);
633 }
634}
635
636static void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass clazz,
637 jint nativePtr, jint pointerIndex, jint historyPos, jobject outPointerCoordsObj) {
638 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
639 size_t pointerCount = event->getPointerCount();
640 if (!validatePointerIndex(env, pointerIndex, pointerCount)
641 || !validatePointerCoords(env, outPointerCoordsObj)) {
642 return;
643 }
644
645 const PointerCoords* rawPointerCoords;
646 if (historyPos == HISTORY_CURRENT) {
647 rawPointerCoords = event->getRawPointerCoords(pointerIndex);
648 } else {
649 size_t historySize = event->getHistorySize();
650 if (!validateHistoryPos(env, historyPos, historySize)) {
651 return;
652 }
653 rawPointerCoords = event->getHistoricalRawPointerCoords(pointerIndex, historyPos);
654 }
655 pointerCoordsFromNative(env, rawPointerCoords, event->getXOffset(), event->getYOffset(),
656 outPointerCoordsObj);
657}
658
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700659static void android_view_MotionEvent_nativeGetPointerProperties(JNIEnv* env, jclass clazz,
660 jint nativePtr, jint pointerIndex, jobject outPointerPropertiesObj) {
661 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
662 size_t pointerCount = event->getPointerCount();
663 if (!validatePointerIndex(env, pointerIndex, pointerCount)
664 || !validatePointerProperties(env, outPointerPropertiesObj)) {
665 return;
666 }
667
668 const PointerProperties* pointerProperties = event->getPointerProperties(pointerIndex);
669 pointerPropertiesFromNative(env, pointerProperties, outPointerPropertiesObj);
670}
671
Jeff Brown91c69ab2011-02-14 17:03:18 -0800672static void android_view_MotionEvent_nativeScale(JNIEnv* env, jclass clazz,
673 jint nativePtr, jfloat scale) {
674 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
675 event->scale(scale);
676}
677
678static void android_view_MotionEvent_nativeTransform(JNIEnv* env, jclass clazz,
679 jint nativePtr, jobject matrixObj) {
680 SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
681 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
682 event->transform(matrix);
683}
684
685static jint android_view_MotionEvent_nativeReadFromParcel(JNIEnv* env, jclass clazz,
686 jint nativePtr, jobject parcelObj) {
687 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
688 if (!event) {
689 event = new MotionEvent();
690 }
691
692 Parcel* parcel = parcelForJavaObject(env, parcelObj);
693
694 status_t status = event->readFromParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800695 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800696 if (!nativePtr) {
697 delete event;
698 }
699 jniThrowRuntimeException(env, "Failed to read MotionEvent parcel.");
700 return 0;
701 }
702 return reinterpret_cast<jint>(event);
703}
704
705static void android_view_MotionEvent_nativeWriteToParcel(JNIEnv* env, jclass clazz,
706 jint nativePtr, jobject parcelObj) {
707 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
708 Parcel* parcel = parcelForJavaObject(env, parcelObj);
709
710 status_t status = event->writeToParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800711 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800712 jniThrowRuntimeException(env, "Failed to write MotionEvent parcel.");
713 }
Jeff Brown20e987b2010-08-23 12:01:02 -0700714}
715
Jeff Brown46b9ac02010-04-22 18:58:52 -0700716// ----------------------------------------------------------------------------
717
Jeff Brown20e987b2010-08-23 12:01:02 -0700718static JNINativeMethod gMotionEventMethods[] = {
719 /* name, signature, funcPtr */
Jeff Brown91c69ab2011-02-14 17:03:18 -0800720 { "nativeInitialize",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700721 "(IIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;"
722 "[Landroid/view/MotionEvent$PointerCoords;)I",
Jeff Brown91c69ab2011-02-14 17:03:18 -0800723 (void*)android_view_MotionEvent_nativeInitialize },
724 { "nativeCopy",
725 "(IIZ)I",
726 (void*)android_view_MotionEvent_nativeCopy },
727 { "nativeDispose",
728 "(I)V",
729 (void*)android_view_MotionEvent_nativeDispose },
730 { "nativeAddBatch",
731 "(IJ[Landroid/view/MotionEvent$PointerCoords;I)V",
732 (void*)android_view_MotionEvent_nativeAddBatch },
733 { "nativeGetDeviceId",
734 "(I)I",
735 (void*)android_view_MotionEvent_nativeGetDeviceId },
736 { "nativeGetSource",
737 "(I)I",
738 (void*)android_view_MotionEvent_nativeGetSource },
739 { "nativeSetSource",
740 "(II)I",
741 (void*)android_view_MotionEvent_nativeSetSource },
742 { "nativeGetAction",
743 "(I)I",
744 (void*)android_view_MotionEvent_nativeGetAction },
745 { "nativeSetAction",
746 "(II)V",
747 (void*)android_view_MotionEvent_nativeSetAction },
Jeff Brown56194eb2011-03-02 19:23:13 -0800748 { "nativeIsTouchEvent",
749 "(I)Z",
750 (void*)android_view_MotionEvent_nativeIsTouchEvent },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800751 { "nativeGetFlags",
752 "(I)I",
753 (void*)android_view_MotionEvent_nativeGetFlags },
Jeff Brown21bc5c92011-02-28 18:27:14 -0800754 { "nativeSetFlags",
755 "(II)V",
756 (void*)android_view_MotionEvent_nativeSetFlags },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800757 { "nativeGetEdgeFlags",
758 "(I)I",
759 (void*)android_view_MotionEvent_nativeGetEdgeFlags },
760 { "nativeSetEdgeFlags",
761 "(II)V",
762 (void*)android_view_MotionEvent_nativeSetEdgeFlags },
763 { "nativeGetMetaState",
764 "(I)I",
765 (void*)android_view_MotionEvent_nativeGetMetaState },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700766 { "nativeGetButtonState",
767 "(I)I",
768 (void*)android_view_MotionEvent_nativeGetButtonState },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800769 { "nativeOffsetLocation",
770 "(IFF)V",
771 (void*)android_view_MotionEvent_nativeOffsetLocation },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700772 { "nativeGetXOffset",
773 "(I)F",
774 (void*)android_view_MotionEvent_nativeGetXOffset },
775 { "nativeGetYOffset",
776 "(I)F",
777 (void*)android_view_MotionEvent_nativeGetYOffset },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800778 { "nativeGetXPrecision",
779 "(I)F",
780 (void*)android_view_MotionEvent_nativeGetXPrecision },
781 { "nativeGetYPrecision",
782 "(I)F",
783 (void*)android_view_MotionEvent_nativeGetYPrecision },
784 { "nativeGetDownTimeNanos",
785 "(I)J",
786 (void*)android_view_MotionEvent_nativeGetDownTimeNanos },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700787 { "nativeSetDownTimeNanos",
788 "(IJ)V",
789 (void*)android_view_MotionEvent_nativeSetDownTimeNanos },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800790 { "nativeGetPointerCount",
791 "(I)I",
792 (void*)android_view_MotionEvent_nativeGetPointerCount },
793 { "nativeGetPointerId",
794 "(II)I",
795 (void*)android_view_MotionEvent_nativeGetPointerId },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700796 { "nativeGetToolType",
797 "(II)I",
798 (void*)android_view_MotionEvent_nativeGetToolType },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800799 { "nativeFindPointerIndex",
800 "(II)I",
801 (void*)android_view_MotionEvent_nativeFindPointerIndex },
802 { "nativeGetHistorySize",
803 "(I)I",
804 (void*)android_view_MotionEvent_nativeGetHistorySize },
805 { "nativeGetEventTimeNanos",
806 "(II)J",
807 (void*)android_view_MotionEvent_nativeGetEventTimeNanos },
808 { "nativeGetRawAxisValue",
809 "(IIII)F",
810 (void*)android_view_MotionEvent_nativeGetRawAxisValue },
811 { "nativeGetAxisValue",
812 "(IIII)F",
813 (void*)android_view_MotionEvent_nativeGetAxisValue },
814 { "nativeGetPointerCoords",
815 "(IIILandroid/view/MotionEvent$PointerCoords;)V",
816 (void*)android_view_MotionEvent_nativeGetPointerCoords },
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700817 { "nativeGetPointerProperties",
818 "(IILandroid/view/MotionEvent$PointerProperties;)V",
819 (void*)android_view_MotionEvent_nativeGetPointerProperties },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800820 { "nativeScale",
821 "(IF)V",
822 (void*)android_view_MotionEvent_nativeScale },
Jeff Brown20e987b2010-08-23 12:01:02 -0700823 { "nativeTransform",
Jeff Brown91c69ab2011-02-14 17:03:18 -0800824 "(ILandroid/graphics/Matrix;)V",
Jeff Brown20e987b2010-08-23 12:01:02 -0700825 (void*)android_view_MotionEvent_nativeTransform },
Jeff Brown91c69ab2011-02-14 17:03:18 -0800826 { "nativeReadFromParcel",
827 "(ILandroid/os/Parcel;)I",
828 (void*)android_view_MotionEvent_nativeReadFromParcel },
829 { "nativeWriteToParcel",
830 "(ILandroid/os/Parcel;)V",
831 (void*)android_view_MotionEvent_nativeWriteToParcel },
Jeff Brown20e987b2010-08-23 12:01:02 -0700832};
833
Jeff Brown46b9ac02010-04-22 18:58:52 -0700834#define FIND_CLASS(var, className) \
835 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800836 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700837
838#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
839 var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
840 LOG_FATAL_IF(! var, "Unable to find static method" methodName);
841
842#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
843 var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
844 LOG_FATAL_IF(! var, "Unable to find method" methodName);
845
846#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
847 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
848 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
849
850int register_android_view_MotionEvent(JNIEnv* env) {
Jeff Brown20e987b2010-08-23 12:01:02 -0700851 int res = jniRegisterNativeMethods(env, "android/view/MotionEvent",
852 gMotionEventMethods, NELEM(gMotionEventMethods));
853 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
854
Jeff Brown46b9ac02010-04-22 18:58:52 -0700855 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800856 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown46b9ac02010-04-22 18:58:52 -0700857
858 GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800859 "obtain", "()Landroid/view/MotionEvent;");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700860 GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
861 "recycle", "()V");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800862 GET_FIELD_ID(gMotionEventClassInfo.mNativePtr, gMotionEventClassInfo.clazz,
863 "mNativePtr", "I");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700864
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800865 jclass clazz;
866 FIND_CLASS(clazz, "android/view/MotionEvent$PointerCoords");
Jeff Brown91c69ab2011-02-14 17:03:18 -0800867
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800868 GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, clazz,
Jeff Brown6f2fba42011-02-19 01:08:02 -0800869 "mPackedAxisBits", "J");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800870 GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800871 "mPackedAxisValues", "[F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800872 GET_FIELD_ID(gPointerCoordsClassInfo.x, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800873 "x", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800874 GET_FIELD_ID(gPointerCoordsClassInfo.y, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800875 "y", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800876 GET_FIELD_ID(gPointerCoordsClassInfo.pressure, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800877 "pressure", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800878 GET_FIELD_ID(gPointerCoordsClassInfo.size, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800879 "size", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800880 GET_FIELD_ID(gPointerCoordsClassInfo.touchMajor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800881 "touchMajor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800882 GET_FIELD_ID(gPointerCoordsClassInfo.touchMinor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800883 "touchMinor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800884 GET_FIELD_ID(gPointerCoordsClassInfo.toolMajor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800885 "toolMajor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800886 GET_FIELD_ID(gPointerCoordsClassInfo.toolMinor, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800887 "toolMinor", "F");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800888 GET_FIELD_ID(gPointerCoordsClassInfo.orientation, clazz,
Jeff Brown91c69ab2011-02-14 17:03:18 -0800889 "orientation", "F");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700890
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700891 FIND_CLASS(clazz, "android/view/MotionEvent$PointerProperties");
892
893 GET_FIELD_ID(gPointerPropertiesClassInfo.id, clazz,
894 "id", "I");
895 GET_FIELD_ID(gPointerPropertiesClassInfo.toolType, clazz,
896 "toolType", "I");
897
Jeff Brown46b9ac02010-04-22 18:58:52 -0700898 return 0;
899}
900
901} // namespace android