Touching the screen adds `0x01` to buttons (#30457)

* Add constants `kPrimaryButton`, `kTouchContact` and `kStylusContact`
* PointerDownEvent and PointerMoveEvent will always set the 0x01 bit on buttons
diff --git a/packages/flutter/lib/src/gestures/converter.dart b/packages/flutter/lib/src/gestures/converter.dart
index 8c0d209..5bb120e 100644
--- a/packages/flutter/lib/src/gestures/converter.dart
+++ b/packages/flutter/lib/src/gestures/converter.dart
@@ -207,7 +207,8 @@
               kind: kind,
               device: datum.device,
               position: position,
-              buttons: datum.buttons,
+              // TODO(tongmu): Move button patching to embedder, https://github.com/flutter/flutter/issues/30454
+              buttons: datum.buttons | kPrimaryButton,
               obscured: datum.obscured,
               pressure: datum.pressure,
               pressureMin: datum.pressureMin,
@@ -236,7 +237,8 @@
               device: datum.device,
               position: position,
               delta: state.deltaTo(position),
-              buttons: datum.buttons,
+              // TODO(tongmu): Move button patching to embedder, https://github.com/flutter/flutter/issues/30454
+              buttons: datum.buttons | kPrimaryButton,
               obscured: datum.obscured,
               pressure: datum.pressure,
               pressureMin: datum.pressureMin,
@@ -271,7 +273,8 @@
                 device: datum.device,
                 position: position,
                 delta: state.deltaTo(position),
-                buttons: datum.buttons,
+                // TODO(tongmu): Move button patching to embedder, https://github.com/flutter/flutter/issues/30454
+                buttons: datum.buttons | kPrimaryButton,
                 obscured: datum.obscured,
                 pressure: datum.pressure,
                 pressureMin: datum.pressureMin,
@@ -418,7 +421,8 @@
                   device: datum.device,
                   position: position,
                   delta: state.deltaTo(position),
-                  buttons: datum.buttons,
+                  // TODO(tongmu): Move button patching to embedder, https://github.com/flutter/flutter/issues/30454
+                  buttons: datum.buttons | kPrimaryButton,
                   obscured: datum.obscured,
                   pressure: datum.pressure,
                   pressureMin: datum.pressureMin,
diff --git a/packages/flutter/lib/src/gestures/events.dart b/packages/flutter/lib/src/gestures/events.dart
index dca70a9..d9b50f0 100644
--- a/packages/flutter/lib/src/gestures/events.dart
+++ b/packages/flutter/lib/src/gestures/events.dart
@@ -8,11 +8,21 @@
 
 export 'dart:ui' show Offset, PointerDeviceKind;
 
+/// The bit of [PointerEvent.buttons] that corresponds to a unified behavior of
+/// "basic operation".
+///
+/// It is equivalent to:
+///
+///  * [kTouchContact]: The pointer contacts the touch screen.
+///  * [kStylusContact]: The stylus contacts the screen.
+///  * [kPrimaryMouseButton]: The primary mouse button.
+const int kPrimaryButton = 0x01;
+
 /// The bit of [PointerEvent.buttons] that corresponds to the primary mouse button.
 ///
 /// The primary mouse button is typically the left button on the top of the
 /// mouse but can be reconfigured to be a different physical button.
-const int kPrimaryMouseButton = 0x01;
+const int kPrimaryMouseButton = kPrimaryButton;
 
 /// The bit of [PointerEvent.buttons] that corresponds to the secondary mouse button.
 ///
@@ -20,6 +30,10 @@
 /// mouse but can be reconfigured to be a different physical button.
 const int kSecondaryMouseButton = 0x02;
 
+/// The bit of [PointerEvent.buttons] that corresponds to when a stylus
+/// contacting the screen.
+const int kStylusContact = kPrimaryButton;
+
 /// The bit of [PointerEvent.buttons] that corresponds to the primary stylus button.
 ///
 /// The primary stylus button is typically the top of the stylus and near the
@@ -51,6 +65,10 @@
 /// be reconfigured to be a different physical button.
 const int kForwardMouseButton = 0x10;
 
+/// The bit of [PointerEvent.buttons] that corresponds to the pointer contacting
+/// a touch screen.
+const int kTouchContact = kPrimaryButton;
+
 /// The bit of [PointerEvent.buttons] that corresponds to the nth mouse button.
 ///
 /// The `number` argument can be at most 62.
diff --git a/packages/flutter/test/gestures/gesture_binding_test.dart b/packages/flutter/test/gestures/gesture_binding_test.dart
index f2924a6..bd30ac3 100644
--- a/packages/flutter/test/gestures/gesture_binding_test.dart
+++ b/packages/flutter/test/gestures/gesture_binding_test.dart
@@ -47,6 +47,7 @@
     ui.window.onPointerDataPacket(packet);
     expect(events.length, 2);
     expect(events[0].runtimeType, equals(PointerDownEvent));
+    expect(events[0].buttons, equals(1));
     expect(events[1].runtimeType, equals(PointerUpEvent));
   });
 
@@ -65,7 +66,9 @@
     ui.window.onPointerDataPacket(packet);
     expect(events.length, 3);
     expect(events[0].runtimeType, equals(PointerDownEvent));
+    expect(events[0].buttons, equals(1));
     expect(events[1].runtimeType, equals(PointerMoveEvent));
+    expect(events[1].buttons, equals(1));
     expect(events[2].runtimeType, equals(PointerUpEvent));
   });
 
@@ -119,7 +122,9 @@
     ui.window.onPointerDataPacket(packet);
     expect(events.length, 3);
     expect(events[0].runtimeType, equals(PointerDownEvent));
+    expect(events[0].buttons, equals(1));
     expect(events[1].runtimeType, equals(PointerMoveEvent));
+    expect(events[1].buttons, equals(1));
     expect(events[1].delta, equals(const Offset(9.0, 12.0)));
     expect(events[2].runtimeType, equals(PointerUpEvent));
   });
@@ -138,6 +143,7 @@
     ui.window.onPointerDataPacket(packet);
     expect(events.length, 2);
     expect(events[0].runtimeType, equals(PointerDownEvent));
+    expect(events[0].buttons, equals(1));
     expect(events[1].runtimeType, equals(PointerCancelEvent));
   });
 
@@ -159,6 +165,7 @@
     ui.window.onPointerDataPacket(packet);
     expect(events.length, 2);
     expect(events[0].runtimeType, equals(PointerDownEvent));
+    expect(events[0].buttons, equals(1));
     expect(events[1].runtimeType, equals(PointerCancelEvent));
   });
 
@@ -200,6 +207,7 @@
     expect(events[1].runtimeType, equals(PointerHoverEvent));
     expect(events[1].delta, equals(const Offset(5.0, 7.0)));
     expect(events[2].runtimeType, equals(PointerDownEvent));
+    expect(events[2].buttons, equals(1));
     expect(events[3].runtimeType, equals(PointerCancelEvent));
     expect(events[4].runtimeType, equals(PointerHoverEvent));
     expect(events[5].runtimeType, equals(PointerRemovedEvent));
@@ -246,7 +254,9 @@
     expect(events[2].runtimeType, equals(PointerScrollEvent));
     expect(events[3].runtimeType, equals(PointerHoverEvent));
     expect(events[4].runtimeType, equals(PointerDownEvent));
+    expect(events[4].buttons, equals(1));
     expect(events[5].runtimeType, equals(PointerMoveEvent));
+    expect(events[5].buttons, equals(1));
     expect(events[5].delta, equals(unexpectedOffset));
     expect(events[6].runtimeType, equals(PointerScrollEvent));
   });