Commit 3ddaf449 authored by Stepan Khapugin's avatar Stepan Khapugin Committed by Commit Bot

[multiball] Enable basic multiwindow operation with flag on.

Adds a startup sequence for when the flag is enabled.
Many features are disabled, but it allows booting up and even
opening a second window.

Details:
* uses scene notifications to connect main+scene controllers
* uses scene notifications for app delegate level plumbing
* fixes window creation w/ flag set

Change-Id: I3f85f430ca916e9a866477582e646ca5b92ce4df
Bug: 1045547
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2097990
Commit-Queue: Mark Cogan <marq@chromium.org>
Auto-Submit: Stepan Khapugin <stkhapugin@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#750638}
parent 504597ba
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#import "ios/chrome/app/main_application_delegate_testing.h" #import "ios/chrome/app/main_application_delegate_testing.h"
#import "ios/chrome/app/main_controller.h" #import "ios/chrome/app/main_controller.h"
#import "ios/chrome/browser/ui/main/scene_controller.h" #import "ios/chrome/browser/ui/main/scene_controller.h"
#import "ios/chrome/browser/ui/main/scene_delegate.h"
#import "ios/chrome/browser/ui/main/scene_state.h" #import "ios/chrome/browser/ui/main/scene_state.h"
#include "ios/chrome/browser/ui/util/multi_window_support.h" #include "ios/chrome/browser/ui/util/multi_window_support.h"
#include "ios/public/provider/chrome/browser/chrome_browser_provider.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
...@@ -129,6 +130,21 @@ ...@@ -129,6 +130,21 @@
self.sceneState.activationLevel = SceneActivationLevelForegroundInactive; self.sceneState.activationLevel = SceneActivationLevelForegroundInactive;
} }
if (@available(iOS 13, *)) {
if (IsMultiwindowSupported()) {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(sceneWillConnect:)
name:UISceneWillConnectNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(sceneDidEnterBackground:)
name:UISceneDidEnterBackgroundNotification
object:nil];
}
}
return requiresHandling; return requiresHandling;
} }
...@@ -199,6 +215,59 @@ ...@@ -199,6 +215,59 @@
[_memoryHelper handleMemoryPressure]; [_memoryHelper handleMemoryPressure];
} }
#pragma mark - Scenes lifecycle
- (NSInteger)foregroundSceneCount {
DCHECK(IsMultiwindowSupported());
if (@available(iOS 13, *)) {
NSInteger foregroundSceneCount = 0;
for (UIScene* scene in UIApplication.sharedApplication.connectedScenes) {
if ((scene.activationState == UISceneActivationStateForegroundInactive) ||
(scene.activationState == UISceneActivationStateForegroundActive)) {
foregroundSceneCount++;
}
}
return foregroundSceneCount;
}
return 0;
}
- (void)sceneWillConnect:(NSNotification*)notification {
DCHECK(IsMultiwindowSupported());
if (@available(iOS 13, *)) {
UIWindowScene* scene = (UIWindowScene*)notification.object;
SceneDelegate* sceneDelegate = (SceneDelegate*)scene.delegate;
SceneController* sceneController = sceneDelegate.sceneController;
_tabSwitcherProtocol = sceneController;
_tabOpener = sceneController;
_appNavigation = sceneController;
// TODO(crbug.com/1060645): This should be called later, or this flow should
// be changed completely.
if (self.foregroundSceneCount == 0) {
[_appState applicationWillEnterForeground:UIApplication.sharedApplication
metricsMediator:_metricsMediator
memoryHelper:_memoryHelper
tabOpener:_tabOpener
appNavigation:_appNavigation];
}
}
}
- (void)sceneDidEnterBackground:(NSNotification*)notification {
DCHECK(IsMultiwindowSupported());
if (@available(iOS 13, *)) {
// When the first scene enters foreground, update the app state.
if (self.foregroundSceneCount == 0) {
[_appState applicationDidEnterBackground:UIApplication.sharedApplication
memoryHelper:_memoryHelper
incognitoContentVisible:self.sceneController
.incognitoContentVisible];
}
}
}
#pragma mark Downloading Data in the Background #pragma mark Downloading Data in the Background
- (void)application:(UIApplication*)application - (void)application:(UIApplication*)application
......
...@@ -124,8 +124,10 @@ ...@@ -124,8 +124,10 @@
#include "ios/chrome/browser/ui/history/history_coordinator.h" #include "ios/chrome/browser/ui/history/history_coordinator.h"
#import "ios/chrome/browser/ui/main/browser_view_wrangler.h" #import "ios/chrome/browser/ui/main/browser_view_wrangler.h"
#import "ios/chrome/browser/ui/main/scene_controller_guts.h" #import "ios/chrome/browser/ui/main/scene_controller_guts.h"
#import "ios/chrome/browser/ui/main/scene_delegate.h"
#import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
#import "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/ui_feature_flags.h"
#include "ios/chrome/browser/ui/util/multi_window_support.h"
#include "ios/chrome/browser/ui/util/ui_util.h" #include "ios/chrome/browser/ui/util/ui_util.h"
#import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
#import "ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.h" #import "ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.h"
...@@ -442,6 +444,22 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData( ...@@ -442,6 +444,22 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData(
// Register all providers before calling any Chromium code. // Register all providers before calling any Chromium code.
[ProviderRegistration registerProviders]; [ProviderRegistration registerProviders];
if (@available(iOS 13, *)) {
if (IsMultiwindowSupported()) {
// Subscribe for scene connection and disconnection notifications.
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(sceneWillConnect:)
name:UISceneWillConnectNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(sceneDidActivate:)
name:UISceneDidActivateNotification
object:nil];
}
}
} }
- (void)startUpBrowserBackgroundInitialization { - (void)startUpBrowserBackgroundInitialization {
...@@ -602,6 +620,15 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData( ...@@ -602,6 +620,15 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData(
BOOL needRestore = BOOL needRestore =
[self startUpBeforeFirstWindowCreatedAndPrepareForRestorationPostCrash: [self startUpBeforeFirstWindowCreatedAndPrepareForRestorationPostCrash:
postCrashLaunch]; postCrashLaunch];
if (@available(iOS 13, *)) {
if (IsMultiwindowSupported()) {
// The rest of the startup sequence is handled by the Scenes and in
// response to notifications.
return;
}
}
[self.sceneController startUpChromeUIPostCrash:postCrashLaunch [self.sceneController startUpChromeUIPostCrash:postCrashLaunch
needRestoration:needRestore]; needRestoration:needRestore];
[self startUpAfterFirstWindowCreated]; [self startUpAfterFirstWindowCreated];
...@@ -648,6 +675,30 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData( ...@@ -648,6 +675,30 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData(
triggerSystemPromptForNewUser:YES]; triggerSystemPromptForNewUser:YES];
} }
#pragma mark - Scene notifications
// Handler for UISceneWillConnectNotification.
- (void)sceneWillConnect:(NSNotification*)notification {
DCHECK(IsMultiwindowSupported());
if (@available(iOS 13, *)) {
UIWindowScene* scene =
base::mac::ObjCCastStrict<UIWindowScene>(notification.object);
SceneDelegate* sceneDelegate =
base::mac::ObjCCastStrict<SceneDelegate>(scene.delegate);
self.sceneController = sceneDelegate.sceneController;
sceneDelegate.sceneController.mainController = self;
}
}
// Handler for UISceneDidActivateNotification.
- (void)sceneDidActivate:(NSNotification*)notification {
DCHECK(IsMultiwindowSupported());
if (@available(iOS 13, *)) {
if (UIApplication.sharedApplication.connectedScenes.count == 1) {
[self startUpAfterFirstWindowCreated];
}
}
}
#pragma mark - Property implementation. #pragma mark - Property implementation.
......
...@@ -60,6 +60,7 @@ source_set("crash_report_internal") { ...@@ -60,6 +60,7 @@ source_set("crash_report_internal") {
"//ios/chrome/browser/sessions:serialisation", "//ios/chrome/browser/sessions:serialisation",
"//ios/chrome/browser/sessions:session_service", "//ios/chrome/browser/sessions:session_service",
"//ios/chrome/browser/ui/infobars:feature_flags", "//ios/chrome/browser/ui/infobars:feature_flags",
"//ios/chrome/browser/ui/util:multiwindow_util",
"//ios/chrome/browser/web:tab_id_tab_helper", "//ios/chrome/browser/web:tab_id_tab_helper",
"//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list",
"//ios/web", "//ios/web",
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "ios/chrome/browser/crash_report/breakpad_helper.h" #include "ios/chrome/browser/crash_report/breakpad_helper.h"
#import "ios/chrome/browser/crash_report/crash_report_user_application_state.h" #import "ios/chrome/browser/crash_report/crash_report_user_application_state.h"
#import "ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.h" #import "ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.h"
#import "ios/chrome/browser/ui/util/multi_window_support.h"
#import "ios/chrome/browser/web/tab_id_tab_helper.h" #import "ios/chrome/browser/web/tab_id_tab_helper.h"
#import "ios/chrome/browser/web_state_list/all_web_state_observation_forwarder.h" #import "ios/chrome/browser/web_state_list/all_web_state_observation_forwarder.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list.h"
...@@ -216,6 +217,11 @@ const NSString* kDocumentMimeType = @"application/pdf"; ...@@ -216,6 +217,11 @@ const NSString* kDocumentMimeType = @"application/pdf";
} }
- (void)observeWebStateList:(WebStateList*)webStateList { - (void)observeWebStateList:(WebStateList*)webStateList {
if (_allWebStateObservationForwarder && IsMultiwindowSupported()) {
// TODO(crbug.com/1060658): enable crash reporting on more than one window.
return;
}
webStateList->AddObserver(_webStateListObserver.get()); webStateList->AddObserver(_webStateListObserver.get());
// CrashReporterURLObserver should only observe one webStateList at a time. // CrashReporterURLObserver should only observe one webStateList at a time.
DCHECK(!_allWebStateObservationForwarder); DCHECK(!_allWebStateObservationForwarder);
......
...@@ -154,6 +154,7 @@ source_set("browser_view") { ...@@ -154,6 +154,7 @@ source_set("browser_view") {
"//ios/chrome/browser/ui/toolbar_container:feature_flags", "//ios/chrome/browser/ui/toolbar_container:feature_flags",
"//ios/chrome/browser/ui/translate:legacy_translate", "//ios/chrome/browser/ui/translate:legacy_translate",
"//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util",
"//ios/chrome/browser/ui/util:multiwindow_util",
"//ios/chrome/browser/ui/voice", "//ios/chrome/browser/ui/voice",
"//ios/chrome/browser/upgrade", "//ios/chrome/browser/upgrade",
"//ios/chrome/browser/url_loading", "//ios/chrome/browser/url_loading",
......
...@@ -141,6 +141,7 @@ ...@@ -141,6 +141,7 @@
#import "ios/chrome/browser/ui/toolbar_container/toolbar_container_features.h" #import "ios/chrome/browser/ui/toolbar_container/toolbar_container_features.h"
#include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/ui_feature_flags.h"
#import "ios/chrome/browser/ui/util/keyboard_observer_helper.h" #import "ios/chrome/browser/ui/util/keyboard_observer_helper.h"
#import "ios/chrome/browser/ui/util/multi_window_support.h"
#import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/chrome/browser/ui/util/named_guide.h"
#import "ios/chrome/browser/ui/util/named_guide_util.h" #import "ios/chrome/browser/ui/util/named_guide_util.h"
#import "ios/chrome/browser/ui/util/page_animation_util.h" #import "ios/chrome/browser/ui/util/page_animation_util.h"
...@@ -929,6 +930,12 @@ NSString* const kBrowserViewControllerSnackbarCategory = ...@@ -929,6 +930,12 @@ NSString* const kBrowserViewControllerSnackbarCategory =
if (_broadcasting == broadcasting) if (_broadcasting == broadcasting)
return; return;
_broadcasting = broadcasting; _broadcasting = broadcasting;
if (IsMultiwindowSupported()) {
// TODO(crbug.com/1060653): fix fullscreen.
return;
}
// TODO(crbug.com/790886): Use the Browser's broadcaster once Browsers are // TODO(crbug.com/790886): Use the Browser's broadcaster once Browsers are
// supported. // supported.
FullscreenController* fullscreenController = FullscreenController* fullscreenController =
......
...@@ -195,15 +195,14 @@ const NSTimeInterval kDisplayPromoDelay = 0.1; ...@@ -195,15 +195,14 @@ const NSTimeInterval kDisplayPromoDelay = 0.1;
[_sceneState addObserver:self]; [_sceneState addObserver:self];
// The window is necessary very early in the app/scene lifecycle, so it // The window is necessary very early in the app/scene lifecycle, so it
// should be created right away. // should be created right away.
if (!self.sceneState.window) { // When multiwindow is supported, the window is created by SceneDelegate,
DCHECK(!IsMultiwindowSupported()) // and fetched by SceneState from UIScene's windows.
<< "The window must be created by the scene delegate"; if (!IsMultiwindowSupported() && !self.sceneState.window) {
self.sceneState.window = [[ChromeOverlayWindow alloc] self.sceneState.window = [[ChromeOverlayWindow alloc]
initWithFrame:[[UIScreen mainScreen] bounds]]; initWithFrame:[[UIScreen mainScreen] bounds]];
_appURLLoadingService = new AppUrlLoadingService();
_appURLLoadingService->SetDelegate(self);
} }
_appURLLoadingService = new AppUrlLoadingService();
_appURLLoadingService->SetDelegate(self);
} }
return self; return self;
} }
...@@ -260,6 +259,13 @@ const NSTimeInterval kDisplayPromoDelay = 0.1; ...@@ -260,6 +259,13 @@ const NSTimeInterval kDisplayPromoDelay = 0.1;
return; return;
} }
DCHECK(self.mainController);
if (IsMultiwindowSupported()) {
// TODO(crbug.com/1012697): This should probably be the only code path for
// multiwindow and non-multiwindow cases.
[self startUpChromeUIPostCrash:NO needRestoration:NO];
}
self.hasInitializedUI = YES; self.hasInitializedUI = YES;
} }
...@@ -270,6 +276,8 @@ const NSTimeInterval kDisplayPromoDelay = 0.1; ...@@ -270,6 +276,8 @@ const NSTimeInterval kDisplayPromoDelay = 0.1;
needRestoration:(BOOL)needsRestoration { needRestoration:(BOOL)needsRestoration {
DCHECK(!self.browserViewWrangler); DCHECK(!self.browserViewWrangler);
DCHECK(self.appURLLoadingService); DCHECK(self.appURLLoadingService);
DCHECK(self.mainController);
DCHECK(self.mainController.mainBrowserState);
self.browserViewWrangler = [[BrowserViewWrangler alloc] self.browserViewWrangler = [[BrowserViewWrangler alloc]
initWithBrowserState:self.mainController.mainBrowserState initWithBrowserState:self.mainController.mainBrowserState
...@@ -337,7 +345,7 @@ const NSTimeInterval kDisplayPromoDelay = 0.1; ...@@ -337,7 +345,7 @@ const NSTimeInterval kDisplayPromoDelay = 0.1;
TabModel* otrTabModel = self.incognitoInterface.tabModel; TabModel* otrTabModel = self.incognitoInterface.tabModel;
// Enables UI initializations to query the keyWindow's size. // Enables UI initializations to query the keyWindow's size.
[self.mainController.window makeKeyAndVisible]; [self.sceneState.window makeKeyAndVisible];
// Lazy init of mainCoordinator. // Lazy init of mainCoordinator.
[self.mainCoordinator start]; [self.mainCoordinator start];
......
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