diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp index efd0547c559ba..292f30510aa0f 100644 --- a/core/jni/android_view_MotionEvent.cpp +++ b/core/jni/android_view_MotionEvent.cpp @@ -265,49 +265,9 @@ static jfloatArray obtainPackedAxisValuesArray(JNIEnv* env, uint32_t minSize, } static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointerCoords, - ui::Transform transform, jobject outPointerCoordsObj) { - float rawX = rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X); - float rawY = rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y); - vec2 transformed = transform.transform(rawX, rawY); - - float rawRelX = rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X); - float rawRelY = rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y); - // Apply only rotation and scale, not translation. - const vec2 transformedOrigin = transform.transform(0, 0); - const vec2 transformedRel = transform.transform(rawRelX, rawRelY) - transformedOrigin; - - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x, transformed.x); - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y, transformed.y); - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.pressure, - rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_PRESSURE)); - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.size, - rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_SIZE)); - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMajor, - rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR)); - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMinor, - rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR)); - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMajor, - rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR)); - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMinor, - rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR)); - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.orientation, - rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION)); - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.relativeX, transformedRel.x); - env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.relativeY, transformedRel.y); - + const BitSet64& axesBitsToCopy, jobject outPointerCoordsObj) { + BitSet64 bits = axesBitsToCopy; uint64_t outBits = 0; - BitSet64 bits = BitSet64(rawPointerCoords->bits); - bits.clearBit(AMOTION_EVENT_AXIS_X); - bits.clearBit(AMOTION_EVENT_AXIS_Y); - bits.clearBit(AMOTION_EVENT_AXIS_PRESSURE); - bits.clearBit(AMOTION_EVENT_AXIS_SIZE); - bits.clearBit(AMOTION_EVENT_AXIS_TOUCH_MAJOR); - bits.clearBit(AMOTION_EVENT_AXIS_TOUCH_MINOR); - bits.clearBit(AMOTION_EVENT_AXIS_TOOL_MAJOR); - bits.clearBit(AMOTION_EVENT_AXIS_TOOL_MINOR); - bits.clearBit(AMOTION_EVENT_AXIS_ORIENTATION); - bits.clearBit(AMOTION_EVENT_AXIS_RELATIVE_X); - bits.clearBit(AMOTION_EVENT_AXIS_RELATIVE_Y); if (!bits.isEmpty()) { uint32_t packedAxesCount = bits.count(); jfloatArray outValuesArray = obtainPackedAxisValuesArray(env, packedAxesCount, @@ -444,18 +404,42 @@ static void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass || !validatePointerCoords(env, outPointerCoordsObj)) { return; } - - const PointerCoords* rawPointerCoords; - if (historyPos == HISTORY_CURRENT) { - rawPointerCoords = event->getRawPointerCoords(pointerIndex); - } else { - size_t historySize = event->getHistorySize(); - if (!validateHistoryPos(env, historyPos, historySize)) { - return; - } - rawPointerCoords = event->getHistoricalRawPointerCoords(pointerIndex, historyPos); + if (historyPos != HISTORY_CURRENT && + !validateHistoryPos(env, historyPos, event->getHistorySize())) { + return; } - pointerCoordsFromNative(env, rawPointerCoords, event->getTransform(), outPointerCoordsObj); + + // Obtain the following axis values directly from the MotionEvent instead of from the raw + // PointerCoords. + const static std::array, 11> kAxesFromMotionEvent = {{ + {AMOTION_EVENT_AXIS_X, gPointerCoordsClassInfo.x}, + {AMOTION_EVENT_AXIS_Y, gPointerCoordsClassInfo.y}, + {AMOTION_EVENT_AXIS_PRESSURE, gPointerCoordsClassInfo.pressure}, + {AMOTION_EVENT_AXIS_SIZE, gPointerCoordsClassInfo.size}, + {AMOTION_EVENT_AXIS_TOUCH_MAJOR, gPointerCoordsClassInfo.touchMajor}, + {AMOTION_EVENT_AXIS_TOUCH_MINOR, gPointerCoordsClassInfo.touchMinor}, + {AMOTION_EVENT_AXIS_TOOL_MAJOR, gPointerCoordsClassInfo.toolMajor}, + {AMOTION_EVENT_AXIS_TOOL_MINOR, gPointerCoordsClassInfo.toolMinor}, + {AMOTION_EVENT_AXIS_ORIENTATION, gPointerCoordsClassInfo.orientation}, + {AMOTION_EVENT_AXIS_RELATIVE_X, gPointerCoordsClassInfo.relativeX}, + {AMOTION_EVENT_AXIS_RELATIVE_Y, gPointerCoordsClassInfo.relativeY}, + }}; + for (const auto& [axis, fieldId] : kAxesFromMotionEvent) { + const float value = historyPos == HISTORY_CURRENT + ? event->getAxisValue(axis, pointerIndex) + : event->getHistoricalAxisValue(axis, pointerIndex, historyPos); + env->SetFloatField(outPointerCoordsObj, fieldId, value); + } + + const PointerCoords* rawPointerCoords = historyPos == HISTORY_CURRENT + ? event->getRawPointerCoords(pointerIndex) + : event->getHistoricalRawPointerCoords(pointerIndex, historyPos); + + BitSet64 bits = BitSet64(rawPointerCoords->bits); + for (const auto [axis, _] : kAxesFromMotionEvent) { + bits.clearBit(axis); + } + pointerCoordsFromNative(env, rawPointerCoords, bits, outPointerCoordsObj); } static void android_view_MotionEvent_nativeGetPointerProperties(JNIEnv* env, jclass clazz,