Skip to content

Commit b804448

Browse files
authored
[macOS] Fix TextInputPlugin crash when no viewId is provided (flutter#169583)
Fixes flutter#169204 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent 0710690 commit b804448

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.mm

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <algorithm>
1111
#include <memory>
1212

13+
#include "flutter/common/constants.h"
1314
#include "flutter/fml/platform/darwin/string_range_sanitization.h"
1415
#include "flutter/shell/platform/common/text_editing_delta.h"
1516
#include "flutter/shell/platform/common/text_input_model.h"
@@ -425,8 +426,12 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
425426
}
426427

427428
_activeModel = std::make_unique<flutter::TextInputModel>();
428-
NSNumber* viewId = config[kViewId];
429-
_currentViewController = [_delegate viewControllerForIdentifier:viewId.longLongValue];
429+
FlutterViewIdentifier viewId = flutter::kFlutterImplicitViewId;
430+
NSObject* requestViewId = config[kViewId];
431+
if ([requestViewId isKindOfClass:[NSNumber class]]) {
432+
viewId = [(NSNumber*)requestViewId longLongValue];
433+
}
434+
_currentViewController = [_delegate viewControllerForIdentifier:viewId];
430435
FML_DCHECK(_currentViewController != nil);
431436
}
432437
} else if ([method isEqualToString:kShowMethod]) {

engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPluginTest.mm

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ - (bool)testClearClientDuringComposing;
6060
@interface FlutterTextInputPluginTestDelegate : NSObject <FlutterTextInputPluginDelegate> {
6161
id<FlutterBinaryMessenger> _binaryMessenger;
6262
FlutterViewController* _viewController;
63+
FlutterViewController* _implicitViewController;
6364
}
6465

6566
@end
@@ -80,10 +81,22 @@ - (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)messenger
8081
return self;
8182
}
8283

84+
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)messenger
85+
implicitViewController:(FlutterViewController*)viewController {
86+
self = [super init];
87+
if (self) {
88+
_binaryMessenger = messenger;
89+
_implicitViewController = viewController;
90+
}
91+
return self;
92+
}
93+
8394
- (nullable FlutterViewController*)viewControllerForIdentifier:
8495
(FlutterViewIdentifier)viewIdentifier {
8596
if (viewIdentifier == kViewId) {
8697
return _viewController;
98+
} else if (viewIdentifier == flutter::kFlutterImplicitViewId) {
99+
return _implicitViewController;
87100
} else {
88101
return nil;
89102
}
@@ -2394,4 +2407,32 @@ - (bool)testSelectorsNotForwardedToFrameworkIfNoClient {
23942407
ASSERT_TRUE(plugin.clipsToBounds);
23952408
}
23962409

2410+
TEST(FlutterTextInputPluginTest, WorksWithoutViewId) {
2411+
id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
2412+
id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
2413+
OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
2414+
[engineMock binaryMessenger])
2415+
.andReturn(binaryMessengerMock);
2416+
2417+
FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
2418+
nibName:@""
2419+
bundle:nil];
2420+
2421+
FlutterTextInputPluginTestDelegate* delegate =
2422+
[[FlutterTextInputPluginTestDelegate alloc] initWithBinaryMessenger:binaryMessengerMock
2423+
implicitViewController:viewController];
2424+
2425+
FlutterTextInputPlugin* plugin = [[FlutterTextInputPlugin alloc] initWithDelegate:delegate];
2426+
2427+
NSDictionary* setClientConfig = @{
2428+
// omit viewId
2429+
};
2430+
[plugin handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
2431+
arguments:@[ @(1), setClientConfig ]]
2432+
result:^(id){
2433+
}];
2434+
2435+
ASSERT_TRUE(plugin.currentViewController == viewController);
2436+
}
2437+
23972438
} // namespace flutter::testing

0 commit comments

Comments
 (0)