diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 3d3a38eb30987..1aa4edc22765c 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -421,19 +421,25 @@ - (void)loadView { _scrollView.reset(scrollView); } -static void SendFakeTouchEvent(FlutterEngine* engine, - CGPoint location, - flutter::PointerData::Change change) { - const CGFloat scale = [UIScreen mainScreen].scale; +- (flutter::PointerData)generatePointerDataForFake { flutter::PointerData pointer_data; pointer_data.Clear(); - 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; + return pointer_data; +} + +static void SendFakeTouchEvent(FlutterEngine* engine, + CGPoint location, + flutter::PointerData::Change change) { + const CGFloat scale = [UIScreen mainScreen].scale; + 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); @@ -762,17 +768,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. - // `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; + 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 d6f3e0f9a1f78..a016991b7caeb 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/platform_configuration.h" #import "flutter/lib/ui/window/viewport_metrics.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" @@ -138,6 +139,7 @@ - (void)startKeyBoardAnimation:(NSTimeInterval)duration; - (void)ensureViewportMetricsIsCorrect; - (void)invalidateDisplayLink; - (void)addInternalPlugins; +- (flutter::PointerData)generatePointerDataForFake; @end @interface FlutterViewControllerTest : XCTestCase @@ -1092,4 +1094,15 @@ - (void)testMouseSupport API_AVAILABLE(ios(13.4)) { dispatchPointerDataPacket:std::make_unique(0)]; } +- (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]; + XCTAssertTrue(current_time == pointer_data.time_stamp / 1000 / 1000, + @"PointerData.time_stamp should be equal to NSProcessInfo.systemUptime"); +} @end