Skip to content

Commit a832a72

Browse files
authored
Handle privatecommand messages that pass no data (#112590)
Fixes an error in some text editors.
1 parent 8815f60 commit a832a72

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

packages/flutter/lib/src/services/text_input.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -1877,7 +1877,9 @@ class TextInput {
18771877
final Map<String, dynamic> firstArg = args[1] as Map<String, dynamic>;
18781878
_currentConnection!._client.performPrivateCommand(
18791879
firstArg['action'] as String,
1880-
firstArg['data'] as Map<String, dynamic>,
1880+
firstArg['data'] == null
1881+
? <String, dynamic>{}
1882+
: firstArg['data'] as Map<String, dynamic>,
18811883
);
18821884
break;
18831885
case 'TextInputClient.updateFloatingCursor':

packages/flutter/test/services/text_input_test.dart

+29-1
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,32 @@ void main() {
562562
expect(client.latestMethodCall, 'performPrivateCommand');
563563
});
564564

565+
test('TextInputClient performPrivateCommand method is called with no data at all', () async {
566+
// Assemble a TextInputConnection so we can verify its change in state.
567+
final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
568+
const TextInputConfiguration configuration = TextInputConfiguration();
569+
TextInput.attach(client, configuration);
570+
571+
expect(client.latestMethodCall, isEmpty);
572+
573+
// Send performPrivateCommand message.
574+
final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
575+
'args': <dynamic>[
576+
1,
577+
jsonDecode('{"action": "actionCommand"}'), // No `data` parameter.
578+
],
579+
'method': 'TextInputClient.performPrivateCommand',
580+
});
581+
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
582+
'flutter/textinput',
583+
messageBytes,
584+
(ByteData? _) {},
585+
);
586+
587+
expect(client.latestMethodCall, 'performPrivateCommand');
588+
expect(client.latestPrivateCommandData, <String, dynamic>{});
589+
});
590+
565591
test('TextInputClient showAutocorrectionPromptRect method is called', () async {
566592
// Assemble a TextInputConnection so we can verify its change in state.
567593
final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
@@ -933,6 +959,7 @@ class FakeTextInputClient with TextInputClient {
933959

934960
String latestMethodCall = '';
935961
final List<String> performedSelectors = <String>[];
962+
late Map<String, dynamic>? latestPrivateCommandData;
936963

937964
@override
938965
TextEditingValue currentTextEditingValue;
@@ -946,8 +973,9 @@ class FakeTextInputClient with TextInputClient {
946973
}
947974

948975
@override
949-
void performPrivateCommand(String action, Map<String, dynamic> data) {
976+
void performPrivateCommand(String action, Map<String, dynamic>? data) {
950977
latestMethodCall = 'performPrivateCommand';
978+
latestPrivateCommandData = data;
951979
}
952980

953981
@override

0 commit comments

Comments
 (0)