Commit 8f80402d authored by Stepan Khapugin's avatar Stepan Khapugin Committed by Commit Bot

[multiball] Replace AppDelegate's window with Scene's window.

Adds |window| property to SceneState. It is backed by SceneDelegate's
|window| property and by UIWindowScene's |scenes| property on iOS 13
with multiwindow; or with an ivar otherwise. When it's an ivar,
SceneController is now responsible for window creation.
Note that the getter for AppDelegate's window remains for iOS 12 compat.
Note that the window is always a ChromeOverlayWindow.

have tested it manually on my machine and it still works)

Bug: none
Test: verify that the incognito screenshot blocker works as expected (I
Change-Id: Ic418ece228854e43aa0e4c9d9e503c1b54bca901
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1827373
Commit-Queue: Stepan Khapugin <stkhapugin@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#701569}
parent ae2652f5
...@@ -278,8 +278,10 @@ source_set("app_internal") { ...@@ -278,8 +278,10 @@ source_set("app_internal") {
"MediaPlayer.framework", "MediaPlayer.framework",
] ]
allow_circular_includes_from = allow_circular_includes_from = [
[ "//ios/chrome/app/application_delegate:application_delegate_internal" ] "//ios/chrome/app/application_delegate:application_delegate_internal",
"//ios/chrome/browser/ui/main:scene",
]
} }
source_set("mode") { source_set("mode") {
......
...@@ -92,14 +92,11 @@ ...@@ -92,14 +92,11 @@
} }
- (UIWindow*)window { - (UIWindow*)window {
return [_mainController window]; return self.sceneState.window;
} }
- (void)setWindow:(UIWindow*)newWindow { - (void)setWindow:(UIWindow*)newWindow {
DCHECK(newWindow); NOTREACHED() << "Should not be called, use [SceneState window] instead";
[_mainController setWindow:newWindow];
// self.window has been set by this time. _appState window can now be set.
[_appState setWindow:newWindow];
} }
#pragma mark - UIApplicationDelegate methods - #pragma mark - UIApplicationDelegate methods -
...@@ -113,9 +110,10 @@ ...@@ -113,9 +110,10 @@
- (BOOL)application:(UIApplication*)application - (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
startup_loggers::RegisterAppDidFinishLaunchingTime(); startup_loggers::RegisterAppDidFinishLaunchingTime();
// Main window must be ChromeOverlayWindow or a subclass of it.
self.window = [[ChromeOverlayWindow alloc] _mainController.window = self.window;
initWithFrame:[[UIScreen mainScreen] bounds]]; // self.window has been set by this time. _appState window can now be set.
_appState.window = self.window;
BOOL inBackground = BOOL inBackground =
[application applicationState] == UIApplicationStateBackground; [application applicationState] == UIApplicationStateBackground;
......
...@@ -21,6 +21,7 @@ source_set("scene") { ...@@ -21,6 +21,7 @@ source_set("scene") {
"//ios/chrome/browser/tabs:tabs", "//ios/chrome/browser/tabs:tabs",
"//ios/chrome/browser/ui/commands:commands", "//ios/chrome/browser/ui/commands:commands",
"//ios/chrome/browser/ui/tab_grid", "//ios/chrome/browser/ui/tab_grid",
"//ios/chrome/browser/ui/util:multiwindow_util",
] ]
libs = [ "UIKit.framework" ] libs = [ "UIKit.framework" ]
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
#import "ios/chrome/browser/ui/main/scene_controller.h" #import "ios/chrome/browser/ui/main/scene_controller.h"
#import "base/logging.h"
#import "ios/chrome/app/chrome_overlay_window.h"
#import "ios/chrome/browser/ui/util/multi_window_support.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
...@@ -15,6 +19,14 @@ ...@@ -15,6 +19,14 @@
if (self) { if (self) {
_sceneState = sceneState; _sceneState = sceneState;
[_sceneState addObserver:self]; [_sceneState addObserver:self];
// The window is necessary very early in the app/scene lifecycle, so it
// should be created right away.
if (!self.sceneState.window) {
DCHECK(!IsMultiwindowSupported())
<< "The window must be created by the scene delegate";
self.sceneState.window = [[ChromeOverlayWindow alloc]
initWithFrame:[[UIScreen mainScreen] bounds]];
}
} }
return self; return self;
} }
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
#import "ios/chrome/browser/ui/main/scene_delegate.h" #import "ios/chrome/browser/ui/main/scene_delegate.h"
#include "base/mac/foundation_util.h"
#import "ios/chrome/app/chrome_overlay_window.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
...@@ -18,7 +21,18 @@ ...@@ -18,7 +21,18 @@
return _sceneState; return _sceneState;
} }
#pragma mark - UISceneDelegate #pragma mark - UIWindowSceneDelegate
// This getter is called when the SceneDelegate is created. Returning a
// ChromeOverlayWindow allows UIKit to use that as the main window for this
// scene.
- (UIWindow*)window {
if (!_window) {
// Sizing of the window is handled by UIKit.
_window = [[ChromeOverlayWindow alloc] init];
}
return _window;
}
#pragma mark Connecting and Disconnecting the Scene #pragma mark Connecting and Disconnecting the Scene
...@@ -26,6 +40,7 @@ ...@@ -26,6 +40,7 @@
willConnectToSession:(UISceneSession*)session willConnectToSession:(UISceneSession*)session
options:(UISceneConnectionOptions*)connectionOptions options:(UISceneConnectionOptions*)connectionOptions
API_AVAILABLE(ios(13)) { API_AVAILABLE(ios(13)) {
self.sceneState.scene = base::mac::ObjCCastStrict<UIWindowScene>(scene);
self.sceneState.activationLevel = SceneActivationLevelBackground; self.sceneState.activationLevel = SceneActivationLevelBackground;
} }
......
...@@ -44,7 +44,9 @@ typedef NS_ENUM(NSUInteger, SceneActivationLevel) { ...@@ -44,7 +44,9 @@ typedef NS_ENUM(NSUInteger, SceneActivationLevel) {
@property(nonatomic, assign) SceneActivationLevel activationLevel; @property(nonatomic, assign) SceneActivationLevel activationLevel;
// Window for the associated scene, if any. // Window for the associated scene, if any.
@property(nonatomic, weak) UIWindow* window; @property(nonatomic, strong) UIWindow* window;
@property(nonatomic, strong) UIWindowScene* scene API_AVAILABLE(ios(13));
// Adds an observer to this scene state. The observers will be notified about // Adds an observer to this scene state. The observers will be notified about
// scene state changes per SceneStateObserver protocol. // scene state changes per SceneStateObserver protocol.
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#import "ios/chrome/browser/ui/main/scene_state.h" #import "ios/chrome/browser/ui/main/scene_state.h"
#import "base/ios/crb_protocol_observers.h" #import "base/ios/crb_protocol_observers.h"
#import "ios/chrome/app/chrome_overlay_window.h"
#import "ios/chrome/browser/ui/util/multi_window_support.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
...@@ -26,6 +28,7 @@ ...@@ -26,6 +28,7 @@
@end @end
@implementation SceneState @implementation SceneState
@synthesize window = _window;
- (instancetype)init { - (instancetype)init {
self = [super init]; self = [super init];
...@@ -48,6 +51,30 @@ ...@@ -48,6 +51,30 @@
#pragma mark - Setters & Getters. #pragma mark - Setters & Getters.
- (void)setWindow:(UIWindow*)window {
if (IsMultiwindowSupported()) {
// No need to set anything, instead the getter is backed by scene.windows
// property.
return;
}
_window = window;
}
- (UIWindow*)window {
if (IsMultiwindowSupported()) {
UIWindow* mainWindow = nil;
if (@available(ios 13, *)) {
for (UIWindow* window in self.scene.windows) {
if ([window isKindOfClass:[ChromeOverlayWindow class]]) {
mainWindow = window;
}
}
}
return mainWindow;
}
return _window;
}
- (void)setActivationLevel:(SceneActivationLevel)newLevel { - (void)setActivationLevel:(SceneActivationLevel)newLevel {
if (_activationLevel == newLevel) { if (_activationLevel == newLevel) {
return; return;
......
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