Commit ec424376 authored by Mark Cogan's avatar Mark Cogan Committed by Commit Bot

[iOS] Prevent AppState getting the BrowserInterface for zero scenes.

In some circumstances, the shutdown logic can run when there are no
connected scenes (possibly when force-quitting). Asking for the
browser interface in this situation will cause an array overflow. This
CL is a quick patch to bypass that pending a cleaner fixup.

Bug: 1113097
Change-Id: I3e14c9bbd887c7ef66ee7e6454f4484bad8cb03a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2367080
Commit-Queue: Mark Cogan <marq@chromium.org>
Reviewed-by: default avatarRohit Rao <rohitrao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#801083}
parent b4349b2d
......@@ -456,8 +456,14 @@ initWithBrowserLauncher:(id<BrowserLauncher>)browserLauncher
// Halt the tabs, so any outstanding requests get cleaned up, without actually
// closing the tabs. Set the BVC to inactive to cancel all the dialogs.
if ([_browserLauncher browserInitializationStage] >=
INITIALIZATION_STAGE_FOREGROUND) {
// Don't do this if there are no scenes, since there's no defined interface
// provider (and no tabs)
// TODO(crbug.com/1113097): Factor out this check by not having app layer
// logic use interface providers.
BOOL scenesAreAvailable = [self connectedScenes].count > 0;
if (scenesAreAvailable && [_browserLauncher browserInitializationStage] >=
INITIALIZATION_STAGE_FOREGROUND) {
_browserLauncher.interfaceProvider.currentInterface.userInteractionEnabled =
NO;
}
......@@ -566,8 +572,10 @@ initWithBrowserLauncher:(id<BrowserLauncher>)browserLauncher
NSSet* connectedScenes =
[UIApplication sharedApplication].connectedScenes;
for (UIWindowScene* scene in connectedScenes) {
if (!scene.delegate) {
if (![scene.delegate isKindOfClass:[SceneDelegate class]]) {
// This might happen in tests.
// TODO(crbug.com/1113097): This shouldn't be needed.
[sceneStates addObject:[[SceneState alloc] initWithAppState:self]];
continue;
}
......@@ -577,11 +585,11 @@ initWithBrowserLauncher:(id<BrowserLauncher>)browserLauncher
}
return sceneStates;
}
NOTREACHED();
return @[];
} else {
} else if (self.mainSceneState) {
return @[ self.mainSceneState ];
}
// This can happen if the app is terminating before any scenes are set up.
return @[];
}
- (void)setLastTappedWindow:(UIWindow*)window {
......
......@@ -568,6 +568,11 @@ TEST_F(AppStateWithThreadTest, willTerminate) {
startupInformation:startupInformation
applicationDelegate:applicationDelegate];
// Create a scene state so that full shutdown will run.
if (!IsSceneStartupSupported()) {
appState.mainSceneState = [[SceneState alloc] initWithAppState:appState];
}
id application = [OCMockObject mockForClass:[UIApplication class]];
// Action.
......
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