Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1db6aa54 authored by Evan Rosky's avatar Evan Rosky
Browse files

Don't rotate inputflinger's display

This "undoes" the rotation in incoming displayviewports
so that inputflinger always works in the orientation the display
grew-up in

It also modifies existing gesture-monitors to deal with unrotated
coordinates

This is behind a flag:
   adb shell setprop persist.debug.per_window_input_rotation 1

Bug: 179274888
Test: phone should work like normal
      atest MotionEventTest (coretests)
Change-Id: Iaa7ff7d62e9f756af2c9c622ec508c5e538ec8bd
parent bd771b8f
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -3768,6 +3768,41 @@ public final class MotionEvent extends InputEvent implements Parcelable {
        return (getButtonState() & button) == button;
    }

    /**
     * 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
     * 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.
     *
     * @hide
     */
    public static Matrix createRotateMatrix(
            @Surface.Rotation int rotation, int displayW, int displayH) {
        if (rotation == Surface.ROTATION_0) {
            return new Matrix(Matrix.IDENTITY_MATRIX);
        }
        // values is row-major
        float[] values = null;
        if (rotation == Surface.ROTATION_90) {
            values = new float[]{0, 1, 0,
                    -1, 0, displayH,
                    0, 0, 1};
        } else if (rotation == Surface.ROTATION_180) {
            values = new float[]{-1, 0, displayW,
                    0, -1, displayH,
                    0, 0, 1};
        } else if (rotation == Surface.ROTATION_270) {
            values = new float[]{0, -1, displayW,
                    1, 0, 0,
                    0, 0, 1};
        }
        Matrix toOrient = new Matrix();
        toOrient.setValues(values);
        return toOrient;
    }

    public static final @android.annotation.NonNull Parcelable.Creator<MotionEvent> CREATOR
            = new Parcelable.Creator<MotionEvent>() {
        public MotionEvent createFromParcel(Parcel in) {
+24 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.Surface;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
@@ -59,6 +60,9 @@ public class PointerLocationView extends View implements InputDeviceListener,
     */
    private static final String GESTURE_EXCLUSION_PROP = "debug.pointerlocation.showexclusion";

    private static final boolean ENABLE_PER_WINDOW_INPUT_ROTATION =
            SystemProperties.getBoolean("persist.debug.per_window_input_rotation", false);

    public static class PointerState {
        // Trace of previous points.
        private float[] mTraceX = new float[32];
@@ -352,6 +356,21 @@ public class PointerLocationView extends View implements InputDeviceListener,
                    .toString(), 1 + itemW * 6, base, mTextPaint);
        }

        int saveId = canvas.save();
        if (ENABLE_PER_WINDOW_INPUT_ROTATION) {
            // Rotate negative (since we're rotating the drawing canvas vs the output).
            canvas.rotate(-90.0f * mContext.getDisplay().getRotation());
            switch (mContext.getDisplay().getRotation()) {
                case Surface.ROTATION_90:
                    canvas.translate(-canvas.getHeight(), 0);
                    break;
                case Surface.ROTATION_180:
                    canvas.translate(-canvas.getWidth(), -canvas.getHeight());
                    break;
                case Surface.ROTATION_270:
                    canvas.translate(0, -canvas.getWidth());
            }
        }
        // Pointer trace.
        for (int p = 0; p < NP; p++) {
            final PointerState ps = mPointers.get(p);
@@ -399,7 +418,10 @@ public class PointerLocationView extends View implements InputDeviceListener,
            if (mCurDown && ps.mCurDown) {
                // Draw crosshairs.
                canvas.drawLine(0, ps.mCoords.y, getWidth(), ps.mCoords.y, mTargetPaint);
                canvas.drawLine(ps.mCoords.x, 0, ps.mCoords.x, getHeight(), mTargetPaint);
                // Extend crosshairs to cover screen regardless of rotation (ie. since the rotated
                // canvas can "expose" content past 0 and up-to the largest screen dimension).
                canvas.drawLine(ps.mCoords.x, -getHeight(), ps.mCoords.x,
                        Math.max(getHeight(), getWidth()), mTargetPaint);

                // Draw current point.
                int pressureLevel = (int)(ps.mCoords.pressure * 255);
@@ -458,6 +480,7 @@ public class PointerLocationView extends View implements InputDeviceListener,
                }
            }
        }
        canvas.restoreToCount(saveId);
    }

    private void logMotionEvent(String type, MotionEvent event) {
+20 −0
Original line number Diff line number Diff line
@@ -169,4 +169,24 @@ public class MotionEventTest {
            assertEquals(0x3 << 30, ID_SOURCE_MASK & event.getId());
        }
    }

    @Test
    public void testEventRotation() {
        final MotionEvent event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */,
                    ACTION_DOWN, 30 /* x */, 50 /* y */, 0 /* metaState */);
        MotionEvent rot90 = MotionEvent.obtain(event);
        rot90.transform(MotionEvent.createRotateMatrix(/* 90 deg */1, 1000, 600));
        assertEquals(50, (int) rot90.getX());
        assertEquals(570, (int) rot90.getY());

        MotionEvent rot180 = MotionEvent.obtain(event);
        rot180.transform(MotionEvent.createRotateMatrix(/* 180 deg */2, 1000, 600));
        assertEquals(970, (int) rot180.getX());
        assertEquals(550, (int) rot180.getY());

        MotionEvent rot270 = MotionEvent.obtain(event);
        rot270.transform(MotionEvent.createRotateMatrix(/* 270 deg */3, 1000, 600));
        assertEquals(950, (int) rot270.getX());
        assertEquals(30, (int) rot270.getY());
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -16,13 +16,12 @@

package com.android.systemui.shared.system;

import android.os.Bundle;
import android.graphics.Matrix;
import android.os.Looper;
import android.view.BatchedInputEventReceiver;
import android.view.Choreographer;
import android.view.InputChannel;
import android.view.InputEvent;
import android.view.InputEventSender;
import android.view.MotionEvent;

/**
@@ -53,6 +52,12 @@ public class InputChannelCompat {
        return target.addBatch(src);
    }

    /** @see MotionEvent#createRotateMatrix */
    public static Matrix createRotationMatrix(
            /*@Surface.Rotation*/ int rotation, int displayW, int displayH) {
        return MotionEvent.createRotateMatrix(rotation, displayW, displayH);
    }

    /**
     * @see BatchedInputEventReceiver
     */
+16 −2
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Choreographer;
import android.view.Display;
import android.view.ISystemGestureExclusionListener;
import android.view.InputDevice;
import android.view.InputEvent;
@@ -96,6 +97,9 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
    static final boolean DEBUG_MISSING_GESTURE = true;
    static final String DEBUG_MISSING_GESTURE_TAG = "NoBackGesture";

    private static final boolean ENABLE_PER_WINDOW_INPUT_ROTATION =
            SystemProperties.getBoolean("persist.debug.per_window_input_rotation", false);

    private ISystemGestureExclusionListener mGestureExclusionListener =
            new ISystemGestureExclusionListener.Stub() {
                @Override
@@ -505,9 +509,19 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
    }

    private void onInputEvent(InputEvent ev) {
        if (ev instanceof MotionEvent) {
            onMotionEvent((MotionEvent) ev);
        }
        if (!(ev instanceof MotionEvent)) return;
        MotionEvent event = (MotionEvent) ev;
        if (ENABLE_PER_WINDOW_INPUT_ROTATION) {
            final Display display = mContext.getDisplay();
            int rotation = display.getRotation();
            if (rotation != Surface.ROTATION_0) {
                Point sz = new Point();
                display.getRealSize(sz);
                event = MotionEvent.obtain(event);
                event.transform(MotionEvent.createRotateMatrix(rotation, sz.x, sz.y));
            }
        }
        onMotionEvent(event);
    }

    private void updateMLModelState() {
Loading