Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix timestamp of touch events should use system startup time #30422

Merged
merged 16 commits into from Mar 13, 2022

Conversation

wangying3426
Copy link
Contributor

@wangying3426 wangying3426 commented Dec 20, 2021

Fixed flutter/flutter#95570

as binding.dart shown, when the frameTime is equal to currentSystemFrameTimeStamp, "[[NSProcessInfo processInfo] systemUptime]" should be used to replace "[[NSDate date] timeIntervalSince1970]".

Otherwise, the time_stamp of fake event will always larger than endTime as resampler.dart shown, and the fake event will be invalid, then the touch down event will never be released.

See UITouch timestamp for more information.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on
    writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard flutter-dashboard bot changed the base branch from master to main December 20, 2021 15:37
@flutter-dashboard
Copy link

This pull request was opened against a branch other than master. Since Flutter pull requests should not normally be opened against branches other than master, I have changed the base to master. If this was intended, you may modify the base back to master. See the Release Process for information about how other branches get updated.

Reviewers: Use caution before merging pull requests to branches other than master, unless this is an intentional hotfix/cherrypick.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

1 similar comment
@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@wangying3426
Copy link
Contributor Author

wangying3426 commented Dec 20, 2021

It seems should be covered by existing tests? cc @Hixie for review, thanks.

@wangying3426 wangying3426 changed the title Fix abnormal touch behavior on iOS platform Fix timestamp of touch events should use system startup time Dec 21, 2021
@Hixie
Copy link
Contributor

Hixie commented Dec 22, 2021

If it's covered by existing tests, what existing test failed before that this is fixing?

@wangying3426
Copy link
Contributor Author

If it's covered by existing tests, what existing test failed before that this is fixing?

I mean it’s a bugfix clearly and seems hard to write tests, maybe it's ok to pass the existing tests only? Could you have better suggestions?

@Hixie
Copy link
Contributor

Hixie commented Dec 22, 2021

Ah, I see. It being hard to write tests isn't a reason to not write tests. :-) Usually the trick is to find a way to refactor the code to be easier to test. For example, can we make it possible to inject the pointer events before this code, and see how it looks once it gets to the Dart side?

cc @gaaclarke who may have opinions, looks like they've looked at this code before. @dkwingsmt and @gspencergoog may also have opinions?

@dkwingsmt
Copy link
Contributor

@wangying3426 The reason to enforce tests for changes is to prevent future changes to accidentally revert your fix. Just like how you feel safe not breaking any existing tests, future contributors might think they are safe for not breaking any tests, while actually breaking yours because you didn't write any.

Copy link
Contributor

@dkwingsmt dkwingsmt left a comment

Choose a reason for hiding this comment

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

Although I'm not familiar with this part, I wonder:

  • If the entire purpose is to make the timestamp lower, can we just use 0, or use "the time of the most recent real event"?
  • Should we also fix the same timestamp scheme in flushOngoingTouches?

As for tests, is it possible to simulate normal events, then the fake events, and test if the fake events have a lower time than the normal events (instead of testing their absolute values)?

@wangying3426
Copy link
Contributor Author

wangying3426 commented Dec 22, 2021

Although I'm not familiar with this part, I wonder:

  • If the entire purpose is to make the timestamp lower, can we just use 0, or use "the time of the most recent real event"?
  • Should we also fix the same timestamp scheme in flushOngoingTouches?

As for tests, is it possible to simulate normal events, then the fake events, and test if the fake events have a lower time than the normal events (instead of testing their absolute values)?

  • If the entire purpose is to make the timestamp lower, can we just use 0, or use "the time of the most recent real event"?
    • Indeed, the purpose of using systemUptime is to fake "the time of the most recent real event", all real events will use systemUptime as UITouch. But 0 or [[NSDate date] timeIntervalSince1970] does not conform to "the most recent real event", and will lead to abnormal behavior sometimes.
  • Should we also fix the same timestamp scheme in flushOngoingTouches?
    • Yes, i have also fixed it in flushOngoingTouches.

Besides,I find that the stable channel also uses systemUptime in generatePointerDataForMouse.

@wangying3426
Copy link
Contributor Author

wangying3426 commented Dec 22, 2021

flushOngoingTouches code was submitted by xster, also cc @xster for review? thanks.

@chinmaygarde
Copy link
Member

The implication here is that an issue is caused by comparing the scheduler timebase with the touch timebase. I can totally believe such issues to occur is code is assuming identical timebases from disparate subsystems. This guarantee was never present however and this patch seems is trying to match timebases. I agree with the insistence on the test. The fix is not to make this assumption on all subsystems using identical timebases. As written, I am not sure this fixes the issue on all platform versions.

@wangying3426 wangying3426 reopened this Jan 7, 2022
@wangying3426
Copy link
Contributor Author

wangying3426 commented Jan 18, 2022

Hi,@chinmaygarde @dkwingsmt , I searched all time_stamp fields on iOS, found that except for these two events and some tests, all the other time_stamp depends on systemUptime, as dispatchTouches and generatePointerDataForMouse shown, maybe we just need to ensure them using identical timebases? And could you have any other suggestions for how to write those test cases?

@wangying3426
Copy link
Contributor Author

wangying3426 commented Jan 25, 2022

hello, @Hixie @chinmaygarde @dkwingsmt To further confirm the problem, some additional informations were added, Could you please review whether these informations are sufficient?

  1. What problems will inconsistent ​timebases cause?
    If there are on going events when FlutterViewController disappear, native will send fake cancel events to flush the on going events. When resamplingEnabled is set to true, a periodic timer will started until the fake event's timestamp is smaller than sampling time. While in the original code the fake event's timestamp is so much bigger than sampling time (one depends on systemUpTime, while another timeIntervalSince1970), the timer will looping execution for a very very long time.

  2. Added an associated PR: Fix timer keeps active when resampling disabled in some cases flutter#97197.

  3. Here is a code sample that can reproduce the problem. Follow the steps below:

  • Run the demo on iOS real device.
  • One finger holds down the flutter list,at the same time another finger clicks the go to native button to push a new viewController. At this moment, flushOngoingTouches will be executed and a native fake event will be sent to flush the ongoing down event.
  • Then, we'll find that ScrollUpdateNotification will be sent continuously even though the FlutterViewController is in the paused state, as the console shown:
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
flutter: AppLifecycleState.paused scrolling.....
......

I also try to verify the timestamp of UITouch on scenario_app, but apple developer documentation has explain it clearly and we can also debug source code to watch this value.

@chinmaygarde
Copy link
Member

cc @dreveman I see you as the author of the resampler. I think I understand the issue @wangying3426 is running into but cannot determine if this is the right fix.

@wangying3426
Copy link
Contributor Author

wangying3426 commented Mar 2, 2022

cc @dreveman I see you as the author of the resampler. I think I understand the issue @wangying3426 is running into but cannot determine if this is the right fix.

It's been a while, @dreveman Could you review this PR, please?

@dreveman
Copy link
Contributor

dreveman commented Mar 8, 2022

I'm not familiar with ios code changed in this PR but the resampler code rely on event timestamps with the same clock as frame presentation timestamps. If this is the correct way to accomplish that on ios and it's not breaking some other assumptions then it's likely the correct fix.

@dkwingsmt
Copy link
Contributor

Fine...

@wangying3426 Do you think you can write a test, either in the way I described or any other proper ways?

@wangying3426
Copy link
Contributor Author

wangying3426 commented Mar 9, 2022

Fine...

@wangying3426 Do you think you can write a test, either in the way I described or any other proper ways?

ok. @dkwingsmt @christopherfujino could we use this demo to verify whether it is the correct change? As mentioned earlier, if not fix, ScrollUpdateNotification will be sent continuously even though the FlutterViewController is in the paused state, while the behavior is correct if fixed. Maybe we can also write many code to mock a scene like the demo, and included it in https://github.com/flutter/engine/tree/main/testing/scenario_app or others, but it seems overly complicated, we don't need to constantly test this fix.

If just validated the behavior of this change, do you think
https://github.com/wangying3426/engine/pull/1/files is a right way to meet the test requirements? I can merge it if you think it's ok.

I personally feel that this issue has been discussed quite clearly, and adding explanation comments maybe a proper ways.

@christopherfujino
Copy link
Member

If just validated the behavior of this change, do you think https://github.com/wangying3426/engine/pull/1/files is a right way to meet the test requirements? I can merge it if you think it's ok.

This looks reasonable

Copy link
Contributor

@dkwingsmt dkwingsmt left a comment

Choose a reason for hiding this comment

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

LGTM except for that one change.

@dkwingsmt
Copy link
Contributor

@gaaclarke @chinmaygarde Can you take a look and give a second review?

…erTest.mm

Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
…erTest.mm

Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
Copy link
Member

@ColdPaleLight ColdPaleLight left a comment

Choose a reason for hiding this comment

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

LGTM with nit

@ColdPaleLight ColdPaleLight added waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land. and removed needs tests labels Mar 13, 2022
@fluttergithubbot
Copy link
Contributor

This pull request is not suitable for automatic merging in its current state.

  • The status or check suite Mac clang-tidy has failed. Please fix the issues identified (or deflake) before re-applying this label.

@fluttergithubbot fluttergithubbot removed the waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land. label Mar 13, 2022
@dkwingsmt dkwingsmt merged commit 56187fa into flutter:main Mar 13, 2022
zanderso pushed a commit to flutter/flutter that referenced this pull request Mar 14, 2022
* ba6f4f5 Roll Skia from c88fff00c8fd to 02ea811ce869 (4 revisions) (flutter/engine#31955)

* 1a8033c Revert "Add a message when a key response takes too long. (#31945)" (flutter/engine#31962)

* ebcd86f Make sure the secondary vsync callback is called after the vsync callback (flutter/engine#31513)

* 2c94cc5 Generate a11y events for widgets that use kFlutterSemanticsFlagIsToggled (flutter/engine#31582)

* e21a58d [macOS, Keyboard] Refactor: Clean up keyboard initialization, connection, and unit test framework (flutter/engine#31940)

* 27e62d0 Set a11y roles for checks, toggles and sliders. (flutter/engine#31600)

* 5e760f6 Fix signals adding/removing a11y nodes in Linux. (flutter/engine#31601)

* 749dc3a Changed the default a11y node role from ATK_ROLE_FRAME to ATK_ROLE_PANEL (flutter/engine#31602)

* da7bae6 Animator stopped notifying delegate to render when pipeline is not empty (flutter/engine#31727)

* 77dd8af Roll Fuchsia Mac SDK from y2eJ9z95V... to j7jyFiU9e... (flutter/engine#31960)

* 3f803b2 Roll Skia from 02ea811ce869 to b141e485d248 (5 revisions) (flutter/engine#31961)

* 187a277 Roll Fuchsia Linux SDK from -9uFZIRSL... to k8Vq-HEG-... (flutter/engine#31971)

* 43975b2 Roll Skia from b141e485d248 to 1df655a42746 (13 revisions) (flutter/engine#31975)

* ab12f81 Roll Fuchsia Mac SDK from j7jyFiU9e... to g8opaxAq7... (flutter/engine#31978)

* 93b792f Roll Skia from 1df655a42746 to 38b9591b5a04 (1 revision) (flutter/engine#31979)

* d6964c0 Update jazzy to 0.14.1. (flutter/engine#31970)

* 31def4e Re-enable dart runner AOT builds (flutter/engine#31844)

* 887a193 Roll Fuchsia Linux SDK from k8Vq-HEG-... to mDjjSq8Im... (flutter/engine#31980)

* afd9ce1 Roll Fuchsia Mac SDK from g8opaxAq7... to f8IibBq3a... (flutter/engine#31983)

* f7d8314 Roll Fuchsia Linux SDK from mDjjSq8Im... to BEc_F0_Fp... (flutter/engine#31986)

* 503c02c Roll Fuchsia Mac SDK from f8IibBq3a... to oyZzinh6U... (flutter/engine#31987)

* caa3f3d Roll Fuchsia Linux SDK from BEc_F0_Fp... to obtypxiCA... (flutter/engine#31988)

* 4643016 Roll Dart SDK from 4fbe27c0f148 to 3e76a897013f (5 revisions) (flutter/engine#31989)

* 06d3d06 Roll Dart SDK from 3e76a897013f to 55b9ec4e382a (5 revisions) (flutter/engine#31991)

* cdf862b Roll Skia from 38b9591b5a04 to 6d19271fb148 (2 revisions) (flutter/engine#31992)

* bbebccd Roll Fuchsia Mac SDK from oyZzinh6U... to rmQ9yYUaF... (flutter/engine#31993)

* 56187fa Fix timestamp of touch events should use system startup time (flutter/engine#30422)

* 1dab008 Roll Fuchsia Linux SDK from obtypxiCA... to xYtoLAOvY... (flutter/engine#31995)

* fccde49 Add systemFontFamily to flutter/settings channel (flutter/engine#22981)

* 2a8c4f4 Roll Fuchsia Mac SDK from rmQ9yYUaF... to 84kG1vmHe... (flutter/engine#31996)

* e6cf464 Roll Skia from 6d19271fb148 to 7a61e5d65399 (1 revision) (flutter/engine#31997)

* 1cc349e Roll Fuchsia Linux SDK from xYtoLAOvY... to P8RdLi_Y_... (flutter/engine#31999)

* 25acd77 Roll Skia from 7a61e5d65399 to 02527b7182ea (1 revision) (flutter/engine#32000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
8 participants