Loading core/java/android/view/MotionEvent.java +34 −9 Original line number Diff line number Diff line Loading @@ -1663,6 +1663,9 @@ public final class MotionEvent extends InputEvent implements Parcelable { @CriticalNative private static native void nativeScale(long nativePtr, float scale); @CriticalNative private static native int nativeGetSurfaceRotation(long nativePtr); private MotionEvent() { } Loading Loading @@ -3805,17 +3808,39 @@ public final class MotionEvent extends InputEvent implements Parcelable { } /** * Gets a rotation matrix that (when applied to a motionevent) will rotate that motion event * such that the result coordinates end up in the same physical location on a display whose * Gets the rotation value of the transform for this MotionEvent. * * This MotionEvent's rotation can be changed by passing a rotation matrix to * {@link #transform(Matrix)} to change the coordinate space of this event. * * @return the rotation value, or -1 if unknown or invalid. * @see Surface.Rotation * @see #createRotateMatrix(int, int, int) * * @hide */ public @Surface.Rotation int getSurfaceRotation() { return nativeGetSurfaceRotation(mNativePtr); } /** * Gets a rotation matrix that (when applied to a MotionEvent) will rotate that motion event * such that the result coordinates end up in the same physical location on a frame whose * coordinates are rotated by `rotation`. * * For example, rotating 0,0 by 90 degrees will move a point from the physical top-left to * the bottom-left of the 90-degree-rotated display. * For example, rotating (0,0) by 90 degrees will move a point from the physical top-left to * the bottom-left of the 90-degree-rotated frame. * * @param rotation the surface rotation of the output matrix * @param rotatedFrameWidth the width of the rotated frame * @param rotatedFrameHeight the height of the rotated frame * * @see #transform(Matrix) * @see #getSurfaceRotation() * @hide */ public static Matrix createRotateMatrix( @Surface.Rotation int rotation, int displayW, int displayH) { @Surface.Rotation int rotation, int rotatedFrameWidth, int rotatedFrameHeight) { if (rotation == Surface.ROTATION_0) { return new Matrix(Matrix.IDENTITY_MATRIX); } Loading @@ -3823,14 +3848,14 @@ public final class MotionEvent extends InputEvent implements Parcelable { float[] values = null; if (rotation == Surface.ROTATION_90) { values = new float[]{0, 1, 0, -1, 0, displayH, -1, 0, rotatedFrameHeight, 0, 0, 1}; } else if (rotation == Surface.ROTATION_180) { values = new float[]{-1, 0, displayW, 0, -1, displayH, values = new float[]{-1, 0, rotatedFrameWidth, 0, -1, rotatedFrameHeight, 0, 0, 1}; } else if (rotation == Surface.ROTATION_270) { values = new float[]{0, -1, displayW, values = new float[]{0, -1, rotatedFrameWidth, 1, 0, 0, 0, 0, 1}; } Loading core/jni/android_view_MotionEvent.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -769,6 +769,11 @@ static void android_view_MotionEvent_nativeScale(jlong nativePtr, jfloat scale) event->scale(scale); } static jint android_view_MotionEvent_nativeGetSurfaceRotation(jlong nativePtr) { MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); return jint(event->getSurfaceRotation()); } // ---------------------------------------------------------------------------- static const JNINativeMethod gMotionEventMethods[] = { Loading Loading @@ -845,6 +850,8 @@ static const JNINativeMethod gMotionEventMethods[] = { {"nativeFindPointerIndex", "(JI)I", (void*)android_view_MotionEvent_nativeFindPointerIndex}, {"nativeGetHistorySize", "(J)I", (void*)android_view_MotionEvent_nativeGetHistorySize}, {"nativeScale", "(JF)V", (void*)android_view_MotionEvent_nativeScale}, {"nativeGetSurfaceRotation", "(J)I", (void*)android_view_MotionEvent_nativeGetSurfaceRotation}, }; int register_android_view_MotionEvent(JNIEnv* env) { Loading core/tests/coretests/src/android/view/MotionEventTest.java +28 −6 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import android.graphics.Matrix; import android.platform.test.annotations.Presubmit; import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerProperties; Loading Loading @@ -174,22 +175,43 @@ public class MotionEventTest { @Test public void testEventRotation() { // The un-rotated frame size. final int width = 600; final int height = 1000; final MotionEvent event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */, ACTION_DOWN, 30 /* x */, 50 /* y */, 0 /* metaState */); event.setSource(InputDevice.SOURCE_TOUCHSCREEN); assertEquals(Surface.ROTATION_0, event.getSurfaceRotation()); MotionEvent rot90 = MotionEvent.obtain(event); rot90.transform(MotionEvent.createRotateMatrix(/* 90 deg */1, 1000, 600)); rot90.transform(MotionEvent.createRotateMatrix(Surface.ROTATION_90, height, width)); assertEquals(50, (int) rot90.getX()); assertEquals(570, (int) rot90.getY()); assertEquals(Surface.ROTATION_90, rot90.getSurfaceRotation()); MotionEvent rot180 = MotionEvent.obtain(event); rot180.transform(MotionEvent.createRotateMatrix(/* 180 deg */2, 1000, 600)); assertEquals(970, (int) rot180.getX()); assertEquals(550, (int) rot180.getY()); rot180.transform(MotionEvent.createRotateMatrix(Surface.ROTATION_180, width, height)); assertEquals(570, (int) rot180.getX()); assertEquals(950, (int) rot180.getY()); assertEquals(Surface.ROTATION_180, rot180.getSurfaceRotation()); MotionEvent rot270 = MotionEvent.obtain(event); rot270.transform(MotionEvent.createRotateMatrix(/* 270 deg */3, 1000, 600)); rot270.transform(MotionEvent.createRotateMatrix(Surface.ROTATION_270, height, width)); assertEquals(950, (int) rot270.getX()); assertEquals(30, (int) rot270.getY()); assertEquals(Surface.ROTATION_270, rot270.getSurfaceRotation()); MotionEvent compoundRot = MotionEvent.obtain(event); compoundRot.transform(MotionEvent.createRotateMatrix(Surface.ROTATION_90, height, width)); compoundRot.transform(MotionEvent.createRotateMatrix(Surface.ROTATION_180, height, width)); assertEquals(950, (int) compoundRot.getX()); assertEquals(30, (int) compoundRot.getY()); assertEquals(Surface.ROTATION_270, compoundRot.getSurfaceRotation()); MotionEvent rotInvalid = MotionEvent.obtain(event); Matrix mat = new Matrix(); mat.setValues(new float[]{1, 2, 3, -4, -5, -6, 0, 0, 1}); rotInvalid.transform(mat); assertEquals(-1, rotInvalid.getSurfaceRotation()); } } Loading
core/java/android/view/MotionEvent.java +34 −9 Original line number Diff line number Diff line Loading @@ -1663,6 +1663,9 @@ public final class MotionEvent extends InputEvent implements Parcelable { @CriticalNative private static native void nativeScale(long nativePtr, float scale); @CriticalNative private static native int nativeGetSurfaceRotation(long nativePtr); private MotionEvent() { } Loading Loading @@ -3805,17 +3808,39 @@ public final class MotionEvent extends InputEvent implements Parcelable { } /** * Gets a rotation matrix that (when applied to a motionevent) will rotate that motion event * such that the result coordinates end up in the same physical location on a display whose * Gets the rotation value of the transform for this MotionEvent. * * This MotionEvent's rotation can be changed by passing a rotation matrix to * {@link #transform(Matrix)} to change the coordinate space of this event. * * @return the rotation value, or -1 if unknown or invalid. * @see Surface.Rotation * @see #createRotateMatrix(int, int, int) * * @hide */ public @Surface.Rotation int getSurfaceRotation() { return nativeGetSurfaceRotation(mNativePtr); } /** * Gets a rotation matrix that (when applied to a MotionEvent) will rotate that motion event * such that the result coordinates end up in the same physical location on a frame whose * coordinates are rotated by `rotation`. * * For example, rotating 0,0 by 90 degrees will move a point from the physical top-left to * the bottom-left of the 90-degree-rotated display. * For example, rotating (0,0) by 90 degrees will move a point from the physical top-left to * the bottom-left of the 90-degree-rotated frame. * * @param rotation the surface rotation of the output matrix * @param rotatedFrameWidth the width of the rotated frame * @param rotatedFrameHeight the height of the rotated frame * * @see #transform(Matrix) * @see #getSurfaceRotation() * @hide */ public static Matrix createRotateMatrix( @Surface.Rotation int rotation, int displayW, int displayH) { @Surface.Rotation int rotation, int rotatedFrameWidth, int rotatedFrameHeight) { if (rotation == Surface.ROTATION_0) { return new Matrix(Matrix.IDENTITY_MATRIX); } Loading @@ -3823,14 +3848,14 @@ public final class MotionEvent extends InputEvent implements Parcelable { float[] values = null; if (rotation == Surface.ROTATION_90) { values = new float[]{0, 1, 0, -1, 0, displayH, -1, 0, rotatedFrameHeight, 0, 0, 1}; } else if (rotation == Surface.ROTATION_180) { values = new float[]{-1, 0, displayW, 0, -1, displayH, values = new float[]{-1, 0, rotatedFrameWidth, 0, -1, rotatedFrameHeight, 0, 0, 1}; } else if (rotation == Surface.ROTATION_270) { values = new float[]{0, -1, displayW, values = new float[]{0, -1, rotatedFrameWidth, 1, 0, 0, 0, 0, 1}; } Loading
core/jni/android_view_MotionEvent.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -769,6 +769,11 @@ static void android_view_MotionEvent_nativeScale(jlong nativePtr, jfloat scale) event->scale(scale); } static jint android_view_MotionEvent_nativeGetSurfaceRotation(jlong nativePtr) { MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); return jint(event->getSurfaceRotation()); } // ---------------------------------------------------------------------------- static const JNINativeMethod gMotionEventMethods[] = { Loading Loading @@ -845,6 +850,8 @@ static const JNINativeMethod gMotionEventMethods[] = { {"nativeFindPointerIndex", "(JI)I", (void*)android_view_MotionEvent_nativeFindPointerIndex}, {"nativeGetHistorySize", "(J)I", (void*)android_view_MotionEvent_nativeGetHistorySize}, {"nativeScale", "(JF)V", (void*)android_view_MotionEvent_nativeScale}, {"nativeGetSurfaceRotation", "(J)I", (void*)android_view_MotionEvent_nativeGetSurfaceRotation}, }; int register_android_view_MotionEvent(JNIEnv* env) { Loading
core/tests/coretests/src/android/view/MotionEventTest.java +28 −6 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import android.graphics.Matrix; import android.platform.test.annotations.Presubmit; import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerProperties; Loading Loading @@ -174,22 +175,43 @@ public class MotionEventTest { @Test public void testEventRotation() { // The un-rotated frame size. final int width = 600; final int height = 1000; final MotionEvent event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */, ACTION_DOWN, 30 /* x */, 50 /* y */, 0 /* metaState */); event.setSource(InputDevice.SOURCE_TOUCHSCREEN); assertEquals(Surface.ROTATION_0, event.getSurfaceRotation()); MotionEvent rot90 = MotionEvent.obtain(event); rot90.transform(MotionEvent.createRotateMatrix(/* 90 deg */1, 1000, 600)); rot90.transform(MotionEvent.createRotateMatrix(Surface.ROTATION_90, height, width)); assertEquals(50, (int) rot90.getX()); assertEquals(570, (int) rot90.getY()); assertEquals(Surface.ROTATION_90, rot90.getSurfaceRotation()); MotionEvent rot180 = MotionEvent.obtain(event); rot180.transform(MotionEvent.createRotateMatrix(/* 180 deg */2, 1000, 600)); assertEquals(970, (int) rot180.getX()); assertEquals(550, (int) rot180.getY()); rot180.transform(MotionEvent.createRotateMatrix(Surface.ROTATION_180, width, height)); assertEquals(570, (int) rot180.getX()); assertEquals(950, (int) rot180.getY()); assertEquals(Surface.ROTATION_180, rot180.getSurfaceRotation()); MotionEvent rot270 = MotionEvent.obtain(event); rot270.transform(MotionEvent.createRotateMatrix(/* 270 deg */3, 1000, 600)); rot270.transform(MotionEvent.createRotateMatrix(Surface.ROTATION_270, height, width)); assertEquals(950, (int) rot270.getX()); assertEquals(30, (int) rot270.getY()); assertEquals(Surface.ROTATION_270, rot270.getSurfaceRotation()); MotionEvent compoundRot = MotionEvent.obtain(event); compoundRot.transform(MotionEvent.createRotateMatrix(Surface.ROTATION_90, height, width)); compoundRot.transform(MotionEvent.createRotateMatrix(Surface.ROTATION_180, height, width)); assertEquals(950, (int) compoundRot.getX()); assertEquals(30, (int) compoundRot.getY()); assertEquals(Surface.ROTATION_270, compoundRot.getSurfaceRotation()); MotionEvent rotInvalid = MotionEvent.obtain(event); Matrix mat = new Matrix(); mat.setValues(new float[]{1, 2, 3, -4, -5, -6, 0, 0, 1}); rotInvalid.transform(mat); assertEquals(-1, rotInvalid.getSurfaceRotation()); } }