1 /*
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 <SkMatrix.h>
22 #include <android_runtime/AndroidRuntime.h>
23 #include <android_runtime/Log.h>
24 #include <utils/Log.h>
25 #include <input/Input.h>
26 #include <ScopedUtfChars.h>
27 #include "android_os_Parcel.h"
28 #include "android_view_MotionEvent.h"
29 #include "android_util_Binder.h"
30 #include "android/graphics/Matrix.h"
31
32 namespace android {
33
34 // ----------------------------------------------------------------------------
35
36 static struct {
37 jclass clazz;
38
39 jmethodID obtain;
40 jmethodID recycle;
41
42 jfieldID mNativePtr;
43 } gMotionEventClassInfo;
44
45 static struct {
46 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
59 static struct {
60 jfieldID id;
61 jfieldID toolType;
62 } gPointerPropertiesClassInfo;
63
64 // ----------------------------------------------------------------------------
65
android_view_MotionEvent_getNativePtr(JNIEnv * env,jobject eventObj)66 MotionEvent* android_view_MotionEvent_getNativePtr(JNIEnv* env, jobject eventObj) {
67 if (!eventObj) {
68 return NULL;
69 }
70 return reinterpret_cast<MotionEvent*>(
71 env->GetLongField(eventObj, gMotionEventClassInfo.mNativePtr));
72 }
73
android_view_MotionEvent_setNativePtr(JNIEnv * env,jobject eventObj,MotionEvent * event)74 static void android_view_MotionEvent_setNativePtr(JNIEnv* env, jobject eventObj,
75 MotionEvent* event) {
76 env->SetLongField(eventObj, gMotionEventClassInfo.mNativePtr,
77 reinterpret_cast<jlong>(event));
78 }
79
android_view_MotionEvent_obtainAsCopy(JNIEnv * env,const MotionEvent * event)80 jobject android_view_MotionEvent_obtainAsCopy(JNIEnv* env, const MotionEvent* event) {
81 jobject eventObj = env->CallStaticObjectMethod(gMotionEventClassInfo.clazz,
82 gMotionEventClassInfo.obtain);
83 if (env->ExceptionCheck() || !eventObj) {
84 ALOGE("An exception occurred while obtaining a motion event.");
85 LOGE_EX(env);
86 env->ExceptionClear();
87 return NULL;
88 }
89
90 MotionEvent* destEvent = android_view_MotionEvent_getNativePtr(env, eventObj);
91 if (!destEvent) {
92 destEvent = new MotionEvent();
93 android_view_MotionEvent_setNativePtr(env, eventObj, destEvent);
94 }
95
96 destEvent->copyFrom(event, true);
97 return eventObj;
98 }
99
android_view_MotionEvent_recycle(JNIEnv * env,jobject eventObj)100 status_t android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj) {
101 env->CallVoidMethod(eventObj, gMotionEventClassInfo.recycle);
102 if (env->ExceptionCheck()) {
103 ALOGW("An exception occurred while recycling a motion event.");
104 LOGW_EX(env);
105 env->ExceptionClear();
106 return UNKNOWN_ERROR;
107 }
108 return OK;
109 }
110
111 // ----------------------------------------------------------------------------
112
113 static const jint HISTORY_CURRENT = -0x80000000;
114
validatePointerCount(JNIEnv * env,jint pointerCount)115 static 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;
120 }
121 return true;
122 }
123
validatePointerPropertiesArray(JNIEnv * env,jobjectArray pointerPropertiesObjArray,size_t pointerCount)124 static bool validatePointerPropertiesArray(JNIEnv* env, jobjectArray pointerPropertiesObjArray,
125 size_t pointerCount) {
126 if (!pointerPropertiesObjArray) {
127 jniThrowException(env, "java/lang/IllegalArgumentException",
128 "pointerProperties array must not be null");
129 return false;
130 }
131 size_t length = size_t(env->GetArrayLength(pointerPropertiesObjArray));
132 if (length < pointerCount) {
133 jniThrowException(env, "java/lang/IllegalArgumentException",
134 "pointerProperties array must be large enough to hold all pointers");
135 return false;
136 }
137 return true;
138 }
139
validatePointerCoordsObjArray(JNIEnv * env,jobjectArray pointerCoordsObjArray,size_t pointerCount)140 static 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 }
155
validatePointerIndex(JNIEnv * env,jint pointerIndex,size_t pointerCount)156 static 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 }
164
validateHistoryPos(JNIEnv * env,jint historyPos,size_t historySize)165 static 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 }
173
validatePointerCoords(JNIEnv * env,jobject pointerCoordsObj)174 static 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
validatePointerProperties(JNIEnv * env,jobject pointerPropertiesObj)183 static 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
pointerCoordsToNative(JNIEnv * env,jobject pointerCoordsObj,float xOffset,float yOffset,PointerCoords * outRawPointerCoords)192 static void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj,
193 float xOffset, float yOffset, PointerCoords* outRawPointerCoords) {
194 outRawPointerCoords->clear();
195 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_X,
196 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.x) - xOffset);
197 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_Y,
198 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.y) - yOffset);
199 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
200 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.pressure));
201 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_SIZE,
202 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.size));
203 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
204 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMajor));
205 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR,
206 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMinor));
207 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR,
208 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMajor));
209 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR,
210 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMinor));
211 outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
212 env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.orientation));
213
214 BitSet64 bits =
215 BitSet64(env->GetLongField(pointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits));
216 if (!bits.isEmpty()) {
217 jfloatArray valuesArray = jfloatArray(env->GetObjectField(pointerCoordsObj,
218 gPointerCoordsClassInfo.mPackedAxisValues));
219 if (valuesArray) {
220 jfloat* values = static_cast<jfloat*>(
221 env->GetPrimitiveArrayCritical(valuesArray, NULL));
222
223 uint32_t index = 0;
224 do {
225 uint32_t axis = bits.clearFirstMarkedBit();
226 outRawPointerCoords->setAxisValue(axis, values[index++]);
227 } while (!bits.isEmpty());
228
229 env->ReleasePrimitiveArrayCritical(valuesArray, values, JNI_ABORT);
230 env->DeleteLocalRef(valuesArray);
231 }
232 }
233 }
234
obtainPackedAxisValuesArray(JNIEnv * env,uint32_t minSize,jobject outPointerCoordsObj)235 static 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
pointerCoordsFromNative(JNIEnv * env,const PointerCoords * rawPointerCoords,float xOffset,float yOffset,jobject outPointerCoordsObj)256 static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointerCoords,
257 float xOffset, float yOffset, jobject outPointerCoordsObj) {
258 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x,
259 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset);
260 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y,
261 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset);
262 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.pressure,
263 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
264 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.size,
265 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_SIZE));
266 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMajor,
267 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR));
268 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMinor,
269 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR));
270 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMajor,
271 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR));
272 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMinor,
273 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR));
274 env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.orientation,
275 rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
276
277 uint64_t outBits = 0;
278 BitSet64 bits = BitSet64(rawPointerCoords->bits);
279 bits.clearBit(AMOTION_EVENT_AXIS_X);
280 bits.clearBit(AMOTION_EVENT_AXIS_Y);
281 bits.clearBit(AMOTION_EVENT_AXIS_PRESSURE);
282 bits.clearBit(AMOTION_EVENT_AXIS_SIZE);
283 bits.clearBit(AMOTION_EVENT_AXIS_TOUCH_MAJOR);
284 bits.clearBit(AMOTION_EVENT_AXIS_TOUCH_MINOR);
285 bits.clearBit(AMOTION_EVENT_AXIS_TOOL_MAJOR);
286 bits.clearBit(AMOTION_EVENT_AXIS_TOOL_MINOR);
287 bits.clearBit(AMOTION_EVENT_AXIS_ORIENTATION);
288 if (!bits.isEmpty()) {
289 uint32_t packedAxesCount = bits.count();
290 jfloatArray outValuesArray = obtainPackedAxisValuesArray(env, packedAxesCount,
291 outPointerCoordsObj);
292 if (!outValuesArray) {
293 return; // OOM
294 }
295
296 jfloat* outValues = static_cast<jfloat*>(env->GetPrimitiveArrayCritical(
297 outValuesArray, NULL));
298
299 const float* values = rawPointerCoords->values;
300 uint32_t index = 0;
301 do {
302 uint32_t axis = bits.clearFirstMarkedBit();
303 outBits |= BitSet64::valueForBit(axis);
304 outValues[index++] = rawPointerCoords->getAxisValue(axis);
305 } while (!bits.isEmpty());
306
307 env->ReleasePrimitiveArrayCritical(outValuesArray, outValues, 0);
308 env->DeleteLocalRef(outValuesArray);
309 }
310 env->SetLongField(outPointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits, outBits);
311 }
312
pointerPropertiesToNative(JNIEnv * env,jobject pointerPropertiesObj,PointerProperties * outPointerProperties)313 static void pointerPropertiesToNative(JNIEnv* env, jobject pointerPropertiesObj,
314 PointerProperties* outPointerProperties) {
315 outPointerProperties->clear();
316 outPointerProperties->id = env->GetIntField(pointerPropertiesObj,
317 gPointerPropertiesClassInfo.id);
318 outPointerProperties->toolType = env->GetIntField(pointerPropertiesObj,
319 gPointerPropertiesClassInfo.toolType);
320 }
321
pointerPropertiesFromNative(JNIEnv * env,const PointerProperties * pointerProperties,jobject outPointerPropertiesObj)322 static void pointerPropertiesFromNative(JNIEnv* env, const PointerProperties* pointerProperties,
323 jobject outPointerPropertiesObj) {
324 env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.id,
325 pointerProperties->id);
326 env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.toolType,
327 pointerProperties->toolType);
328 }
329
330
331 // ----------------------------------------------------------------------------
332
android_view_MotionEvent_nativeInitialize(JNIEnv * env,jclass clazz,jlong nativePtr,jint deviceId,jint source,jint action,jint flags,jint edgeFlags,jint metaState,jint buttonState,jfloat xOffset,jfloat yOffset,jfloat xPrecision,jfloat yPrecision,jlong downTimeNanos,jlong eventTimeNanos,jint pointerCount,jobjectArray pointerPropertiesObjArray,jobjectArray pointerCoordsObjArray)333 static jlong android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz,
334 jlong nativePtr,
335 jint deviceId, jint source, jint action, jint flags, jint edgeFlags,
336 jint metaState, jint buttonState,
337 jfloat xOffset, jfloat yOffset, jfloat xPrecision, jfloat yPrecision,
338 jlong downTimeNanos, jlong eventTimeNanos,
339 jint pointerCount, jobjectArray pointerPropertiesObjArray,
340 jobjectArray pointerCoordsObjArray) {
341 if (!validatePointerCount(env, pointerCount)
342 || !validatePointerPropertiesArray(env, pointerPropertiesObjArray, pointerCount)
343 || !validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
344 return 0;
345 }
346
347 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
348 if (!event) {
349 event = new MotionEvent();
350 }
351
352 PointerProperties pointerProperties[pointerCount];
353 PointerCoords rawPointerCoords[pointerCount];
354
355 for (jint i = 0; i < pointerCount; i++) {
356 jobject pointerPropertiesObj = env->GetObjectArrayElement(pointerPropertiesObjArray, i);
357 if (!pointerPropertiesObj) {
358 goto Error;
359 }
360 pointerPropertiesToNative(env, pointerPropertiesObj, &pointerProperties[i]);
361 env->DeleteLocalRef(pointerPropertiesObj);
362
363 jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
364 if (!pointerCoordsObj) {
365 jniThrowNullPointerException(env, "pointerCoords");
366 goto Error;
367 }
368 pointerCoordsToNative(env, pointerCoordsObj, xOffset, yOffset, &rawPointerCoords[i]);
369 env->DeleteLocalRef(pointerCoordsObj);
370 }
371
372 event->initialize(deviceId, source, action, flags, edgeFlags, metaState, buttonState,
373 xOffset, yOffset, xPrecision, yPrecision,
374 downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords);
375
376 return reinterpret_cast<jlong>(event);
377
378 Error:
379 if (!nativePtr) {
380 delete event;
381 }
382 return 0;
383 }
384
android_view_MotionEvent_nativeCopy(JNIEnv * env,jclass clazz,jlong destNativePtr,jlong sourceNativePtr,jboolean keepHistory)385 static jlong android_view_MotionEvent_nativeCopy(JNIEnv* env, jclass clazz,
386 jlong destNativePtr, jlong sourceNativePtr, jboolean keepHistory) {
387 MotionEvent* destEvent = reinterpret_cast<MotionEvent*>(destNativePtr);
388 if (!destEvent) {
389 destEvent = new MotionEvent();
390 }
391 MotionEvent* sourceEvent = reinterpret_cast<MotionEvent*>(sourceNativePtr);
392 destEvent->copyFrom(sourceEvent, keepHistory);
393 return reinterpret_cast<jlong>(destEvent);
394 }
395
android_view_MotionEvent_nativeDispose(JNIEnv * env,jclass clazz,jlong nativePtr)396 static void android_view_MotionEvent_nativeDispose(JNIEnv* env, jclass clazz,
397 jlong nativePtr) {
398 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
399 delete event;
400 }
401
android_view_MotionEvent_nativeAddBatch(JNIEnv * env,jclass clazz,jlong nativePtr,jlong eventTimeNanos,jobjectArray pointerCoordsObjArray,jint metaState)402 static void android_view_MotionEvent_nativeAddBatch(JNIEnv* env, jclass clazz,
403 jlong nativePtr, jlong eventTimeNanos, jobjectArray pointerCoordsObjArray,
404 jint metaState) {
405 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
406 size_t pointerCount = event->getPointerCount();
407 if (!validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
408 return;
409 }
410
411 PointerCoords rawPointerCoords[pointerCount];
412
413 for (size_t i = 0; i < pointerCount; i++) {
414 jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
415 if (!pointerCoordsObj) {
416 jniThrowNullPointerException(env, "pointerCoords");
417 return;
418 }
419 pointerCoordsToNative(env, pointerCoordsObj,
420 event->getXOffset(), event->getYOffset(), &rawPointerCoords[i]);
421 env->DeleteLocalRef(pointerCoordsObj);
422 }
423
424 event->addSample(eventTimeNanos, rawPointerCoords);
425 event->setMetaState(event->getMetaState() | metaState);
426 }
427
android_view_MotionEvent_nativeGetDeviceId(JNIEnv * env,jclass clazz,jlong nativePtr)428 static jint android_view_MotionEvent_nativeGetDeviceId(JNIEnv* env, jclass clazz,
429 jlong nativePtr) {
430 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
431 return event->getDeviceId();
432 }
433
android_view_MotionEvent_nativeGetSource(JNIEnv * env,jclass clazz,jlong nativePtr)434 static jint android_view_MotionEvent_nativeGetSource(JNIEnv* env, jclass clazz,
435 jlong nativePtr) {
436 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
437 return event->getSource();
438 }
439
android_view_MotionEvent_nativeSetSource(JNIEnv * env,jclass clazz,jlong nativePtr,jint source)440 static void android_view_MotionEvent_nativeSetSource(JNIEnv* env, jclass clazz,
441 jlong nativePtr, jint source) {
442 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
443 event->setSource(source);
444 }
445
android_view_MotionEvent_nativeGetAction(JNIEnv * env,jclass clazz,jlong nativePtr)446 static jint android_view_MotionEvent_nativeGetAction(JNIEnv* env, jclass clazz,
447 jlong nativePtr) {
448 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
449 return event->getAction();
450 }
451
android_view_MotionEvent_nativeSetAction(JNIEnv * env,jclass clazz,jlong nativePtr,jint action)452 static void android_view_MotionEvent_nativeSetAction(JNIEnv* env, jclass clazz,
453 jlong nativePtr, jint action) {
454 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
455 event->setAction(action);
456 }
457
android_view_MotionEvent_nativeIsTouchEvent(JNIEnv * env,jclass clazz,jlong nativePtr)458 static jboolean android_view_MotionEvent_nativeIsTouchEvent(JNIEnv* env, jclass clazz,
459 jlong nativePtr) {
460 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
461 return event->isTouchEvent();
462 }
463
android_view_MotionEvent_nativeGetFlags(JNIEnv * env,jclass clazz,jlong nativePtr)464 static jint android_view_MotionEvent_nativeGetFlags(JNIEnv* env, jclass clazz,
465 jlong nativePtr) {
466 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
467 return event->getFlags();
468 }
469
android_view_MotionEvent_nativeSetFlags(JNIEnv * env,jclass clazz,jlong nativePtr,jint flags)470 static void android_view_MotionEvent_nativeSetFlags(JNIEnv* env, jclass clazz,
471 jlong nativePtr, jint flags) {
472 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
473 event->setFlags(flags);
474 }
475
android_view_MotionEvent_nativeGetEdgeFlags(JNIEnv * env,jclass clazz,jlong nativePtr)476 static jint android_view_MotionEvent_nativeGetEdgeFlags(JNIEnv* env, jclass clazz,
477 jlong nativePtr) {
478 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
479 return event->getEdgeFlags();
480 }
481
android_view_MotionEvent_nativeSetEdgeFlags(JNIEnv * env,jclass clazz,jlong nativePtr,jint edgeFlags)482 static void android_view_MotionEvent_nativeSetEdgeFlags(JNIEnv* env, jclass clazz,
483 jlong nativePtr, jint edgeFlags) {
484 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
485 event->setEdgeFlags(edgeFlags);
486 }
487
android_view_MotionEvent_nativeGetMetaState(JNIEnv * env,jclass clazz,jlong nativePtr)488 static jint android_view_MotionEvent_nativeGetMetaState(JNIEnv* env, jclass clazz,
489 jlong nativePtr) {
490 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
491 return event->getMetaState();
492 }
493
android_view_MotionEvent_nativeGetButtonState(JNIEnv * env,jclass clazz,jlong nativePtr)494 static jint android_view_MotionEvent_nativeGetButtonState(JNIEnv* env, jclass clazz,
495 jlong nativePtr) {
496 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
497 return event->getButtonState();
498 }
499
android_view_MotionEvent_nativeOffsetLocation(JNIEnv * env,jclass clazz,jlong nativePtr,jfloat deltaX,jfloat deltaY)500 static void android_view_MotionEvent_nativeOffsetLocation(JNIEnv* env, jclass clazz,
501 jlong nativePtr, jfloat deltaX, jfloat deltaY) {
502 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
503 return event->offsetLocation(deltaX, deltaY);
504 }
505
android_view_MotionEvent_nativeGetXOffset(JNIEnv * env,jclass clazz,jlong nativePtr)506 static jfloat android_view_MotionEvent_nativeGetXOffset(JNIEnv* env, jclass clazz,
507 jlong nativePtr) {
508 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
509 return event->getXOffset();
510 }
511
android_view_MotionEvent_nativeGetYOffset(JNIEnv * env,jclass clazz,jlong nativePtr)512 static jfloat android_view_MotionEvent_nativeGetYOffset(JNIEnv* env, jclass clazz,
513 jlong nativePtr) {
514 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
515 return event->getYOffset();
516 }
517
android_view_MotionEvent_nativeGetXPrecision(JNIEnv * env,jclass clazz,jlong nativePtr)518 static jfloat android_view_MotionEvent_nativeGetXPrecision(JNIEnv* env, jclass clazz,
519 jlong nativePtr) {
520 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
521 return event->getXPrecision();
522 }
523
android_view_MotionEvent_nativeGetYPrecision(JNIEnv * env,jclass clazz,jlong nativePtr)524 static jfloat android_view_MotionEvent_nativeGetYPrecision(JNIEnv* env, jclass clazz,
525 jlong nativePtr) {
526 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
527 return event->getYPrecision();
528 }
529
android_view_MotionEvent_nativeGetDownTimeNanos(JNIEnv * env,jclass clazz,jlong nativePtr)530 static jlong android_view_MotionEvent_nativeGetDownTimeNanos(JNIEnv* env, jclass clazz,
531 jlong nativePtr) {
532 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
533 return event->getDownTime();
534 }
535
android_view_MotionEvent_nativeSetDownTimeNanos(JNIEnv * env,jclass clazz,jlong nativePtr,jlong downTimeNanos)536 static void android_view_MotionEvent_nativeSetDownTimeNanos(JNIEnv* env, jclass clazz,
537 jlong nativePtr, jlong downTimeNanos) {
538 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
539 event->setDownTime(downTimeNanos);
540 }
541
android_view_MotionEvent_nativeGetPointerCount(JNIEnv * env,jclass clazz,jlong nativePtr)542 static jint android_view_MotionEvent_nativeGetPointerCount(JNIEnv* env, jclass clazz,
543 jlong nativePtr) {
544 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
545 return jint(event->getPointerCount());
546 }
547
android_view_MotionEvent_nativeGetPointerId(JNIEnv * env,jclass clazz,jlong nativePtr,jint pointerIndex)548 static jint android_view_MotionEvent_nativeGetPointerId(JNIEnv* env, jclass clazz,
549 jlong nativePtr, jint pointerIndex) {
550 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
551 size_t pointerCount = event->getPointerCount();
552 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
553 return -1;
554 }
555 return event->getPointerId(pointerIndex);
556 }
557
android_view_MotionEvent_nativeGetToolType(JNIEnv * env,jclass clazz,jlong nativePtr,jint pointerIndex)558 static jint android_view_MotionEvent_nativeGetToolType(JNIEnv* env, jclass clazz,
559 jlong nativePtr, jint pointerIndex) {
560 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
561 size_t pointerCount = event->getPointerCount();
562 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
563 return -1;
564 }
565 return event->getToolType(pointerIndex);
566 }
567
android_view_MotionEvent_nativeFindPointerIndex(JNIEnv * env,jclass clazz,jlong nativePtr,jint pointerId)568 static jint android_view_MotionEvent_nativeFindPointerIndex(JNIEnv* env, jclass clazz,
569 jlong nativePtr, jint pointerId) {
570 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
571 return jint(event->findPointerIndex(pointerId));
572 }
573
android_view_MotionEvent_nativeGetHistorySize(JNIEnv * env,jclass clazz,jlong nativePtr)574 static jint android_view_MotionEvent_nativeGetHistorySize(JNIEnv* env, jclass clazz,
575 jlong nativePtr) {
576 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
577 return jint(event->getHistorySize());
578 }
579
android_view_MotionEvent_nativeGetEventTimeNanos(JNIEnv * env,jclass clazz,jlong nativePtr,jint historyPos)580 static jlong android_view_MotionEvent_nativeGetEventTimeNanos(JNIEnv* env, jclass clazz,
581 jlong nativePtr, jint historyPos) {
582 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
583 if (historyPos == HISTORY_CURRENT) {
584 return event->getEventTime();
585 } else {
586 size_t historySize = event->getHistorySize();
587 if (!validateHistoryPos(env, historyPos, historySize)) {
588 return 0;
589 }
590 return event->getHistoricalEventTime(historyPos);
591 }
592 }
593
android_view_MotionEvent_nativeGetRawAxisValue(JNIEnv * env,jclass clazz,jlong nativePtr,jint axis,jint pointerIndex,jint historyPos)594 static jfloat android_view_MotionEvent_nativeGetRawAxisValue(JNIEnv* env, jclass clazz,
595 jlong nativePtr, jint axis, jint pointerIndex, jint historyPos) {
596 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
597 size_t pointerCount = event->getPointerCount();
598 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
599 return 0;
600 }
601
602 if (historyPos == HISTORY_CURRENT) {
603 return event->getRawAxisValue(axis, pointerIndex);
604 } else {
605 size_t historySize = event->getHistorySize();
606 if (!validateHistoryPos(env, historyPos, historySize)) {
607 return 0;
608 }
609 return event->getHistoricalRawAxisValue(axis, pointerIndex, historyPos);
610 }
611 }
612
android_view_MotionEvent_nativeGetAxisValue(JNIEnv * env,jclass clazz,jlong nativePtr,jint axis,jint pointerIndex,jint historyPos)613 static jfloat android_view_MotionEvent_nativeGetAxisValue(JNIEnv* env, jclass clazz,
614 jlong nativePtr, jint axis, jint pointerIndex, jint historyPos) {
615 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
616 size_t pointerCount = event->getPointerCount();
617 if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
618 return 0;
619 }
620
621 if (historyPos == HISTORY_CURRENT) {
622 return event->getAxisValue(axis, pointerIndex);
623 } else {
624 size_t historySize = event->getHistorySize();
625 if (!validateHistoryPos(env, historyPos, historySize)) {
626 return 0;
627 }
628 return event->getHistoricalAxisValue(axis, pointerIndex, historyPos);
629 }
630 }
631
android_view_MotionEvent_nativeGetPointerCoords(JNIEnv * env,jclass clazz,jlong nativePtr,jint pointerIndex,jint historyPos,jobject outPointerCoordsObj)632 static void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass clazz,
633 jlong nativePtr, jint pointerIndex, jint historyPos, jobject outPointerCoordsObj) {
634 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
635 size_t pointerCount = event->getPointerCount();
636 if (!validatePointerIndex(env, pointerIndex, pointerCount)
637 || !validatePointerCoords(env, outPointerCoordsObj)) {
638 return;
639 }
640
641 const PointerCoords* rawPointerCoords;
642 if (historyPos == HISTORY_CURRENT) {
643 rawPointerCoords = event->getRawPointerCoords(pointerIndex);
644 } else {
645 size_t historySize = event->getHistorySize();
646 if (!validateHistoryPos(env, historyPos, historySize)) {
647 return;
648 }
649 rawPointerCoords = event->getHistoricalRawPointerCoords(pointerIndex, historyPos);
650 }
651 pointerCoordsFromNative(env, rawPointerCoords, event->getXOffset(), event->getYOffset(),
652 outPointerCoordsObj);
653 }
654
android_view_MotionEvent_nativeGetPointerProperties(JNIEnv * env,jclass clazz,jlong nativePtr,jint pointerIndex,jobject outPointerPropertiesObj)655 static void android_view_MotionEvent_nativeGetPointerProperties(JNIEnv* env, jclass clazz,
656 jlong nativePtr, jint pointerIndex, jobject outPointerPropertiesObj) {
657 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
658 size_t pointerCount = event->getPointerCount();
659 if (!validatePointerIndex(env, pointerIndex, pointerCount)
660 || !validatePointerProperties(env, outPointerPropertiesObj)) {
661 return;
662 }
663
664 const PointerProperties* pointerProperties = event->getPointerProperties(pointerIndex);
665 pointerPropertiesFromNative(env, pointerProperties, outPointerPropertiesObj);
666 }
667
android_view_MotionEvent_nativeScale(JNIEnv * env,jclass clazz,jlong nativePtr,jfloat scale)668 static void android_view_MotionEvent_nativeScale(JNIEnv* env, jclass clazz,
669 jlong nativePtr, jfloat scale) {
670 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
671 event->scale(scale);
672 }
673
android_view_MotionEvent_nativeTransform(JNIEnv * env,jclass clazz,jlong nativePtr,jobject matrixObj)674 static void android_view_MotionEvent_nativeTransform(JNIEnv* env, jclass clazz,
675 jlong nativePtr, jobject matrixObj) {
676 SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
677 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
678
679 float m[9];
680 m[0] = SkScalarToFloat(matrix->get(SkMatrix::kMScaleX));
681 m[1] = SkScalarToFloat(matrix->get(SkMatrix::kMSkewX));
682 m[2] = SkScalarToFloat(matrix->get(SkMatrix::kMTransX));
683 m[3] = SkScalarToFloat(matrix->get(SkMatrix::kMSkewY));
684 m[4] = SkScalarToFloat(matrix->get(SkMatrix::kMScaleY));
685 m[5] = SkScalarToFloat(matrix->get(SkMatrix::kMTransY));
686 m[6] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp0));
687 m[7] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp1));
688 m[8] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp2));
689 event->transform(m);
690 }
691
android_view_MotionEvent_nativeReadFromParcel(JNIEnv * env,jclass clazz,jlong nativePtr,jobject parcelObj)692 static jlong android_view_MotionEvent_nativeReadFromParcel(JNIEnv* env, jclass clazz,
693 jlong nativePtr, jobject parcelObj) {
694 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
695 if (!event) {
696 event = new MotionEvent();
697 }
698
699 Parcel* parcel = parcelForJavaObject(env, parcelObj);
700
701 status_t status = event->readFromParcel(parcel);
702 if (status) {
703 if (!nativePtr) {
704 delete event;
705 }
706 jniThrowRuntimeException(env, "Failed to read MotionEvent parcel.");
707 return 0;
708 }
709 return reinterpret_cast<jlong>(event);
710 }
711
android_view_MotionEvent_nativeWriteToParcel(JNIEnv * env,jclass clazz,jlong nativePtr,jobject parcelObj)712 static void android_view_MotionEvent_nativeWriteToParcel(JNIEnv* env, jclass clazz,
713 jlong nativePtr, jobject parcelObj) {
714 MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
715 Parcel* parcel = parcelForJavaObject(env, parcelObj);
716
717 status_t status = event->writeToParcel(parcel);
718 if (status) {
719 jniThrowRuntimeException(env, "Failed to write MotionEvent parcel.");
720 }
721 }
722
android_view_MotionEvent_nativeAxisToString(JNIEnv * env,jclass clazz,jint axis)723 static jstring android_view_MotionEvent_nativeAxisToString(JNIEnv* env, jclass clazz,
724 jint axis) {
725 return env->NewStringUTF(MotionEvent::getLabel(static_cast<int32_t>(axis)));
726 }
727
android_view_MotionEvent_nativeAxisFromString(JNIEnv * env,jclass clazz,jstring label)728 static jint android_view_MotionEvent_nativeAxisFromString(JNIEnv* env, jclass clazz,
729 jstring label) {
730 ScopedUtfChars axisLabel(env, label);
731 return static_cast<jint>(MotionEvent::getAxisFromLabel(axisLabel.c_str()));
732 }
733
734 // ----------------------------------------------------------------------------
735
736 static JNINativeMethod gMotionEventMethods[] = {
737 /* name, signature, funcPtr */
738 { "nativeInitialize",
739 "(JIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;"
740 "[Landroid/view/MotionEvent$PointerCoords;)J",
741 (void*)android_view_MotionEvent_nativeInitialize },
742 { "nativeCopy",
743 "(JJZ)J",
744 (void*)android_view_MotionEvent_nativeCopy },
745 { "nativeDispose",
746 "(J)V",
747 (void*)android_view_MotionEvent_nativeDispose },
748 { "nativeAddBatch",
749 "(JJ[Landroid/view/MotionEvent$PointerCoords;I)V",
750 (void*)android_view_MotionEvent_nativeAddBatch },
751 { "nativeGetDeviceId",
752 "(J)I",
753 (void*)android_view_MotionEvent_nativeGetDeviceId },
754 { "nativeGetSource",
755 "(J)I",
756 (void*)android_view_MotionEvent_nativeGetSource },
757 { "nativeSetSource",
758 "(JI)I",
759 (void*)android_view_MotionEvent_nativeSetSource },
760 { "nativeGetAction",
761 "(J)I",
762 (void*)android_view_MotionEvent_nativeGetAction },
763 { "nativeSetAction",
764 "(JI)V",
765 (void*)android_view_MotionEvent_nativeSetAction },
766 { "nativeIsTouchEvent",
767 "(J)Z",
768 (void*)android_view_MotionEvent_nativeIsTouchEvent },
769 { "nativeGetFlags",
770 "(J)I",
771 (void*)android_view_MotionEvent_nativeGetFlags },
772 { "nativeSetFlags",
773 "(JI)V",
774 (void*)android_view_MotionEvent_nativeSetFlags },
775 { "nativeGetEdgeFlags",
776 "(J)I",
777 (void*)android_view_MotionEvent_nativeGetEdgeFlags },
778 { "nativeSetEdgeFlags",
779 "(JI)V",
780 (void*)android_view_MotionEvent_nativeSetEdgeFlags },
781 { "nativeGetMetaState",
782 "(J)I",
783 (void*)android_view_MotionEvent_nativeGetMetaState },
784 { "nativeGetButtonState",
785 "(J)I",
786 (void*)android_view_MotionEvent_nativeGetButtonState },
787 { "nativeOffsetLocation",
788 "(JFF)V",
789 (void*)android_view_MotionEvent_nativeOffsetLocation },
790 { "nativeGetXOffset",
791 "(J)F",
792 (void*)android_view_MotionEvent_nativeGetXOffset },
793 { "nativeGetYOffset",
794 "(J)F",
795 (void*)android_view_MotionEvent_nativeGetYOffset },
796 { "nativeGetXPrecision",
797 "(J)F",
798 (void*)android_view_MotionEvent_nativeGetXPrecision },
799 { "nativeGetYPrecision",
800 "(J)F",
801 (void*)android_view_MotionEvent_nativeGetYPrecision },
802 { "nativeGetDownTimeNanos",
803 "(J)J",
804 (void*)android_view_MotionEvent_nativeGetDownTimeNanos },
805 { "nativeSetDownTimeNanos",
806 "(JJ)V",
807 (void*)android_view_MotionEvent_nativeSetDownTimeNanos },
808 { "nativeGetPointerCount",
809 "(J)I",
810 (void*)android_view_MotionEvent_nativeGetPointerCount },
811 { "nativeGetPointerId",
812 "(JI)I",
813 (void*)android_view_MotionEvent_nativeGetPointerId },
814 { "nativeGetToolType",
815 "(JI)I",
816 (void*)android_view_MotionEvent_nativeGetToolType },
817 { "nativeFindPointerIndex",
818 "(JI)I",
819 (void*)android_view_MotionEvent_nativeFindPointerIndex },
820 { "nativeGetHistorySize",
821 "(J)I",
822 (void*)android_view_MotionEvent_nativeGetHistorySize },
823 { "nativeGetEventTimeNanos",
824 "(JI)J",
825 (void*)android_view_MotionEvent_nativeGetEventTimeNanos },
826 { "nativeGetRawAxisValue",
827 "(JIII)F",
828 (void*)android_view_MotionEvent_nativeGetRawAxisValue },
829 { "nativeGetAxisValue",
830 "(JIII)F",
831 (void*)android_view_MotionEvent_nativeGetAxisValue },
832 { "nativeGetPointerCoords",
833 "(JIILandroid/view/MotionEvent$PointerCoords;)V",
834 (void*)android_view_MotionEvent_nativeGetPointerCoords },
835 { "nativeGetPointerProperties",
836 "(JILandroid/view/MotionEvent$PointerProperties;)V",
837 (void*)android_view_MotionEvent_nativeGetPointerProperties },
838 { "nativeScale",
839 "(JF)V",
840 (void*)android_view_MotionEvent_nativeScale },
841 { "nativeTransform",
842 "(JLandroid/graphics/Matrix;)V",
843 (void*)android_view_MotionEvent_nativeTransform },
844 { "nativeReadFromParcel",
845 "(JLandroid/os/Parcel;)J",
846 (void*)android_view_MotionEvent_nativeReadFromParcel },
847 { "nativeWriteToParcel",
848 "(JLandroid/os/Parcel;)V",
849 (void*)android_view_MotionEvent_nativeWriteToParcel },
850 { "nativeAxisToString", "(I)Ljava/lang/String;",
851 (void*)android_view_MotionEvent_nativeAxisToString },
852 { "nativeAxisFromString", "(Ljava/lang/String;)I",
853 (void*)android_view_MotionEvent_nativeAxisFromString },
854 };
855
856 #define FIND_CLASS(var, className) \
857 var = env->FindClass(className); \
858 LOG_FATAL_IF(! var, "Unable to find class " className);
859
860 #define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
861 var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
862 LOG_FATAL_IF(! var, "Unable to find static method" methodName);
863
864 #define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
865 var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
866 LOG_FATAL_IF(! var, "Unable to find method" methodName);
867
868 #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
869 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
870 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
871
register_android_view_MotionEvent(JNIEnv * env)872 int register_android_view_MotionEvent(JNIEnv* env) {
873 int res = jniRegisterNativeMethods(env, "android/view/MotionEvent",
874 gMotionEventMethods, NELEM(gMotionEventMethods));
875 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
876
877 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
878 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
879
880 GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
881 "obtain", "()Landroid/view/MotionEvent;");
882 GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
883 "recycle", "()V");
884 GET_FIELD_ID(gMotionEventClassInfo.mNativePtr, gMotionEventClassInfo.clazz,
885 "mNativePtr", "J");
886
887 jclass clazz;
888 FIND_CLASS(clazz, "android/view/MotionEvent$PointerCoords");
889
890 GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, clazz,
891 "mPackedAxisBits", "J");
892 GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, clazz,
893 "mPackedAxisValues", "[F");
894 GET_FIELD_ID(gPointerCoordsClassInfo.x, clazz,
895 "x", "F");
896 GET_FIELD_ID(gPointerCoordsClassInfo.y, clazz,
897 "y", "F");
898 GET_FIELD_ID(gPointerCoordsClassInfo.pressure, clazz,
899 "pressure", "F");
900 GET_FIELD_ID(gPointerCoordsClassInfo.size, clazz,
901 "size", "F");
902 GET_FIELD_ID(gPointerCoordsClassInfo.touchMajor, clazz,
903 "touchMajor", "F");
904 GET_FIELD_ID(gPointerCoordsClassInfo.touchMinor, clazz,
905 "touchMinor", "F");
906 GET_FIELD_ID(gPointerCoordsClassInfo.toolMajor, clazz,
907 "toolMajor", "F");
908 GET_FIELD_ID(gPointerCoordsClassInfo.toolMinor, clazz,
909 "toolMinor", "F");
910 GET_FIELD_ID(gPointerCoordsClassInfo.orientation, clazz,
911 "orientation", "F");
912
913 FIND_CLASS(clazz, "android/view/MotionEvent$PointerProperties");
914
915 GET_FIELD_ID(gPointerPropertiesClassInfo.id, clazz,
916 "id", "I");
917 GET_FIELD_ID(gPointerPropertiesClassInfo.toolType, clazz,
918 "toolType", "I");
919
920 return 0;
921 }
922
923 } // namespace android
924