[go: nahoru, domu]

blob: 81102058443ae6e42a9fe3e2726f4db73f10b7da [file] [log] [blame]
// Copyright 2020 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/ui/settings/safety_check/safety_check_coordinator.h"
#import "base/apple/foundation_util.h"
#import "base/memory/scoped_refptr.h"
#import "base/metrics/histogram_functions.h"
#import "base/metrics/histogram_macros.h"
#import "base/metrics/user_metrics.h"
#import "base/strings/sys_string_conversions.h"
#import "components/password_manager/core/common/password_manager_features.h"
#import "components/safe_browsing/core/common/features.h"
#import "ios/chrome/browser/passwords/ios_chrome_password_check_manager.h"
#import "ios/chrome/browser/passwords/ios_chrome_password_check_manager_factory.h"
#import "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
#import "ios/chrome/browser/passwords/password_checkup_utils.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/model/browser/browser.h"
#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/shared/public/commands/application_commands.h"
#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
#import "ios/chrome/browser/shared/public/commands/open_new_tab_command.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h"
#import "ios/chrome/browser/signin/authentication_service_factory.h"
#import "ios/chrome/browser/sync/sync_service_factory.h"
#import "ios/chrome/browser/ui/settings/elements/enterprise_info_popover_view_controller.h"
#import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.h"
#import "ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h"
#import "ios/chrome/browser/ui/settings/privacy/privacy_safe_browsing_coordinator.h"
#import "ios/chrome/browser/ui/settings/safety_check/safety_check_constants.h"
#import "ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.h"
#import "ios/chrome/browser/ui/settings/safety_check/safety_check_navigation_commands.h"
#import "ios/chrome/browser/ui/settings/safety_check/safety_check_ui_swift.h"
#import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
#import "ios/chrome/common/ui/elements/popover_label_view_controller.h"
#import "net/base/mac/url_conversions.h"
#import "url/gurl.h"
using password_manager::WarningType;
@interface SafetyCheckCoordinator () <
PasswordCheckupCoordinatorDelegate,
PasswordIssuesCoordinatorDelegate,
PopoverLabelViewControllerDelegate,
PrivacySafeBrowsingCoordinatorDelegate,
SafetyCheckNavigationCommands,
SafetyCheckTableViewControllerPresentationDelegate>
// Safety check mediator.
@property(nonatomic, strong) SafetyCheckMediator* mediator;
// The container view controller.
@property(nonatomic, strong) SafetyCheckTableViewController* viewController;
// Coordinator for Password Checkup.
@property(nonatomic, strong)
PasswordCheckupCoordinator* passwordCheckupCoordinator;
// Coordinator for passwords issues screen.
@property(nonatomic, strong)
PasswordIssuesCoordinator* passwordIssuesCoordinator;
// Dispatcher which can handle changing passwords on sites.
@property(nonatomic, strong) id<ApplicationCommands> handler;
// Coordinator for the Privacy and Security screen (SafeBrowsing toggle
// location).
@property(nonatomic, strong)
PrivacySafeBrowsingCoordinator* privacySafeBrowsingCoordinator;
// Popover view controller with error information.
@property(nonatomic, strong)
PopoverLabelViewController* errorInfoPopoverViewController;
@end
@implementation SafetyCheckCoordinator
@synthesize baseNavigationController = _baseNavigationController;
- (instancetype)initWithBaseNavigationController:
(UINavigationController*)navigationController
browser:(Browser*)browser {
self = [super initWithBaseViewController:navigationController
browser:browser];
if (self) {
_baseNavigationController = navigationController;
_handler = HandlerForProtocol(self.browser->GetCommandDispatcher(),
ApplicationCommands);
}
return self;
}
- (void)startCheckIfNotRunning {
[self.mediator startCheckIfNotRunning];
}
#pragma mark - ChromeCoordinator
- (void)start {
SafetyCheckTableViewController* viewController =
[[SafetyCheckTableViewController alloc]
initWithStyle:ChromeTableViewStyle()];
self.viewController = viewController;
scoped_refptr<IOSChromePasswordCheckManager> passwordCheckManager =
IOSChromePasswordCheckManagerFactory::GetForBrowserState(
self.browser->GetBrowserState());
self.mediator = [[SafetyCheckMediator alloc]
initWithUserPrefService:self.browser->GetBrowserState()->GetPrefs()
passwordCheckManager:passwordCheckManager
authService:AuthenticationServiceFactory::GetForBrowserState(
self.browser->GetBrowserState())
syncService:SyncServiceFactory::GetForBrowserState(
self.browser->GetBrowserState())];
self.mediator.consumer = self.viewController;
self.mediator.handler = self;
self.viewController.serviceDelegate = self.mediator;
self.viewController.presentationDelegate = self;
DCHECK(self.baseNavigationController);
[self.baseNavigationController pushViewController:self.viewController
animated:YES];
}
- (void)stop {
// If the Safe Browsing Settings page was accessed through the Safe
// Browsing row of the safety check, we need to explicity stop the
// privacySafeBrowsingCoordinator before closing the settings window.
[self.privacySafeBrowsingCoordinator stop];
self.privacySafeBrowsingCoordinator.delegate = nil;
self.privacySafeBrowsingCoordinator = nil;
[self.passwordCheckupCoordinator stop];
self.passwordCheckupCoordinator.delegate = nil;
self.passwordCheckupCoordinator = nil;
}
#pragma mark - SafetyCheckTableViewControllerPresentationDelegate
- (void)safetyCheckTableViewControllerDidRemove:
(SafetyCheckTableViewController*)controller {
DCHECK_EQ(self.viewController, controller);
[self.delegate safetyCheckCoordinatorDidRemove:self];
}
#pragma mark - PopoverLabelViewControllerDelegate
- (void)didTapLinkURL:(NSURL*)URL {
GURL convertedURL = net::GURLWithNSURL(URL);
const GURL safeBrowsingURL(
base::SysNSStringToUTF8(kSafeBrowsingSafetyCheckStringURL));
// Take the user to Sync and Google Services page in Bling instead of desktop
// settings.
if (convertedURL == safeBrowsingURL) {
[self.errorInfoPopoverViewController
dismissViewControllerAnimated:YES
completion:^{
[self showSafeBrowsingPreferencePage];
}];
return;
}
OpenNewTabCommand* command =
[OpenNewTabCommand commandWithURLFromChrome:convertedURL];
[self.handler closeSettingsUIAndOpenURL:command];
}
#pragma mark - SafetyCheckNavigationCommands
// TODO(crbug.com/1464966): Make sure there aren't mutiple active
// `passwordCheckupCoordinator`s at once.
- (void)showPasswordCheckupPage {
CHECK(password_manager::features::IsPasswordCheckupEnabled());
self.passwordCheckupCoordinator = [[PasswordCheckupCoordinator alloc]
initWithBaseNavigationController:self.baseNavigationController
browser:self.browser
reauthModule:nil
referrer:password_manager::PasswordCheckReferrer::
kSafetyCheck];
self.passwordCheckupCoordinator.delegate = self;
[self.passwordCheckupCoordinator start];
}
- (void)showPasswordIssuesPage {
CHECK(!password_manager::features::IsPasswordCheckupEnabled());
CHECK(!self.passwordIssuesCoordinator);
self.passwordIssuesCoordinator = [[PasswordIssuesCoordinator alloc]
initForWarningType:WarningType::kCompromisedPasswordsWarning
baseNavigationController:self.baseNavigationController
browser:self.browser];
self.passwordIssuesCoordinator.delegate = self;
self.passwordIssuesCoordinator.reauthModule = nil;
[self.passwordIssuesCoordinator start];
}
- (void)showErrorInfoFrom:(UIButton*)buttonView
withText:(NSAttributedString*)text {
self.errorInfoPopoverViewController =
[[PopoverLabelViewController alloc] initWithPrimaryAttributedString:text
secondaryAttributedString:nil];
self.errorInfoPopoverViewController.delegate = self;
self.errorInfoPopoverViewController.popoverPresentationController.sourceView =
buttonView;
self.errorInfoPopoverViewController.popoverPresentationController.sourceRect =
buttonView.bounds;
self.errorInfoPopoverViewController.popoverPresentationController
.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self.viewController presentViewController:self.errorInfoPopoverViewController
animated:YES
completion:nil];
}
- (void)showUpdateAtLocation:(NSString*)location {
if (!location) {
NOTREACHED();
return;
}
const GURL url(base::SysNSStringToUTF8(location));
OpenNewTabCommand* command = [OpenNewTabCommand commandWithURLFromChrome:url];
[self.handler closeSettingsUIAndOpenURL:command];
}
- (void)showSafeBrowsingPreferencePage {
DCHECK(!self.privacySafeBrowsingCoordinator);
base::RecordAction(
base::UserMetricsAction("Settings.SafetyCheck.ManageSafeBrowsing"));
base::UmaHistogramEnumeration("Settings.SafetyCheck.Interactions",
SafetyCheckInteractions::kSafeBrowsingManage);
self.privacySafeBrowsingCoordinator = [[PrivacySafeBrowsingCoordinator alloc]
initWithBaseNavigationController:self.baseNavigationController
browser:self.browser];
self.privacySafeBrowsingCoordinator.delegate = self;
[self.privacySafeBrowsingCoordinator start];
}
- (void)showManagedInfoFrom:(UIButton*)buttonView {
EnterpriseInfoPopoverViewController* bubbleViewController =
[[EnterpriseInfoPopoverViewController alloc] initWithEnterpriseName:nil];
[self.viewController presentViewController:bubbleViewController
animated:YES
completion:nil];
// Disable the button when showing the bubble.
// The button will be enabled when close the bubble in
// (void)popoverPresentationControllerDidDismissPopover: of
// EnterpriseInfoPopoverViewController.
buttonView.enabled = NO;
// Set the anchor and arrow direction of the bubble.
bubbleViewController.popoverPresentationController.sourceView = buttonView;
bubbleViewController.popoverPresentationController.sourceRect =
buttonView.bounds;
bubbleViewController.popoverPresentationController.permittedArrowDirections =
UIPopoverArrowDirectionAny;
}
#pragma mark - PasswordCheckupCoordinatorDelegate
- (void)passwordCheckupCoordinatorDidRemove:
(PasswordCheckupCoordinator*)coordinator {
DCHECK_EQ(self.passwordCheckupCoordinator, coordinator);
[self.passwordCheckupCoordinator stop];
self.passwordCheckupCoordinator.delegate = nil;
self.passwordCheckupCoordinator = nil;
}
// TODO(crbug.com/1406871): Remove when kIOSPasswordCheckup is enabled by
// default.
#pragma mark - PasswordIssuesCoordinatorDelegate
- (void)passwordIssuesCoordinatorDidRemove:
(PasswordIssuesCoordinator*)coordinator {
DCHECK_EQ(self.passwordIssuesCoordinator, coordinator);
[self.passwordIssuesCoordinator stop];
self.passwordIssuesCoordinator.delegate = nil;
self.passwordIssuesCoordinator = nil;
}
#pragma mark - PrivacySafeBrowsingCoordinatorDelegate
- (void)privacySafeBrowsingCoordinatorDidRemove:
(PrivacySafeBrowsingCoordinator*)coordinator {
DCHECK_EQ(_privacySafeBrowsingCoordinator, coordinator);
[self.privacySafeBrowsingCoordinator stop];
self.privacySafeBrowsingCoordinator.delegate = nil;
self.privacySafeBrowsingCoordinator = nil;
}
@end