@@ -2782,6 +2782,111 @@ - (void)testFlutterPlatformViewTouchesCancelledEventAreForcedToBeCancelled {
27822782 flutterPlatformViewsController->Reset ();
27832783}
27842784
2785+ - (void )testFlutterPlatformViewTouchesEndedOrTouchesCancelledEventDoesNotFailTheGestureRecognizer {
2786+ flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2787+
2788+ flutter::TaskRunners runners (/* label=*/ self.name .UTF8String ,
2789+ /* platform=*/ GetDefaultTaskRunner (),
2790+ /* raster=*/ GetDefaultTaskRunner (),
2791+ /* ui=*/ GetDefaultTaskRunner (),
2792+ /* io=*/ GetDefaultTaskRunner ());
2793+ auto flutterPlatformViewsController = std::make_shared<flutter::PlatformViewsController>();
2794+ flutterPlatformViewsController->SetTaskRunner (GetDefaultTaskRunner ());
2795+ auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2796+ /* delegate=*/ mock_delegate,
2797+ /* rendering_api=*/ mock_delegate.settings_ .enable_impeller
2798+ ? flutter::IOSRenderingAPI::kMetal
2799+ : flutter::IOSRenderingAPI::kSoftware ,
2800+ /* platform_views_controller=*/ flutterPlatformViewsController,
2801+ /* task_runners=*/ runners,
2802+ /* worker_task_runner=*/ nil ,
2803+ /* is_gpu_disabled_jsync_switch=*/ std::make_shared<fml::SyncSwitch>());
2804+
2805+ FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
2806+ [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc ] init ];
2807+ flutterPlatformViewsController->RegisterViewFactory (
2808+ factory, @" MockFlutterPlatformView" ,
2809+ FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
2810+ FlutterResult result = ^(id result) {
2811+ };
2812+ flutterPlatformViewsController->OnMethodCall (
2813+ [FlutterMethodCall
2814+ methodCallWithMethodName: @" create"
2815+ arguments: @{@" id" : @2 , @" viewType" : @" MockFlutterPlatformView" }],
2816+ result);
2817+
2818+ XCTAssertNotNil (gMockPlatformView );
2819+
2820+ // Find touch inteceptor view
2821+ UIView* touchInteceptorView = gMockPlatformView ;
2822+ while (touchInteceptorView != nil &&
2823+ ![touchInteceptorView isKindOfClass: [FlutterTouchInterceptingView class ]]) {
2824+ touchInteceptorView = touchInteceptorView.superview ;
2825+ }
2826+ XCTAssertNotNil (touchInteceptorView);
2827+
2828+ // Find ForwardGestureRecognizer
2829+ __block UIGestureRecognizer* forwardGestureRecognizer = nil ;
2830+ for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers ) {
2831+ if ([gestureRecognizer isKindOfClass: NSClassFromString (@" ForwardingGestureRecognizer" )]) {
2832+ forwardGestureRecognizer = gestureRecognizer;
2833+ break ;
2834+ }
2835+ }
2836+ id flutterViewContoller = OCMClassMock ([FlutterViewController class ]);
2837+
2838+ flutterPlatformViewsController->SetFlutterViewController (flutterViewContoller);
2839+
2840+ NSSet * touches1 = [NSSet setWithObject: @1 ];
2841+ id event1 = OCMClassMock ([UIEvent class ]);
2842+ XCTAssert (forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
2843+ @" Forwarding gesture recognizer must start with possible state." );
2844+ [forwardGestureRecognizer touchesBegan: touches1 withEvent: event1];
2845+ [forwardGestureRecognizer touchesEnded: touches1 withEvent: event1];
2846+ XCTAssert (forwardGestureRecognizer.state == UIGestureRecognizerStateFailed,
2847+ @" Forwarding gesture recognizer must end with failed state." );
2848+
2849+ XCTestExpectation* touchEndedExpectation =
2850+ [self expectationWithDescription: @" Wait for gesture recognizer's state change." ];
2851+ dispatch_async (dispatch_get_main_queue (), ^{
2852+ // Re-query forward gesture recognizer since it's recreated.
2853+ for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers ) {
2854+ if ([gestureRecognizer isKindOfClass: NSClassFromString (@" ForwardingGestureRecognizer" )]) {
2855+ forwardGestureRecognizer = gestureRecognizer;
2856+ break ;
2857+ }
2858+ }
2859+ XCTAssert (forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
2860+ @" Forwarding gesture recognizer must be reset to possible state." );
2861+ [touchEndedExpectation fulfill ];
2862+ });
2863+ [self waitForExpectationsWithTimeout: 30 handler: nil ];
2864+
2865+ XCTAssert (forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
2866+ @" Forwarding gesture recognizer must start with possible state." );
2867+ [forwardGestureRecognizer touchesBegan: touches1 withEvent: event1];
2868+ [forwardGestureRecognizer touchesCancelled: touches1 withEvent: event1];
2869+ XCTAssert (forwardGestureRecognizer.state == UIGestureRecognizerStateFailed,
2870+ @" Forwarding gesture recognizer must end with failed state." );
2871+ XCTestExpectation* touchCancelledExpectation =
2872+ [self expectationWithDescription: @" Wait for gesture recognizer's state change." ];
2873+ dispatch_async (dispatch_get_main_queue (), ^{
2874+ // Re-query forward gesture recognizer since it's recreated.
2875+ for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers ) {
2876+ if ([gestureRecognizer isKindOfClass: NSClassFromString (@" ForwardingGestureRecognizer" )]) {
2877+ forwardGestureRecognizer = gestureRecognizer;
2878+ break ;
2879+ }
2880+ }
2881+ XCTAssert (forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
2882+ @" Forwarding gesture recognizer must be reset to possible state." );
2883+ [touchCancelledExpectation fulfill ];
2884+ });
2885+ [self waitForExpectationsWithTimeout: 30 handler: nil ];
2886+
2887+ flutterPlatformViewsController->Reset ();
2888+ }
2889+
27852890- (void )testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashing {
27862891 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
27872892
0 commit comments