| Index: ios/chrome/app/main_application_delegate.mm | 
| diff --git a/ios/chrome/app/main_application_delegate.mm b/ios/chrome/app/main_application_delegate.mm | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..9d3c911cc459f096c6ac15982186554febfdf550 | 
| --- /dev/null | 
| +++ b/ios/chrome/app/main_application_delegate.mm | 
| @@ -0,0 +1,274 @@ | 
| +// Copyright 2016 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#import "ios/chrome/app/main_application_delegate.h" | 
| + | 
| +#include "base/mac/foundation_util.h" | 
| +#import "base/mac/scoped_nsobject.h" | 
| +#import "ios/chrome/app/application_delegate/app_navigation.h" | 
| +#import "ios/chrome/app/application_delegate/app_state.h" | 
| +#import "ios/chrome/app/application_delegate/background_activity.h" | 
| +#import "ios/chrome/app/application_delegate/browser_launcher.h" | 
| +#import "ios/chrome/app/application_delegate/memory_warning_helper.h" | 
| +#import "ios/chrome/app/application_delegate/metrics_mediator.h" | 
| +#import "ios/chrome/app/application_delegate/startup_information.h" | 
| +#import "ios/chrome/app/application_delegate/tab_opening.h" | 
| +#import "ios/chrome/app/application_delegate/tab_switching.h" | 
| +#import "ios/chrome/app/application_delegate/url_opener.h" | 
| +#import "ios/chrome/app/application_delegate/user_activity_handler.h" | 
| +#import "ios/chrome/app/chrome_overlay_window.h" | 
| +#import "ios/chrome/app/main_application_delegate_testing.h" | 
| +#import "ios/chrome/app/main_controller.h" | 
| +#include "ios/public/provider/chrome/browser/chrome_browser_provider.h" | 
| +#include "ios/public/provider/chrome/browser/signin/chrome_identity_service.h" | 
| + | 
| +@interface MainApplicationDelegate () { | 
| +  base::scoped_nsobject<MainController> _mainController; | 
| +  // Memory helper used to log the number of memory warnings received. | 
| +  base::scoped_nsobject<MemoryWarningHelper> _memoryHelper; | 
| +  // Metrics mediator used to check and update the metrics accordingly to | 
| +  // to the user preferences. | 
| +  base::scoped_nsobject<MetricsMediator> _metricsMediator; | 
| +  // Browser launcher to have a global launcher. | 
| +  base::scoped_nsprotocol<id<BrowserLauncher>> _browserLauncher; | 
| +  // Container for startup information. | 
| +  base::scoped_nsprotocol<id<StartupInformation>> _startupInformation; | 
| +  // Helper to open new tabs. | 
| +  base::scoped_nsprotocol<id<TabOpening>> _tabOpener; | 
| +  // Handles the application stage changes. | 
| +  base::scoped_nsobject<AppState> _appState; | 
| +  // Handles tab switcher. | 
| +  base::scoped_nsprotocol<id<AppNavigation>> _appNavigation; | 
| +  // Handles tab switcher. | 
| +  base::scoped_nsprotocol<id<TabSwitching>> _tabSwitcherProtocol; | 
| +} | 
| + | 
| +@end | 
| + | 
| +@implementation MainApplicationDelegate | 
| + | 
| +- (instancetype)init { | 
| +  if (self = [super init]) { | 
| +    _memoryHelper.reset([[MemoryWarningHelper alloc] init]); | 
| +    _mainController.reset([[MainController alloc] init]); | 
| +    _metricsMediator.reset([[MetricsMediator alloc] init]); | 
| +    [_mainController setMetricsMediator:_metricsMediator]; | 
| +    _browserLauncher.reset([_mainController retain]); | 
| +    _startupInformation.reset([_mainController retain]); | 
| +    _tabOpener.reset([_mainController retain]); | 
| +    _appState.reset([[AppState alloc] | 
| +        initWithBrowserLauncher:_browserLauncher | 
| +             startupInformation:_startupInformation | 
| +            applicationDelegate:self]); | 
| +    _tabSwitcherProtocol.reset([_mainController retain]); | 
| +    _appNavigation.reset([_mainController retain]); | 
| +    [_mainController setAppState:_appState]; | 
| +  } | 
| +  return self; | 
| +} | 
| + | 
| +- (UIWindow*)window { | 
| +  return [_mainController window]; | 
| +} | 
| + | 
| +- (void)setWindow:(UIWindow*)newWindow { | 
| +  DCHECK(newWindow); | 
| +  [_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 Responding to App State Changes and System Events | 
| + | 
| +// Called by the OS to create the UI for display.  The UI will not be displayed, | 
| +// even if it is ready, until this function returns. | 
| +// The absolute minimum work should be done here, to ensure that the application | 
| +// startup is fast, and the UI appears as soon as possible. | 
| +- (BOOL)application:(UIApplication*)application | 
| +    didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { | 
| +  // Main window must be ChromeOverlayWindow or a subclass of it. | 
| +  self.window = [[[ChromeOverlayWindow alloc] | 
| +      initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; | 
| + | 
| +  BOOL inBackground = | 
| +      [application applicationState] == UIApplicationStateBackground; | 
| +  return [_appState requiresHandlingAfterLaunchWithOptions:launchOptions | 
| +                                           stateBackground:inBackground]; | 
| +} | 
| + | 
| +- (void)applicationDidBecomeActive:(UIApplication*)application { | 
| +  if ([_appState isInSafeMode]) | 
| +    return; | 
| + | 
| +  [_appState resumeSessionWithTabOpener:_tabOpener | 
| +                            tabSwitcher:_tabSwitcherProtocol]; | 
| +} | 
| + | 
| +- (void)applicationWillResignActive:(UIApplication*)application { | 
| +  if ([_appState isInSafeMode]) | 
| +    return; | 
| + | 
| +  [_appState willResignActiveTabModel]; | 
| +} | 
| + | 
| +// Called when going into the background. iOS already broadcasts, so | 
| +// stakeholders can register for it directly. | 
| +- (void)applicationDidEnterBackground:(UIApplication*)application { | 
| +  [_appState | 
| +      applicationDidEnterBackground:application | 
| +                       memoryHelper:_memoryHelper | 
| +                tabSwitcherIsActive:[_mainController isTabSwitcherActive]]; | 
| +} | 
| + | 
| +// Called when returning to the foreground. | 
| +- (void)applicationWillEnterForeground:(UIApplication*)application { | 
| +  [_appState applicationWillEnterForeground:application | 
| +                            metricsMediator:_metricsMediator | 
| +                               memoryHelper:_memoryHelper | 
| +                                  tabOpener:_tabOpener | 
| +                              appNavigation:_appNavigation]; | 
| +} | 
| + | 
| +- (void)applicationWillTerminate:(UIApplication*)application { | 
| +  if ([_appState isInSafeMode]) | 
| +    return; | 
| + | 
| +  // Instead of adding code here, consider if it could be handled by listening | 
| +  // for  UIApplicationWillterminate. | 
| +  [_appState applicationWillTerminate:application | 
| +                applicationNavigation:_appNavigation]; | 
| +} | 
| + | 
| +- (void)applicationDidReceiveMemoryWarning:(UIApplication*)application { | 
| +  if ([_appState isInSafeMode]) | 
| +    return; | 
| + | 
| +  [_memoryHelper handleMemoryPressure]; | 
| +} | 
| + | 
| +#pragma mark Downloading Data in the Background | 
| + | 
| +- (void)application:(UIApplication*)application | 
| +    performFetchWithCompletionHandler: | 
| +        (void (^)(UIBackgroundFetchResult))completionHandler { | 
| +  if ([_appState isInSafeMode]) | 
| +    return; | 
| + | 
| +  if ([application applicationState] != UIApplicationStateBackground) { | 
| +    // If this handler is called in foreground, it means it has to be activated. | 
| +    // Returning |UIBackgroundFetchResultNewData| means that the handler will be | 
| +    // called again in case of a crash. | 
| +    completionHandler(UIBackgroundFetchResultNewData); | 
| +    return; | 
| +  } | 
| + | 
| +  [BackgroundActivity application:application | 
| +      performFetchWithCompletionHandler:completionHandler | 
| +                        metricsMediator:_metricsMediator | 
| +                        browserLauncher:_browserLauncher]; | 
| +} | 
| + | 
| +- (void)application:(UIApplication*)application | 
| +    handleEventsForBackgroundURLSession:(NSString*)identifier | 
| +                      completionHandler:(void (^)(void))completionHandler { | 
| +  if ([_appState isInSafeMode]) | 
| +    return; | 
| + | 
| +  [BackgroundActivity handleEventsForBackgroundURLSession:identifier | 
| +                                        completionHandler:completionHandler | 
| +                                          browserLauncher:_browserLauncher]; | 
| +} | 
| + | 
| +#pragma mark Continuing User Activity and Handling Quick Actions | 
| + | 
| +- (BOOL)application:(UIApplication*)application | 
| +    willContinueUserActivityWithType:(NSString*)userActivityType { | 
| +  if ([_appState isInSafeMode]) | 
| +    return NO; | 
| + | 
| +  return | 
| +      [UserActivityHandler willContinueUserActivityWithType:userActivityType]; | 
| +} | 
| + | 
| +- (BOOL)application:(UIApplication*)application | 
| +    continueUserActivity:(NSUserActivity*)userActivity | 
| +      restorationHandler:(void (^)(NSArray*))restorationHandler { | 
| +  if ([_appState isInSafeMode]) | 
| +    return NO; | 
| + | 
| +  BOOL applicationIsActive = | 
| +      [application applicationState] == UIApplicationStateActive; | 
| + | 
| +  return [UserActivityHandler continueUserActivity:userActivity | 
| +                               applicationIsActive:applicationIsActive | 
| +                                         tabOpener:_tabOpener | 
| +                                startupInformation:_startupInformation]; | 
| +} | 
| + | 
| +- (void)application:(UIApplication*)application | 
| +    performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem | 
| +               completionHandler:(void (^)(BOOL succeeded))completionHandler { | 
| +  if ([_appState isInSafeMode]) | 
| +    return; | 
| + | 
| +  [UserActivityHandler | 
| +      performActionForShortcutItem:shortcutItem | 
| +                 completionHandler:completionHandler | 
| +                         tabOpener:_tabOpener | 
| +                startupInformation:_startupInformation | 
| +            browserViewInformation:[_mainController browserViewInformation]]; | 
| +} | 
| + | 
| +#pragma mark Opening a URL-Specified Resource | 
| + | 
| +// Handles open URL. The registered URL Schemes are defined in project | 
| +// variables ${CHROMIUM_URL_SCHEME_x}. | 
| +// The url can either be empty, in which case the app is simply opened or | 
| +// can contain an URL that will be opened in a new tab. | 
| +- (BOOL)application:(UIApplication*)application | 
| +            openURL:(NSURL*)url | 
| +            options:(NSDictionary<NSString*, id>*)options { | 
| +  if ([_appState isInSafeMode]) | 
| +    return NO; | 
| + | 
| +  if (ios::GetChromeBrowserProvider() | 
| +          ->GetChromeIdentityService() | 
| +          ->HandleApplicationOpenURL(application, url, options)) { | 
| +    return YES; | 
| +  } | 
| + | 
| +  BOOL applicationActive = | 
| +      [application applicationState] == UIApplicationStateActive; | 
| +  return [URLOpener openURL:url | 
| +          applicationActive:applicationActive | 
| +                    options:options | 
| +                  tabOpener:_tabOpener | 
| +         startupInformation:_startupInformation]; | 
| +} | 
| + | 
| +#pragma mark - chromeExecuteCommand | 
| + | 
| +- (void)chromeExecuteCommand:(id)sender { | 
| +  [_mainController chromeExecuteCommand:sender]; | 
| +} | 
| + | 
| +#pragma mark - Testing methods | 
| + | 
| +- (MainController*)mainController { | 
| +  return _mainController; | 
| +} | 
| + | 
| +- (AppState*)appState { | 
| +  return _appState; | 
| +} | 
| + | 
| ++ (MainController*)sharedMainController { | 
| +  return base::mac::ObjCCast<MainApplicationDelegate>( | 
| +             [[UIApplication sharedApplication] delegate]) | 
| +      .mainController; | 
| +} | 
| + | 
| +@end | 
|  |