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