From 45f12c3c1c2baded797d665dd3c69de526736871 Mon Sep 17 00:00:00 2001 From: Prabir Pradhan Date: Fri, 14 May 2021 16:53:54 -0700 Subject: [PATCH] MotionEvent: Add relative X and Y fields to PointerCoords PointerCoord's axes AXIS_RELATIVE_X and AXIS_RELATIVE_Y are affected by the MotionEvent's transform because they need to be rotated according to the window orientation. We add fields for those axes in PointerCoords, and ensure they are rotated when populating the java instance from a native one. Bug: 179274888 Test: build, manual with test app Change-Id: Iab529ee7841d616678b48d301c059c9bf1311231 --- core/java/android/view/MotionEvent.java | 30 +++++++++++++++++++++++++ core/jni/android_view_MotionEvent.cpp | 20 +++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 0483d0ba76152..11b5a0615a351 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -3998,6 +3998,22 @@ public final class MotionEvent extends InputEvent implements Parcelable { */ public float orientation; + /** + * The movement of x position of a motion event. + * + * @see MotionEvent#AXIS_RELATIVE_X + * @hide + */ + public float relativeX; + + /** + * The movement of y position of a motion event. + * + * @see MotionEvent#AXIS_RELATIVE_Y + * @hide + */ + public float relativeY; + /** * Clears the contents of this object. * Resets all axes to zero. @@ -4014,6 +4030,8 @@ public final class MotionEvent extends InputEvent implements Parcelable { toolMajor = 0; toolMinor = 0; orientation = 0; + relativeX = 0; + relativeY = 0; } /** @@ -4044,6 +4062,8 @@ public final class MotionEvent extends InputEvent implements Parcelable { toolMajor = other.toolMajor; toolMinor = other.toolMinor; orientation = other.orientation; + relativeX = other.relativeX; + relativeY = other.relativeY; } /** @@ -4075,6 +4095,10 @@ public final class MotionEvent extends InputEvent implements Parcelable { return toolMinor; case AXIS_ORIENTATION: return orientation; + case AXIS_RELATIVE_X: + return relativeX; + case AXIS_RELATIVE_Y: + return relativeY; default: { if (axis < 0 || axis > 63) { throw new IllegalArgumentException("Axis out of range."); @@ -4128,6 +4152,12 @@ public final class MotionEvent extends InputEvent implements Parcelable { case AXIS_ORIENTATION: orientation = value; break; + case AXIS_RELATIVE_X: + relativeX = value; + break; + case AXIS_RELATIVE_Y: + relativeY = value; + break; default: { if (axis < 0 || axis > 63) { throw new IllegalArgumentException("Axis out of range."); diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp index 6971301cec32d..a2ca1111b878b 100644 --- a/core/jni/android_view_MotionEvent.cpp +++ b/core/jni/android_view_MotionEvent.cpp @@ -56,6 +56,8 @@ static struct { jfieldID toolMajor; jfieldID toolMinor; jfieldID orientation; + jfieldID relativeX; + jfieldID relativeY; } gPointerCoordsClassInfo; static struct { @@ -212,6 +214,12 @@ static void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj, env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMinor)); outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.orientation)); + outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, + env->GetFloatField(pointerCoordsObj, + gPointerCoordsClassInfo.relativeX)); + outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, + env->GetFloatField(pointerCoordsObj, + gPointerCoordsClassInfo.relativeY)); BitSet64 bits = BitSet64(env->GetLongField(pointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits)); @@ -261,6 +269,12 @@ static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointer 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, @@ -277,6 +291,8 @@ static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointer 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); uint64_t outBits = 0; BitSet64 bits = BitSet64(rawPointerCoords->bits); @@ -289,6 +305,8 @@ static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointer 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, @@ -872,6 +890,8 @@ int register_android_view_MotionEvent(JNIEnv* env) { gPointerCoordsClassInfo.toolMajor = GetFieldIDOrDie(env, clazz, "toolMajor", "F"); gPointerCoordsClassInfo.toolMinor = GetFieldIDOrDie(env, clazz, "toolMinor", "F"); gPointerCoordsClassInfo.orientation = GetFieldIDOrDie(env, clazz, "orientation", "F"); + gPointerCoordsClassInfo.relativeX = GetFieldIDOrDie(env, clazz, "relativeX", "F"); + gPointerCoordsClassInfo.relativeY = GetFieldIDOrDie(env, clazz, "relativeY", "F"); clazz = FindClassOrDie(env, "android/view/MotionEvent$PointerProperties");