[go: nahoru, domu]

blob: 9969acb212f51183bfec2ba723ed49d93104f014 [file] [log] [blame]
// Copyright 2018 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/google_services/google_services_settings_coordinator.h"
#import "base/apple/foundation_util.h"
#import "components/google/core/common/google_util.h"
#import "components/signin/public/identity_manager/identity_manager.h"
#import "components/strings/grit/components_strings.h"
#import "components/sync/service/sync_service_utils.h"
#import "ios/chrome/browser/shared/coordinator/alert/action_sheet_coordinator.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/model/url/chrome_url_constants.h"
#import "ios/chrome/browser/shared/public/commands/application_commands.h"
#import "ios/chrome/browser/shared/public/commands/browsing_data_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/commands/show_signin_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.h"
#import "ios/chrome/browser/signin/authentication_service_factory.h"
#import "ios/chrome/browser/signin/identity_manager_factory.h"
#import "ios/chrome/browser/sync/sync_service_factory.h"
#import "ios/chrome/browser/sync/sync_setup_service.h"
#import "ios/chrome/browser/sync/sync_setup_service_factory.h"
#import "ios/chrome/browser/ui/authentication/authentication_flow.h"
#import "ios/chrome/browser/ui/authentication/authentication_ui_util.h"
#import "ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator.h"
#import "ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_command_handler.h"
#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.h"
#import "ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.h"
#import "ios/chrome/grit/ios_strings.h"
#import "ui/base/l10n/l10n_util.h"
using signin_metrics::AccessPoint;
using signin_metrics::PromoAction;
@interface GoogleServicesSettingsCoordinator () <
GoogleServicesSettingsCommandHandler,
GoogleServicesSettingsViewControllerPresentationDelegate,
SignoutActionSheetCoordinatorDelegate>
// Google services settings mediator.
@property(nonatomic, strong) GoogleServicesSettingsMediator* mediator;
// Returns the authentication service.
@property(nonatomic, assign, readonly) AuthenticationService* authService;
// Manages the authentication flow for a given identity.
@property(nonatomic, strong) AuthenticationFlow* authenticationFlow;
// Manages user's Google identities.
@property(nonatomic, assign, readonly) signin::IdentityManager* identityManager;
// View controller presented by this coordinator.
@property(nonatomic, strong, readonly)
GoogleServicesSettingsViewController* googleServicesSettingsViewController;
// Action sheets that provides options for sign out.
@property(nonatomic, strong) ActionSheetCoordinator* signOutCoordinator;
@property(nonatomic, strong)
SignoutActionSheetCoordinator* signoutActionSheetCoordinator;
@end
@implementation GoogleServicesSettingsCoordinator
@synthesize baseNavigationController = _baseNavigationController;
- (instancetype)initWithBaseNavigationController:
(UINavigationController*)navigationController
browser:(Browser*)browser {
self = [super initWithBaseViewController:navigationController
browser:browser];
if (self) {
_baseNavigationController = navigationController;
}
return self;
}
- (void)start {
GoogleServicesSettingsViewController* viewController =
[[GoogleServicesSettingsViewController alloc]
initWithStyle:ChromeTableViewStyle()];
viewController.presentationDelegate = self;
viewController.forcedSigninEnabled =
self.authService->GetServiceStatus() ==
AuthenticationService::ServiceStatus::SigninForcedByPolicy;
self.viewController = viewController;
self.mediator = [[GoogleServicesSettingsMediator alloc]
initWithUserPrefService:self.browser->GetBrowserState()->GetPrefs()
localPrefService:GetApplicationContext()->GetLocalState()];
self.mediator.consumer = viewController;
self.mediator.authService = self.authService;
self.mediator.identityManager = IdentityManagerFactory::GetForBrowserState(
self.browser->GetBrowserState());
self.mediator.commandHandler = self;
viewController.modelDelegate = self.mediator;
viewController.serviceDelegate = self.mediator;
viewController.dispatcher = static_cast<
id<ApplicationCommands, BrowserCommands, BrowsingDataCommands>>(
self.browser->GetCommandDispatcher());
DCHECK(self.baseNavigationController);
[self.baseNavigationController pushViewController:self.viewController
animated:YES];
}
- (void)stop {
[self.signOutCoordinator stop];
_signOutCoordinator = nil;
}
#pragma mark - Private
- (void)authenticationFlowDidComplete {
DCHECK(self.authenticationFlow);
self.authenticationFlow = nil;
[self.googleServicesSettingsViewController allowUserInteraction];
}
#pragma mark - Properties
- (AuthenticationService*)authService {
return AuthenticationServiceFactory::GetForBrowserState(
self.browser->GetBrowserState());
}
- (GoogleServicesSettingsViewController*)googleServicesSettingsViewController {
return base::apple::ObjCCast<GoogleServicesSettingsViewController>(
self.viewController);
}
- (signin::IdentityManager*)identityManager {
return IdentityManagerFactory::GetForBrowserState(
self.browser->GetBrowserState());
}
#pragma mark - GoogleServicesSettingsCommandHandler
- (void)showSignOutFromTargetRect:(CGRect)targetRect
completion:(signin_ui::CompletionCallback)completion {
DCHECK(completion);
SyncSetupService* syncSetupService =
SyncSetupServiceFactory::GetForBrowserState(
self.browser->GetBrowserState());
BOOL isSyncConsentGiven =
syncSetupService && syncSetupService->IsInitialSyncFeatureSetupComplete();
self.signOutCoordinator = [[ActionSheetCoordinator alloc]
initWithBaseViewController:self.viewController
browser:self.browser
title:nil
message:nil
rect:targetRect
view:self.viewController.view];
// Because setting `title` to nil automatically forces the title-style text on
// `message` in the UIAlertController, the attributed message below
// specifically denotes the font style to apply.
if (isSyncConsentGiven) {
self.signOutCoordinator.attributedMessage = [[NSAttributedString alloc]
initWithString:l10n_util::GetNSString(
IDS_IOS_SIGNOUT_DIALOG_MESSAGE_WITH_SYNC)
attributes:@{
NSFontAttributeName :
[UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]
}];
[self.signOutCoordinator updateAttributedText];
}
__weak GoogleServicesSettingsCoordinator* weakSelf = self;
[self.signOutCoordinator
addItemWithTitle:l10n_util::GetNSString(
IDS_IOS_SIGNOUT_DIALOG_SIGN_OUT_BUTTON)
action:^{
if (!weakSelf) {
return;
}
// Provide additional data retention options if the user is
// syncing their data.
// TODO(crbug.com/1462552): Simplify once kSync becomes
// unreachable or is deleted from the codebase. See
// ConsentLevel::kSync documentation for details.
if (weakSelf.identityManager->HasPrimaryAccount(
signin::ConsentLevel::kSync)) {
[weakSelf
showDataRetentionOptionsWithTargetRect:targetRect
completion:completion];
return;
}
[weakSelf signOutWithCompletion:completion];
}
style:UIAlertActionStyleDestructive];
[self.signOutCoordinator
addItemWithTitle:l10n_util::GetNSString(IDS_CANCEL)
action:^{
weakSelf.signOutCoordinator = nil;
completion(NO);
}
style:UIAlertActionStyleCancel];
[self.signOutCoordinator start];
}
// Displays the option to keep or clear data for a syncing user.
- (void)showDataRetentionOptionsWithTargetRect:(CGRect)targetRect
completion:(signin_ui::CompletionCallback)
completion {
DCHECK(completion);
self.signoutActionSheetCoordinator = [[SignoutActionSheetCoordinator alloc]
initWithBaseViewController:self.viewController
browser:self.browser
rect:targetRect
view:self.viewController.view
withSource:signin_metrics::ProfileSignout::
kUserClickedSignoutSettings];
__weak GoogleServicesSettingsCoordinator* weakSelf = self;
self.signoutActionSheetCoordinator.delegate = self;
self.signoutActionSheetCoordinator.completion = ^(BOOL success) {
if (completion)
completion(success);
[weakSelf.signoutActionSheetCoordinator stop];
weakSelf.signoutActionSheetCoordinator = nil;
};
[self.signoutActionSheetCoordinator start];
}
// Signs the user out of Chrome, only clears data for managed accounts.
- (void)signOutWithCompletion:(signin_ui::CompletionCallback)completion {
DCHECK(completion);
[self.googleServicesSettingsViewController preventUserInteraction];
__weak GoogleServicesSettingsCoordinator* weakSelf = self;
self.authService->SignOut(
signin_metrics::ProfileSignout::kUserClickedSignoutSettings,
/*force_clear_browsing_data=*/NO, ^{
if (!weakSelf) {
return;
}
[weakSelf.googleServicesSettingsViewController allowUserInteraction];
completion(YES);
});
}
#pragma mark - GoogleServicesSettingsViewControllerPresentationDelegate
- (void)googleServicesSettingsViewControllerDidRemove:
(GoogleServicesSettingsViewController*)controller {
DCHECK_EQ(self.viewController, controller);
[self.delegate googleServicesSettingsCoordinatorDidRemove:self];
}
#pragma mark - SignoutActionSheetCoordinatorDelegate
- (void)signoutActionSheetCoordinatorPreventUserInteraction:
(SignoutActionSheetCoordinator*)coordinator {
[self.googleServicesSettingsViewController preventUserInteraction];
}
- (void)signoutActionSheetCoordinatorAllowUserInteraction:
(SignoutActionSheetCoordinator*)coordinator {
[self.googleServicesSettingsViewController allowUserInteraction];
}
@end