[CP] Fix a type casting error in text_input.dart (#109635) (#114806)

(cherry picked from commit 8caa14e6291667a972936ebc210380995e82f5df)

Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
Co-authored-by: Casey Hillers <chillers@google.com>
diff --git a/packages/flutter/lib/src/services/text_input.dart b/packages/flutter/lib/src/services/text_input.dart
index e19757d..a233a10 100644
--- a/packages/flutter/lib/src/services/text_input.dart
+++ b/packages/flutter/lib/src/services/text_input.dart
@@ -1510,7 +1510,7 @@
   assert(encoded['X'] != null, 'You must provide a value for the horizontal location of the floating cursor.');
   assert(encoded['Y'] != null, 'You must provide a value for the vertical location of the floating cursor.');
   final Offset offset = state == FloatingCursorDragState.Update
-    ? Offset(encoded['X'] as double, encoded['Y'] as double)
+    ? Offset((encoded['X'] as num).toDouble(), (encoded['Y'] as num).toDouble())
     : Offset.zero;
   return RawFloatingCursorPoint(offset: offset, state: state);
 }
diff --git a/packages/flutter/test/services/text_input_test.dart b/packages/flutter/test/services/text_input_test.dart
index 87c4204..e0e9932 100644
--- a/packages/flutter/test/services/text_input_test.dart
+++ b/packages/flutter/test/services/text_input_test.dart
@@ -241,6 +241,33 @@
       expect(record[0].exception.toString(), matches(RegExp(r'\brange.start >= 0 && range.start <= text.length\b')));
       expect(record[0].exception.toString(), matches(RegExp(r'\bRange start 2 is out of text of length 1\b')));
     });
+
+    test('FloatingCursor coordinates type-casting', () async {
+      // Regression test for https://github.com/flutter/flutter/issues/109632.
+      final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
+      FlutterError.onError = errors.add;
+
+      final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue(text: 'test3'));
+      const TextInputConfiguration configuration = TextInputConfiguration();
+      TextInput.attach(client, configuration);
+
+      final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
+        'method': 'TextInputClient.updateFloatingCursor',
+        'args': <dynamic>[
+          -1,
+          'FloatingCursorDragState.update',
+          <String, dynamic>{ 'X': 2, 'Y': 3 },
+        ],
+      });
+
+      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
+        'flutter/textinput',
+        messageBytes,
+        (ByteData? _) {},
+      );
+
+      expect(errors, isEmpty);
+    });
   });
 
   group('TextInputConfiguration', () {