From 0dc4972362b2981edff0d563c87c5fc577ad75d9 Mon Sep 17 00:00:00 2001 From: "wangying.666" Date: Mon, 20 Dec 2021 22:13:31 +0800 Subject: [PATCH 01/11] fix touch exception when route to a native page in add-to-app --- .../darwin/ios/framework/Source/FlutterViewController.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 1f727a17d28e2..f6eb40305da71 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -752,7 +752,7 @@ - (void)flushOngoingTouches { pointer_data.Clear(); // Use current time. - pointer_data.time_stamp = [[NSDate date] timeIntervalSince1970] * kMicrosecondsPerSecond; + pointer_data.time_stamp = CACurrentMediaTime() * kMicrosecondsPerSecond; pointer_data.change = flutter::PointerData::Change::kCancel; pointer_data.kind = flutter::PointerData::DeviceKind::kTouch; From 0823b9ce20dda56193fffeadc7e640c3df5a7657 Mon Sep 17 00:00:00 2001 From: "wangying.666" Date: Tue, 21 Dec 2021 14:42:05 +0800 Subject: [PATCH 02/11] fix time_stamp of touch events should depend on system startup time --- .../darwin/ios/framework/Source/FlutterViewController.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index f6eb40305da71..4c847a26d771d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -423,7 +423,7 @@ static void SendFakeTouchEvent(FlutterEngine* engine, pointer_data.physical_x = location.x * scale; pointer_data.physical_y = location.y * scale; pointer_data.kind = flutter::PointerData::DeviceKind::kTouch; - pointer_data.time_stamp = [[NSDate date] timeIntervalSince1970] * kMicrosecondsPerSecond; + pointer_data.time_stamp = [[NSProcessInfo processInfo] systemUptime] * kMicrosecondsPerSecond; auto packet = std::make_unique(/*count=*/1); pointer_data.change = change; packet->SetPointerData(0, pointer_data); @@ -752,7 +752,7 @@ - (void)flushOngoingTouches { pointer_data.Clear(); // Use current time. - pointer_data.time_stamp = CACurrentMediaTime() * kMicrosecondsPerSecond; + pointer_data.time_stamp = [[NSProcessInfo processInfo] systemUptime] * kMicrosecondsPerSecond; pointer_data.change = flutter::PointerData::Change::kCancel; pointer_data.kind = flutter::PointerData::DeviceKind::kTouch; From a0599ba64891fe77511aca0b2be359f19b77f057 Mon Sep 17 00:00:00 2001 From: "wangying.666" Date: Tue, 8 Mar 2022 20:39:55 +0800 Subject: [PATCH 03/11] Add comments with explanation --- .../darwin/ios/framework/Source/FlutterViewController.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index a95427cd8f8c3..6a9d6c4456398 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -423,6 +423,9 @@ static void SendFakeTouchEvent(FlutterEngine* engine, pointer_data.physical_x = location.x * scale; pointer_data.physical_y = location.y * scale; pointer_data.kind = flutter::PointerData::DeviceKind::kTouch; + // `UITouch.timestamp` is defined as seconds since system startup. Synthesized events can get this time + // with `NSProcessInfo.systemUptime`. See + // https://developer.apple.com/documentation/uikit/uitouch/1618144-timestamp?language=objc pointer_data.time_stamp = [[NSProcessInfo processInfo] systemUptime] * kMicrosecondsPerSecond; auto packet = std::make_unique(/*count=*/1); pointer_data.change = change; @@ -756,6 +759,9 @@ - (void)flushOngoingTouches { pointer_data.Clear(); // Use current time. + // `UITouch.timestamp` is defined as seconds since system startup. Synthesized events can get this time + // with `NSProcessInfo.systemUptime`. See + // https://developer.apple.com/documentation/uikit/uitouch/1618144-timestamp?language=objc pointer_data.time_stamp = [[NSProcessInfo processInfo] systemUptime] * kMicrosecondsPerSecond; pointer_data.change = flutter::PointerData::Change::kCancel; From a547ee2b909eb5aa19eaab92c4b84347da305698 Mon Sep 17 00:00:00 2001 From: "wangying.666" Date: Tue, 8 Mar 2022 20:43:05 +0800 Subject: [PATCH 04/11] fix ci format error --- .../darwin/ios/framework/Source/FlutterViewController.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 6a9d6c4456398..16233047a47f7 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -423,8 +423,8 @@ static void SendFakeTouchEvent(FlutterEngine* engine, pointer_data.physical_x = location.x * scale; pointer_data.physical_y = location.y * scale; pointer_data.kind = flutter::PointerData::DeviceKind::kTouch; - // `UITouch.timestamp` is defined as seconds since system startup. Synthesized events can get this time - // with `NSProcessInfo.systemUptime`. See + // `UITouch.timestamp` is defined as seconds since system startup. Synthesized events can get this + // time with `NSProcessInfo.systemUptime`. See // https://developer.apple.com/documentation/uikit/uitouch/1618144-timestamp?language=objc pointer_data.time_stamp = [[NSProcessInfo processInfo] systemUptime] * kMicrosecondsPerSecond; auto packet = std::make_unique(/*count=*/1); @@ -759,8 +759,8 @@ - (void)flushOngoingTouches { pointer_data.Clear(); // Use current time. - // `UITouch.timestamp` is defined as seconds since system startup. Synthesized events can get this time - // with `NSProcessInfo.systemUptime`. See + // `UITouch.timestamp` is defined as seconds since system startup. Synthesized events can get + // this time with `NSProcessInfo.systemUptime`. See // https://developer.apple.com/documentation/uikit/uitouch/1618144-timestamp?language=objc pointer_data.time_stamp = [[NSProcessInfo processInfo] systemUptime] * kMicrosecondsPerSecond; From d6ed6aa04c61fd23e934b8e9088e4b9d4115f727 Mon Sep 17 00:00:00 2001 From: "wangying.666" Date: Wed, 9 Mar 2022 23:43:14 +0800 Subject: [PATCH 05/11] fix time_stamp bug --- .../framework/Source/FlutterViewController.mm | 23 +++++++++++-------- .../Source/FlutterViewControllerTest.mm | 12 ++++++++++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 08f44786fb04e..42b704df854a8 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -414,16 +414,24 @@ - (void)loadView { _scrollView.reset(scrollView); } +- (flutter::PointerData)generatePointerDataForFake { + flutter::PointerData pointer_data; + pointer_data.Clear(); + pointer_data.kind = flutter::PointerData::DeviceKind::kTouch; + // `UITouch.timestamp` is defined as seconds since system startup. Synthesized events can get this + // time with `NSProcessInfo.systemUptime`. See + // https://developer.apple.com/documentation/uikit/uitouch/1618144-timestamp?language=objc + pointer_data.time_stamp = [[NSProcessInfo processInfo] systemUptime] * kMicrosecondsPerSecond; + return pointer_data; +} + static void SendFakeTouchEvent(FlutterEngine* engine, CGPoint location, flutter::PointerData::Change change) { const CGFloat scale = [UIScreen mainScreen].scale; - flutter::PointerData pointer_data; - pointer_data.Clear(); + flutter::PointerData pointer_data = [[engine viewController] generatePointerDataForFake]; pointer_data.physical_x = location.x * scale; pointer_data.physical_y = location.y * scale; - pointer_data.kind = flutter::PointerData::DeviceKind::kTouch; - pointer_data.time_stamp = [[NSDate date] timeIntervalSince1970] * kMicrosecondsPerSecond; auto packet = std::make_unique(/*count=*/1); pointer_data.change = change; packet->SetPointerData(0, pointer_data); @@ -752,14 +760,9 @@ - (void)flushOngoingTouches { // touches to the framework so nothing gets orphaned. for (NSNumber* device in _ongoingTouches.get()) { // Create fake PointerData to balance out each previously started one for the framework. - flutter::PointerData pointer_data; - pointer_data.Clear(); - - // Use current time. - pointer_data.time_stamp = [[NSDate date] timeIntervalSince1970] * kMicrosecondsPerSecond; + flutter::PointerData pointer_data = [self generatePointerDataForFake]; pointer_data.change = flutter::PointerData::Change::kCancel; - pointer_data.kind = flutter::PointerData::DeviceKind::kTouch; pointer_data.device = device.longLongValue; pointer_data.pointer_identifier = 0; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index a91101c36807b..a5a45b8418fdd 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -141,6 +141,7 @@ - (void)startKeyBoardAnimation:(NSTimeInterval)duration; - (void)ensureViewportMetricsIsCorrect; - (void)invalidateDisplayLink; - (void)addInternalPlugins; +- (flutter::PointerData)generatePointerDataForFake; @end @interface FlutterViewControllerTest : XCTestCase @@ -1055,4 +1056,15 @@ - (void)testMouseSupport API_AVAILABLE(ios(13.4)) { dispatchPointerDataPacket:std::make_unique()]; } +- (void)testFakeEventTimeStamp { + FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine + nibName:nil + bundle:nil]; + XCTAssertNotNil(vc); + + flutter::PointerData pointer_data = [vc generatePointerDataForFake]; + int64_t current_time = [[NSProcessInfo processInfo] systemUptime] * kMicrosecondsPerSecond; + XCTAssertTrue(current_time == pointer_data.time_stamp, + @"PointerData.time_stamp should be equal to NSProcessInfo.systemUptime"); +} @end From 34dd7dbed20363a4aec9e1bbb3c4532d85466b13 Mon Sep 17 00:00:00 2001 From: "wangying.666" Date: Thu, 10 Mar 2022 16:47:14 +0800 Subject: [PATCH 06/11] fix time_stamp compare exception --- .../darwin/ios/framework/Source/FlutterViewControllerTest.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index a5a45b8418fdd..98d8de6596b01 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -6,6 +6,7 @@ #import #include "flutter/fml/platform/darwin/message_loop_darwin.h" +#include "flutter/lib/ui/window/pointer_data.h" #import "flutter/lib/ui/window/viewport_metrics.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" @@ -1063,8 +1064,8 @@ - (void)testFakeEventTimeStamp { XCTAssertNotNil(vc); flutter::PointerData pointer_data = [vc generatePointerDataForFake]; - int64_t current_time = [[NSProcessInfo processInfo] systemUptime] * kMicrosecondsPerSecond; - XCTAssertTrue(current_time == pointer_data.time_stamp, + int64_t current_time = [[NSProcessInfo processInfo] systemUptime]; + XCTAssertTrue(current_time == pointer_data.time_stamp / 1000 / 1000, @"PointerData.time_stamp should be equal to NSProcessInfo.systemUptime"); } @end From b9876635ca8766dc42ae9302683f295c6c280bce Mon Sep 17 00:00:00 2001 From: wangying Date: Fri, 11 Mar 2022 10:47:44 +0800 Subject: [PATCH 07/11] avoid extreme cases of inequality --- .../darwin/ios/framework/Source/FlutterViewControllerTest.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index a016991b7caeb..526816190570f 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -1102,7 +1102,7 @@ - (void)testFakeEventTimeStamp { flutter::PointerData pointer_data = [vc generatePointerDataForFake]; int64_t current_time = [[NSProcessInfo processInfo] systemUptime]; - XCTAssertTrue(current_time == pointer_data.time_stamp / 1000 / 1000, + XCTAssertTrue(current_time / 2 == pointer_data.time_stamp / 1000 / 1000 / 2, @"PointerData.time_stamp should be equal to NSProcessInfo.systemUptime"); } @end From fa91c3f984ae01255d47f9e4fca21321658ae19a Mon Sep 17 00:00:00 2001 From: "wangying.666" Date: Fri, 11 Mar 2022 12:06:47 +0800 Subject: [PATCH 08/11] opt test logic to avoid boundary case --- .../ios/framework/Source/FlutterViewControllerTest.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index 526816190570f..d5d0e40027921 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -6,8 +6,8 @@ #import #include "flutter/fml/platform/darwin/message_loop_darwin.h" -#include "flutter/lib/ui/window/pointer_data.h" #import "flutter/lib/ui/window/platform_configuration.h" +#include "flutter/lib/ui/window/pointer_data.h" #import "flutter/lib/ui/window/viewport_metrics.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" @@ -1101,8 +1101,9 @@ - (void)testFakeEventTimeStamp { XCTAssertNotNil(vc); flutter::PointerData pointer_data = [vc generatePointerDataForFake]; - int64_t current_time = [[NSProcessInfo processInfo] systemUptime]; - XCTAssertTrue(current_time / 2 == pointer_data.time_stamp / 1000 / 1000 / 2, + int64_t current_micros = [[NSProcessInfo processInfo] systemUptime] * 1000 * 1000; + int64_t interval_micros = current_micros - pointer_data.time_stamp; + XCTAssertTrue(interval_micros / 1000 == 0, @"PointerData.time_stamp should be equal to NSProcessInfo.systemUptime"); } @end From 8ab13b689939142e448de11aa772e50804471e62 Mon Sep 17 00:00:00 2001 From: wangying Date: Fri, 11 Mar 2022 12:23:51 +0800 Subject: [PATCH 09/11] Update shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm Co-authored-by: Tong Mu --- .../darwin/ios/framework/Source/FlutterViewControllerTest.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index d5d0e40027921..9f299d912cfdc 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -1103,7 +1103,8 @@ - (void)testFakeEventTimeStamp { flutter::PointerData pointer_data = [vc generatePointerDataForFake]; int64_t current_micros = [[NSProcessInfo processInfo] systemUptime] * 1000 * 1000; int64_t interval_micros = current_micros - pointer_data.time_stamp; - XCTAssertTrue(interval_micros / 1000 == 0, + const int64_t tolerance_millis = 2; + XCTAssertTrue(interval_micros / 1000 < 2, @"PointerData.time_stamp should be equal to NSProcessInfo.systemUptime"); } @end From ff82df3623807f17e1feb6d5182e4b736794d764 Mon Sep 17 00:00:00 2001 From: wangying Date: Fri, 11 Mar 2022 12:25:12 +0800 Subject: [PATCH 10/11] Update shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm Co-authored-by: Tong Mu --- .../darwin/ios/framework/Source/FlutterViewControllerTest.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index 9f299d912cfdc..8d838d72d02ec 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -1104,7 +1104,7 @@ - (void)testFakeEventTimeStamp { int64_t current_micros = [[NSProcessInfo processInfo] systemUptime] * 1000 * 1000; int64_t interval_micros = current_micros - pointer_data.time_stamp; const int64_t tolerance_millis = 2; - XCTAssertTrue(interval_micros / 1000 < 2, + XCTAssertTrue(interval_micros / 1000 < tolerance_millis, @"PointerData.time_stamp should be equal to NSProcessInfo.systemUptime"); } @end From 26bcea153cdd5c911fe270b5a78f3dfddd4f4e69 Mon Sep 17 00:00:00 2001 From: "wangying.666" Date: Sun, 13 Mar 2022 22:59:19 +0800 Subject: [PATCH 11/11] remove repeat code --- .../darwin/ios/framework/Source/FlutterViewController.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 1aa4edc22765c..b497d0917580a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -439,7 +439,6 @@ static void SendFakeTouchEvent(FlutterEngine* engine, flutter::PointerData pointer_data = [[engine viewController] generatePointerDataForFake]; pointer_data.physical_x = location.x * scale; pointer_data.physical_y = location.y * scale; - pointer_data.kind = flutter::PointerData::DeviceKind::kTouch; auto packet = std::make_unique(/*count=*/1); pointer_data.change = change; packet->SetPointerData(0, pointer_data);