chromium/ios/chrome/browser/safe_mode/ui_bundled/safe_mode_coordinator.mm

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "ios/chrome/browser/safe_mode/ui_bundled/safe_mode_coordinator.h"

#import <ostream>

#import "base/notreached.h"
#import "ios/chrome/browser/crash_report/model/crash_loop_detection_util.h"
#import "ios/chrome/browser/safe_mode/ui_bundled/safe_mode_view_controller.h"

namespace {
const int kStartupCrashLoopThreshold = 3;
}

@interface SafeModeCoordinator ()<SafeModeViewControllerDelegate>
@property(weak, nonatomic, readonly) UIWindow* window;
@end

@implementation SafeModeCoordinator

@synthesize delegate = _delegate;

#pragma mark - Public class methods

- (instancetype)initWithWindow:(UIWindow*)window {
  if ((self = [super initWithBaseViewController:nil browser:nullptr])) {
    _window = window;
  }
  return self;
}

+ (BOOL)shouldStart {
  // Check whether there appears to be a startup crash loop. If not, don't look
  // at anything else.
  if (crash_util::GetFailedStartupAttemptCount() < kStartupCrashLoopThreshold)
    return NO;

  return [SafeModeViewController hasSuggestions];
}

#pragma mark - ChromeCoordinator implementation

- (void)start {
  // Create the SafeModeViewController and make it the root view controller for
  // the window. The window has ownership of it and will dispose of it when
  // another view controller is made root.
  //
  // General note: Safe mode should be safe; it should not depend on other
  // objects being created. Be extremely conservative when adding code to this
  // method.
  SafeModeViewController* viewController =
      [[SafeModeViewController alloc] initWithDelegate:self];
  DCHECK(self.window);
  [self.window setRootViewController:viewController];

  // Reset the crash count; the user may change something based on the recovery
  // UI that will fix the crash, and having the next launch start in recovery
  // mode would be strange.
  crash_util::ResetFailedStartupAttemptCount();
}

// Override of ChildCoordinators method, which is not supported in this class.
- (MutableCoordinatorArray*)childCoordinators {
  NOTREACHED_IN_MIGRATION()
      << "Do not add child coordinators to SafeModeCoordinator.";
  return nil;
}

#pragma mark - SafeModeViewControllerDelegate implementation

- (void)startBrowserFromSafeMode {
  [self.delegate coordinatorDidExitSafeMode:self];
}

@end