Add a minimum physical threshold for freeform gesture on touchpad

Currently, TouchInputMapper uses the product of the size of the touchpad
and a ratio (currently 0.25) to determine a two finger gesture is a
freeform gesture or a swipe, that when the distance of two pointers is
greater than the calculated value, it is a freeform gesture, otherwise,
it is a swipe gesture. However, on a really small touch pad, such as
Sony Dualshock4's, due to the common size of human fingers, almost all
two finger gestures are decided to be freeform. Adding a minimun
physical value for the freeform gesture, 30 mm, can solve the problem.

Bug: 197146318
Test: manual test
Change-Id: Ia4ff521cb2f47b587fa55a5d753b90d023a648ef
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index f07a3e8..1b0c61c 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -42,6 +42,8 @@
 // data.
 static constexpr nsecs_t STYLUS_DATA_LATENCY = ms2ns(10);
 
+// Minimum width between two pointers to determine a gesture as freeform gesture in mm
+static const float MIN_FREEFORM_GESTURE_WIDTH_IN_MILLIMETER = 30;
 // --- Static Definitions ---
 
 template <typename T>
@@ -936,6 +938,11 @@
     // Raw width and height in the natural orientation.
     const int32_t rawWidth = mRawPointerAxes.getRawWidth();
     const int32_t rawHeight = mRawPointerAxes.getRawHeight();
+    const int32_t rawXResolution = mRawPointerAxes.x.resolution;
+    const int32_t rawYResolution = mRawPointerAxes.y.resolution;
+    // Calculate the mean resolution when both x and y resolution are set, otherwise set it to 0.
+    const float rawMeanResolution =
+            (rawXResolution > 0 && rawYResolution > 0) ? (rawXResolution + rawYResolution) / 2 : 0;
 
     const bool viewportChanged = mViewport != *newViewport;
     bool skipViewportUpdate = false;
@@ -1094,10 +1101,14 @@
                     mConfig.pointerGestureZoomSpeedRatio * displayDiagonal / rawDiagonal;
             mPointerYZoomScale = mPointerXZoomScale;
 
-            // Max width between pointers to detect a swipe gesture is more than some fraction
-            // of the diagonal axis of the touch pad.  Touches that are wider than this are
-            // translated into freeform gestures.
-            mPointerGestureMaxSwipeWidth = mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
+            // Calculate the min freeform gesture width. It will be 0 when the resolution of any
+            // axis is non positive value.
+            const float minFreeformGestureWidth =
+                    rawMeanResolution * MIN_FREEFORM_GESTURE_WIDTH_IN_MILLIMETER;
+
+            mPointerGestureMaxSwipeWidth =
+                    std::max(mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal,
+                             minFreeformGestureWidth);
 
             // Abort current pointer usages because the state has changed.
             const nsecs_t readTime = when; // synthetic event
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index 714ad3f..3042be6 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -527,7 +527,9 @@
     float mPointerXZoomScale;
     float mPointerYZoomScale;
 
-    // The maximum swipe width.
+    // The maximum swipe width between pointers to detect a swipe gesture
+    // in the number of pixels.Touches that are wider than this are translated
+    // into freeform gestures.
     float mPointerGestureMaxSwipeWidth;
 
     struct PointerDistanceHeapElement {