From 932ecf69e0a20c22bb00dc6910caec08fdc230af Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Wed, 14 Feb 2024 19:47:57 +0000 Subject: [PATCH] macOS: add stubs for PlatformView gesture handling (flutter/engine#50630) Adds method handler stubs for acceptGesture and rejectGesture channel method invocations. This avoids error messages being logged and puts in place the scaffolding for the implementation. Issue: https://github.com/flutter/flutter/issues/124492 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- .../Source/FlutterPlatformViewController.mm | 34 +++++ .../FlutterPlatformViewControllerTest.mm | 116 ++++++++++++++++++ 2 files changed, 150 insertions(+) diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.mm index 917ee5def5a..64b83cd80d3 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.mm @@ -116,11 +116,45 @@ NSNumber* arg = [call arguments]; int64_t viewId = [arg longLongValue]; [self onDisposeWithViewID:viewId result:result]; + } else if ([[call method] isEqualToString:@"acceptGesture"]) { + [self handleAcceptGesture:call result:result]; + } else if ([[call method] isEqualToString:@"rejectGesture"]) { + [self handleRejectGesture:call result:result]; } else { result(FlutterMethodNotImplemented); } } +- (void)handleAcceptGesture:(FlutterMethodCall*)call result:(FlutterResult)result { + NSDictionary* args = [call arguments]; + NSAssert(args && args[@"id"], @"id argument is required"); + int64_t viewId = [args[@"id"] longLongValue]; + if (_platformViews.count(viewId) == 0) { + result([FlutterError errorWithCode:@"unknown_view" + message:@"trying to set gesture state for an unknown view" + details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); + return; + } + + // TODO(cbracken): Implement. https://github.com/flutter/flutter/issues/124492 + result(nil); +} + +- (void)handleRejectGesture:(FlutterMethodCall*)call result:(FlutterResult)result { + NSDictionary* args = [call arguments]; + NSAssert(args && args[@"id"], @"id argument is required"); + int64_t viewId = [args[@"id"] longLongValue]; + if (_platformViews.count(viewId) == 0) { + result([FlutterError errorWithCode:@"unknown_view" + message:@"trying to set gesture state for an unknown view" + details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); + return; + } + + // TODO(cbracken): Implement. https://github.com/flutter/flutter/issues/124492 + result(nil); +} + - (void)disposePlatformViews { if (_platformViewsToDispose.empty()) { return; diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewControllerTest.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewControllerTest.mm index f8880ba69d3..65f59ddaf21 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewControllerTest.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewControllerTest.mm @@ -161,4 +161,120 @@ TEST(FlutterPlatformViewController, TestDisposeOnMissingViewId) { EXPECT_TRUE(errored); } +TEST(FlutterPlatformViewController, TestAcceptGesture) { + FlutterPlatformViewController* platformViewController = + [[FlutterPlatformViewController alloc] init]; + [platformViewController registerViewFactory:[TestFlutterPlatformViewFactory alloc] + withId:@"MockPlatformView"]; + + // Create the PlatformView. + const NSNumber* viewId = [NSNumber numberWithLongLong:2]; + FlutterMethodCall* methodCallOnCreate = [FlutterMethodCall + methodCallWithMethodName:@"create" + arguments:@{@"id" : viewId, @"viewType" : @"MockPlatformView"}]; + __block bool created = false; + FlutterResult resultOnCreate = ^(id result) { + // If a platform view is successfully created, the result is nil. + if (result == nil) { + created = true; + } + }; + [platformViewController handleMethodCall:methodCallOnCreate result:resultOnCreate]; + + // Call acceptGesture. + FlutterMethodCall* methodCallAcceptGesture = + [FlutterMethodCall methodCallWithMethodName:@"acceptGesture" arguments:@{@"id" : viewId}]; + __block bool acceptGestureCalled = false; + FlutterResult resultAcceptGesture = ^(id result) { + // If a acceptGesture is successful, the result is nil. + if (result == nil) { + acceptGestureCalled = true; + } + }; + [platformViewController handleMethodCall:methodCallAcceptGesture result:resultAcceptGesture]; + + EXPECT_TRUE(created); + EXPECT_TRUE(acceptGestureCalled); +} + +TEST(FlutterPlatformViewController, TestAcceptGestureOnMissingViewId) { + FlutterPlatformViewController* platformViewController = + [[FlutterPlatformViewController alloc] init]; + [platformViewController registerViewFactory:[TestFlutterPlatformViewFactory alloc] + withId:@"MockPlatformView"]; + + // Call rejectGesture. + FlutterMethodCall* methodCallAcceptGesture = + [FlutterMethodCall methodCallWithMethodName:@"acceptGesture" arguments:@{ + @"id" : @20 + }]; + __block bool errored = false; + FlutterResult result = ^(id result) { + if ([result isKindOfClass:[FlutterError class]]) { + errored = true; + } + }; + [platformViewController handleMethodCall:methodCallAcceptGesture result:result]; + + EXPECT_TRUE(errored); +} + +TEST(FlutterPlatformViewController, TestRejectGesture) { + FlutterPlatformViewController* platformViewController = + [[FlutterPlatformViewController alloc] init]; + [platformViewController registerViewFactory:[TestFlutterPlatformViewFactory alloc] + withId:@"MockPlatformView"]; + + // Create the PlatformView. + const NSNumber* viewId = [NSNumber numberWithLongLong:2]; + FlutterMethodCall* methodCallOnCreate = [FlutterMethodCall + methodCallWithMethodName:@"create" + arguments:@{@"id" : viewId, @"viewType" : @"MockPlatformView"}]; + __block bool created = false; + FlutterResult resultOnCreate = ^(id result) { + // If a platform view is successfully created, the result is nil. + if (result == nil) { + created = true; + } + }; + [platformViewController handleMethodCall:methodCallOnCreate result:resultOnCreate]; + + // Call rejectGesture. + FlutterMethodCall* methodCallRejectGesture = + [FlutterMethodCall methodCallWithMethodName:@"rejectGesture" arguments:@{@"id" : viewId}]; + __block bool rejectGestureCalled = false; + FlutterResult resultRejectGesture = ^(id result) { + // If a rejectGesture is successful, the result is nil. + if (result == nil) { + rejectGestureCalled = true; + } + }; + [platformViewController handleMethodCall:methodCallRejectGesture result:resultRejectGesture]; + + EXPECT_TRUE(created); + EXPECT_TRUE(rejectGestureCalled); +} + +TEST(FlutterPlatformViewController, TestRejectGestureOnMissingViewId) { + FlutterPlatformViewController* platformViewController = + [[FlutterPlatformViewController alloc] init]; + [platformViewController registerViewFactory:[TestFlutterPlatformViewFactory alloc] + withId:@"MockPlatformView"]; + + // Call rejectGesture. + FlutterMethodCall* methodCallRejectGesture = + [FlutterMethodCall methodCallWithMethodName:@"rejectGesture" arguments:@{ + @"id" : @20 + }]; + __block bool errored = false; + FlutterResult result = ^(id result) { + if ([result isKindOfClass:[FlutterError class]]) { + errored = true; + } + }; + [platformViewController handleMethodCall:methodCallRejectGesture result:result]; + + EXPECT_TRUE(errored); +} + } // namespace flutter::testing