MotionEvent: Differentiate directional support for AXIS_ORIENTATION
We have three cases for handling AXIS_ORIENTATION:
1. Orientation is not supported by the input device, so the value for
AXIS_ORIENTATION should always be 0, regardless of display rotation.
2. Orientation is supported, but a "direction" is not specified, like
for touchscreens and touchpads. The orientation must be in the range
[-pi/2, pi/2] for all display rotations.
3. Orientation is fully supported, and the value is in the range [-pi,
pi] for all display rotations.
It is insufficient to rely on whether or not the PointerCoords has the
bit for AXIS_ORIENTATION set to determine whether the event has a valid
orientation. This is because we always skip setting values of 0 for any
axis in PointerCoords to save space during serialization.
To support these three cases, we introduce two new MotionEvent private
flags. These are flags that are not exposed to Java and to the public
APIs.
Bug: 263310669
Test: atest TouchScreenTest libinput_tests inputflinger_tests
Change-Id: Iaa38afe35b00de74fbc5eefce25191bea52c2ea6
diff --git a/include/input/Input.h b/include/input/Input.h
index 3ca9c19..a96dae2 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -99,6 +99,18 @@
/* Motion event is inconsistent with previously sent motion events. */
AMOTION_EVENT_FLAG_TAINTED = android::os::IInputConstants::INPUT_EVENT_FLAG_TAINTED,
+
+ /** Private flag, not used in Java. */
+ AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION =
+ android::os::IInputConstants::MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION,
+
+ /** Private flag, not used in Java. */
+ AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = android::os::IInputConstants::
+ MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION,
+
+ /** Mask for all private flags that are not used in Java. */
+ AMOTION_EVENT_PRIVATE_FLAG_MASK = AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION |
+ AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION,
};
/**
@@ -209,8 +221,12 @@
* Transform an angle on the x-y plane. An angle of 0 radians corresponds to "north" or
* pointing upwards in the negative Y direction, a positive angle points towards the right, and a
* negative angle points towards the left.
+ *
+ * If the angle represents a direction that needs to be preserved, set isDirectional to true to get
+ * an output range of [-pi, pi]. If the angle's direction does not need to be preserved, set
+ * isDirectional to false to get an output range of [-pi/2, pi/2].
*/
-float transformAngle(const ui::Transform& transform, float angleRadians);
+float transformAngle(const ui::Transform& transform, float angleRadians, bool isDirectional);
/**
* The type of the InputEvent.
@@ -462,7 +478,7 @@
// axes, however the window scaling will not.
void scale(float globalScale, float windowXScale, float windowYScale);
- void transform(const ui::Transform& transform);
+ void transform(const ui::Transform& transform, int32_t motionEventFlags);
inline float getX() const {
return getAxisValue(AMOTION_EVENT_AXIS_X);
@@ -930,10 +946,10 @@
// relative mouse device (since SOURCE_RELATIVE_MOUSE is a non-pointer source). These methods
// are used to apply these transformations for different axes.
static vec2 calculateTransformedXY(uint32_t source, const ui::Transform&, const vec2& xy);
- static float calculateTransformedAxisValue(int32_t axis, uint32_t source, const ui::Transform&,
- const PointerCoords&);
- static PointerCoords calculateTransformedCoords(uint32_t source, const ui::Transform&,
- const PointerCoords&);
+ static float calculateTransformedAxisValue(int32_t axis, uint32_t source, int32_t flags,
+ const ui::Transform&, const PointerCoords&);
+ static PointerCoords calculateTransformedCoords(uint32_t source, int32_t flags,
+ const ui::Transform&, const PointerCoords&);
// The rounding precision for transformed motion events.
static constexpr float ROUNDING_PRECISION = 0.001f;