Commit 5e65b875 authored by Chris Lu's avatar Chris Lu Committed by Commit Bot

[ios] Mark Coordinator as stopped before calling dismissal callbacks

Mark self.started as NO in stopAnimated: before calling
dismissal callbacks in the Infobar Overlay Coordinators
will prevent successive calls to stop from executing. This is
bad because the request will be destroyed in the first callback
sequence, and then a DCHECK will fail in a successive sequence.

Bug: 1112482
Change-Id: I13f487ebe99f593e253a70af8f26a79375210fd7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2335408
Commit-Queue: Chris Lu <thegreenfrog@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#794543}
parent 7bd9b701
...@@ -119,11 +119,13 @@ ...@@ -119,11 +119,13 @@
- (void)stopAnimated:(BOOL)animated { - (void)stopAnimated:(BOOL)animated {
if (!self.started) if (!self.started)
return; return;
// Mark started as NO before calling dismissal callback to prevent dup
// stopAnimated: executions.
self.started = NO;
[self.baseViewController dismissViewControllerAnimated:animated [self.baseViewController dismissViewControllerAnimated:animated
completion:^{ completion:^{
[self finishDismissal]; [self finishDismissal];
}]; }];
self.started = NO;
} }
- (UIViewController*)viewController { - (UIViewController*)viewController {
......
...@@ -39,11 +39,14 @@ ...@@ -39,11 +39,14 @@
- (void)stopAnimated:(BOOL)animated { - (void)stopAnimated:(BOOL)animated {
if (!self.started) if (!self.started)
return; return;
// Mark started as NO before calling dismissal callback to prevent dup
// stopAnimated: executions.
self.started = NO;
// Notify the presentation context that the dismissal has finished. This // Notify the presentation context that the dismissal has finished. This
// is necessary to synchronize OverlayPresenter scheduling logic with the UI // is necessary to synchronize OverlayPresenter scheduling logic with the UI
// layer. // layer.
self.delegate->OverlayUIDidFinishDismissal(self.request); self.delegate->OverlayUIDidFinishDismissal(self.request);
self.started = NO;
} }
@end @end
...@@ -52,11 +52,13 @@ ...@@ -52,11 +52,13 @@
- (void)stopAnimated:(BOOL)animated { - (void)stopAnimated:(BOOL)animated {
if (!self.started) if (!self.started)
return; return;
// Mark started as NO before calling dismissal callback to prevent dup
// stopAnimated: executions.
self.started = NO;
[self.baseViewController dismissViewControllerAnimated:animated [self.baseViewController dismissViewControllerAnimated:animated
completion:^{ completion:^{
[self finishDismissal]; [self finishDismissal];
}]; }];
self.started = NO;
} }
- (UIViewController*)viewController { - (UIViewController*)viewController {
......
...@@ -152,3 +152,33 @@ TEST_F(InfobarModalOverlayCoordinatorTest, ModalPresentation) { ...@@ -152,3 +152,33 @@ TEST_F(InfobarModalOverlayCoordinatorTest, ModalPresentation) {
return !root_view_controller_.presentedViewController; return !root_view_controller_.presentedViewController;
})); }));
} }
// Tests the modal dismiss flow for a FakeInfobarModalOverlayCoordinator.
TEST_F(InfobarModalOverlayCoordinatorTest, ModalDismiss) {
// Start the coordinator, expecting OverlayUIDidFinishPresentation() to be
// executed.
EXPECT_CALL(delegate_, OverlayUIDidFinishPresentation(request_.get()));
[coordinator_ startAnimated:NO];
// Wait for presentation to finish.
EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^BOOL {
UIViewController* presented_view_controller =
root_view_controller_.presentedViewController;
return presented_view_controller &&
!presented_view_controller.beingPresented;
}));
// Stop the coordinator, expecting OverlayUIDidFinishDismissal() to be
// executed once.
EXPECT_CALL(delegate_, OverlayUIDidFinishDismissal(request_.get())).Times(1);
[coordinator_ stopAnimated:NO];
// Stop coordinator again. It should be a no-op since stop has been called
// already (i.e. No OverlayUIDidFinishDismissal called).
[coordinator_ stopAnimated:NO];
// Wait for dismissal to finish.
EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^BOOL {
return !root_view_controller_.presentedViewController;
}));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment