From 324fe201b0231fcc39fff8c99fee1b22425c4bc0 Mon Sep 17 00:00:00 2001 From: Matt Carroll Date: Mon, 19 Aug 2019 15:49:32 -0700 Subject: [PATCH] Add handling of 'TextInput.clearClient' message from platform to framework (#35054). (#35100) --- .../flutter/lib/src/services/text_input.dart | 18 +++++++-- .../test/services/text_input_test.dart | 39 +++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/packages/flutter/lib/src/services/text_input.dart b/packages/flutter/lib/src/services/text_input.dart index 0a95f75877e..0d5975aafdb 100644 --- a/packages/flutter/lib/src/services/text_input.dart +++ b/packages/flutter/lib/src/services/text_input.dart @@ -632,7 +632,7 @@ abstract class TextInputClient { /// See also: /// /// * [TextInput.attach] -class TextInputConnection { +class TextInputConnection with ChangeNotifier { TextInputConnection._(this._client) : assert(_client != null), _id = _nextId++; @@ -667,12 +667,19 @@ class TextInputConnection { void close() { if (attached) { SystemChannels.textInput.invokeMethod('TextInput.clearClient'); - _clientHandler - .._currentConnection = null - .._scheduleHide(); + _onConnectionClosed(); + _clientHandler._scheduleHide(); } assert(!attached); } + + /// Clear out the current text input connection. + /// + /// Call this method when the current text input connection has cleared. + void _onConnectionClosed() { + _clientHandler._currentConnection = null; + notifyListeners(); + } } TextInputAction _toTextInputAction(String action) { @@ -753,6 +760,9 @@ class _TextInputClientHandler { case 'TextInputClient.updateFloatingCursor': _currentConnection._client.updateFloatingCursor(_toTextPoint(_toTextCursorAction(args[1]), args[2])); break; + case 'TextInputClient.onConnectionClosed': + _currentConnection._onConnectionClosed(); + break; default: throw MissingPluginException(); } diff --git a/packages/flutter/test/services/text_input_test.dart b/packages/flutter/test/services/text_input_test.dart index ee9192c51cc..80651ed9dec 100644 --- a/packages/flutter/test/services/text_input_test.dart +++ b/packages/flutter/test/services/text_input_test.dart @@ -85,5 +85,44 @@ void main() { expect(signed.hashCode == signedDecimal.hashCode, false); expect(decimal.hashCode == signedDecimal.hashCode, false); }); + + test('The framework TextInputConnection closes when the platform loses its input connection', () async { + // Assemble a TextInputConnection so we can verify its change in state. + final TextInputClient client = NoOpTextInputClient(); + const TextInputConfiguration configuration = TextInputConfiguration(); + final TextInputConnection textInputConnection = TextInput.attach(client, configuration); + + // Verify that TextInputConnection think its attached to a client. This is + // an intermediate verification of expected state. + expect(textInputConnection.attached, true); + + // Pretend that the platform has lost its input connection. + final ByteData messageBytes = const JSONMessageCodec().encodeMessage( + { + 'args': [1], + 'method': 'TextInputClient.onConnectionClosed', + } + ); + defaultBinaryMessenger.handlePlatformMessage( + 'flutter/textinput', + messageBytes, + (ByteData _) {}, + ); + + // Verify that textInputConnection no longer think its attached to an input + // connection. This is the critical verification of this test. + expect(textInputConnection.attached, false); + }); }); } + +class NoOpTextInputClient extends TextInputClient { + @override + void performAction(TextInputAction action) {} + + @override + void updateEditingValue(TextEditingValue value) {} + + @override + void updateFloatingCursor(RawFloatingCursorPoint point) {} +} \ No newline at end of file