diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 568a222455681..bc8f4c457e512 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -553,9 +553,11 @@ - (void)viewWillDisappear:(BOOL)animated { - (void)viewDidDisappear:(BOOL)animated { TRACE_EVENT0("flutter", "viewDidDisappear"); - [self surfaceUpdated:NO]; - [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.paused"]; - [self flushOngoingTouches]; + if ([_engine.get() viewController] == self) { + [self surfaceUpdated:NO]; + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.paused"]; + [self flushOngoingTouches]; + } [super viewDidDisappear:animated]; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index 7c986c120f46a..6c5d6ff4b45a7 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -54,11 +54,45 @@ - (UIAccessibilityContrast)accessibilityContrast; #endif @interface FlutterViewController (Tests) +- (void)surfaceUpdated:(BOOL)appeared; - (void)performOrientationUpdate:(UIInterfaceOrientationMask)new_preferences; @end @implementation FlutterViewControllerTest +- (void)testViewDidDisappearDoesntPauseEngine { + id engine = OCMClassMock([FlutterEngine class]); + id lifecycleChannel = OCMClassMock([FlutterBasicMessageChannel class]); + OCMStub([engine lifecycleChannel]).andReturn(lifecycleChannel); + FlutterViewController* viewControllerA = [[FlutterViewController alloc] initWithEngine:engine + nibName:nil + bundle:nil]; + FlutterViewController* viewControllerB = [[FlutterViewController alloc] initWithEngine:engine + nibName:nil + bundle:nil]; + id viewControllerMock = OCMPartialMock(viewControllerA); + OCMStub([viewControllerMock surfaceUpdated:NO]); + OCMStub([engine viewController]).andReturn(viewControllerB); + [viewControllerA viewDidDisappear:NO]; + OCMReject([lifecycleChannel sendMessage:@"AppLifecycleState.paused"]); + OCMReject([viewControllerMock surfaceUpdated:[OCMArg any]]); +} + +- (void)testViewDidDisappearDoesPauseEngine { + id engine = OCMClassMock([FlutterEngine class]); + id lifecycleChannel = OCMClassMock([FlutterBasicMessageChannel class]); + OCMStub([engine lifecycleChannel]).andReturn(lifecycleChannel); + FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine + nibName:nil + bundle:nil]; + id viewControllerMock = OCMPartialMock(viewController); + OCMStub([viewControllerMock surfaceUpdated:NO]); + OCMStub([engine viewController]).andReturn(viewController); + [viewController viewDidDisappear:NO]; + OCMVerify([lifecycleChannel sendMessage:@"AppLifecycleState.paused"]); + OCMVerify([viewControllerMock surfaceUpdated:NO]); +} + - (void)testBinaryMessenger { id engine = OCMClassMock([FlutterEngine class]); FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine