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
This commit is contained in:
Prabir Pradhan
2021-05-14 16:53:54 -07:00
parent d4fcf3ac04
commit 45f12c3c1c
2 changed files with 50 additions and 0 deletions

View File

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

View File

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