Skip to content

Conversation

@dnfield
Copy link
Contributor

@dnfield dnfield commented Dec 17, 2019

Description

The removed line prevents us from mutating the tracking variable too early (it gets mutated by a later function anyway, but mutating it this early means we don't end up notifying the engine side of changes). This wasn't a problem before because the engine stayed running when the app was backgrounded, which meant the state was never really lost. Now that the engine detaches, we lose the state and need to have it to send it up again.

This results in #47137.

I also found that some tests were mutating global state, so I updated those, and I updated the tester harness to reset some global state between tests to make it more useful (this is now asserted by those tests). I also noticed that isRegistered was not trustworthy because of this global state it's connected to, so I tried to make it work better.

Related Issues

fixes #47137

Tests

I added the following tests:

Assert the expected textInput method call is made (setEditingState) after mutating the text.

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Did any tests fail when you ran them? Please read Handling breaking changes.

@fluttergithubbot fluttergithubbot added a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels. labels Dec 17, 2019
@dnfield
Copy link
Contributor Author

dnfield commented Dec 17, 2019

/cc @dannyvalentesonos

_obscureLatestCharIndex = _value.selection.baseOffset;
}
}
_lastKnownRemoteTextEditingValue = value;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the key piece here - we update this value in the call path of _formatAndSetValue anyway, and if we update it here, a later check that compares the value being passed with _lastKnownRemoteTextEditingValue always returns true.

This is just too early to set the value -we haven't actually notified the remote side yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM

'TextInput.setEditingState',
'TextInput.setEditingState',
'TextInput.show',
'TextInput.setEditingState',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is the key part of this test - without the change, we don't get the last setEditingState, which contains the value ....

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/foundation.dart';
import 'package:pedantic/pedantic.dart';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonahwilliams is this ok? It's for unawaited.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would introduce a new (direct) dependency on package:pedantic. I don't think we want that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this, but FWIW it looks like we directly depend on it elsewhere (although our pubspec doesn't indicate that).

@dnfield dnfield added the a: text input Entering text in a text field or keyboard related problems label Dec 17, 2019
Comment on lines 66 to 78
// Someone could have unregistered us by calling
// `SystemChannels.textInput.setMockMethodCallHandler` in the test. Actually
// check if we're registered by calling the method, which should work
// immediately if we are registered since that method does no real async work.
bool get isRegistered {
final int oldLogLength = log.length;
unawaited(SystemChannels.textInput.invokeMethod<void>('__isRegistered'));
if (log.length == oldLogLength) {
return false;
}
log.removeLast();
return true;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can move this to a separate PR if that works better - it's not needed for this issue.

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/foundation.dart';
import 'package:pedantic/pedantic.dart';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would introduce a new (direct) dependency on package:pedantic. I don't think we want that.

// immediately if we are registered since that method does no real async work.
bool get isRegistered {
final int oldLogLength = log.length;
unawaited(SystemChannels.textInput.invokeMethod<void>('__isRegistered'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may have unintended side effects if somebody else is currently registered and receives this, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Yes. I'm going to back this change out, don't need it for this PR, - will file an issue about it.

_obscureLatestCharIndex = _value.selection.baseOffset;
}
}
_lastKnownRemoteTextEditingValue = value;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM

return binding.runTest(
() async {
debugResetSemanticsIdCounter();
tester.testTextInput.register();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there maybe be a convenience method and tester (or testTextInput) to reset everything that does both of this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is the right place to reset these things, it feels odd here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried doing it before the binding.runTest and that didn't work. FWIW, this is where we reset the semantics ID counter as well so...

I'll move these to a convenience method.

Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dnfield
Copy link
Contributor Author

dnfield commented Dec 17, 2019

Fixing the test API is breaking one other test, which, IMO is buggy.

I'm going to spit out the package:flutter_test changes into a separate PR so we can do a proper breaking change/migration guide for it (and not have to roll this back if it breaks something internally).

@dnfield
Copy link
Contributor Author

dnfield commented Dec 17, 2019

No, it's my actual code change in the framework causing the test breakage. Investigating why, but it looks like this may be a breaking change.

@dnfield dnfield requested a review from goderbauer December 17, 2019 01:58
@dnfield
Copy link
Contributor Author

dnfield commented Dec 17, 2019

This is breaking whether or not I fix the issue in the tester.

If I fix the tester issue, it's breaking because the existing test relied on dirty state from the previous test.

If I avoid fixing the tester issue, it's still breaking because the existing test now gets different dirty state from the previous test.

@dnfield
Copy link
Contributor Author

dnfield commented Dec 17, 2019

Created flutter/website#3430 for migration.

@fluttergithubbot fluttergithubbot added the f: material design flutter/packages/flutter/material repository. label Dec 17, 2019
@dnfield
Copy link
Contributor Author

dnfield commented Dec 17, 2019

Migration guide has landed. Going ot land this on green.

@dnfield dnfield merged commit d4b49ce into flutter:master Dec 17, 2019
@dnfield dnfield deleted the setEditingState branch December 17, 2019 22:03
chingjun added a commit that referenced this pull request Dec 19, 2019
chingjun added a commit that referenced this pull request Dec 19, 2019
dnfield added a commit to dnfield/flutter that referenced this pull request Dec 19, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

a: tests "flutter test", flutter_test, or one of our tests a: text input Entering text in a text field or keyboard related problems c: API break Backwards-incompatible API changes f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Add2App] The typed characters in a TextField are lost when backgrounding the app with focus on the TextField on Android

4 participants