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");