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