diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 1a87c66386..2c0f4c9bec 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -1124,6 +1124,7 @@ static void SetThreadPriority(FlutterThreadPriority priority) { while ((nextViewController = [viewControllerEnumerator nextObject])) { [nextViewController onPreEngineRestart]; } + [_platformViewController reset]; } - (void)onVSync:(uintptr_t)baton { diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h index 4123d8208f..a784a69b94 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h @@ -58,6 +58,11 @@ */ - (void)disposePlatformViews; +/** + * Removes all platform views. + */ +- (void)reset; + @end #endif // FLUTTER_SHELL_PLATFORM_DARWIN_MACOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWCONTROLLER_H_ 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 64b83cd80d..5e7230c7d1 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 @@ -170,4 +170,11 @@ _platformViewsToDispose.clear(); } +- (void)reset { + for (const auto& pair : _platformViews) { + _platformViewsToDispose.insert(pair.first); + } + [self disposePlatformViews]; +} + @end 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 65f59ddaf2..066eeff4dc 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 @@ -141,6 +141,60 @@ TEST(FlutterPlatformViewController, TestCreateAndDispose) { EXPECT_TRUE(disposed); } +TEST(FlutterPlatformViewController, TestReset) { + // Use id so we can access handleMethodCall method. + id platformViewController = [[FlutterPlatformViewController alloc] init]; + TestFlutterPlatformViewFactory* factory = [TestFlutterPlatformViewFactory alloc]; + + [platformViewController registerViewFactory:factory withId:@"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; + } else { + created = false; + } + }; + + // Create 2 views. + FlutterMethodCall* methodCallOnCreate0 = + [FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @0, + @"viewType" : @"MockPlatformView" + }]; + + [platformViewController handleMethodCall:methodCallOnCreate0 result:resultOnCreate]; + EXPECT_TRUE(created); + + FlutterMethodCall* methodCallOnCreate1 = + [FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @1, + @"viewType" : @"MockPlatformView" + }]; + [platformViewController handleMethodCall:methodCallOnCreate1 result:resultOnCreate]; + EXPECT_TRUE(created); + + TestFlutterPlatformView* view = nil; + + // Before the reset, the views exist. + view = (TestFlutterPlatformView*)[platformViewController platformViewWithID:0]; + EXPECT_TRUE(view != nil); + view = (TestFlutterPlatformView*)[platformViewController platformViewWithID:1]; + EXPECT_TRUE(view != nil); + + // After a reset, the views should no longer exist. + [platformViewController reset]; + + view = (TestFlutterPlatformView*)[platformViewController platformViewWithID:0]; + EXPECT_TRUE(view == nil); + view = (TestFlutterPlatformView*)[platformViewController platformViewWithID:1]; + EXPECT_TRUE(view == nil); +} + TEST(FlutterPlatformViewController, TestDisposeOnMissingViewId) { // Use id so we can access handleMethodCall method. id platformViewController = [[FlutterPlatformViewController alloc] init];