[go: nahoru, domu]

blob: 4d7385dc4c5a3e316e976264f144e8b7c5e8a597 [file] [log] [blame]
// Copyright 2022 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/first_run/signin/signin_screen_coordinator.h"
#import "base/apple/foundation_util.h"
#import "base/strings/sys_string_conversions.h"
#import "ios/chrome/browser/first_run/first_run_metrics.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/browsing_data_commands.h"
#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
#import "ios/chrome/browser/shared/public/commands/tos_commands.h"
#import "ios/chrome/browser/signin/authentication_service.h"
#import "ios/chrome/browser/signin/authentication_service_factory.h"
#import "ios/chrome/browser/signin/chrome_account_manager_service.h"
#import "ios/chrome/browser/signin/chrome_account_manager_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/ui/authentication/authentication_flow.h"
#import "ios/chrome/browser/ui/authentication/signin/signin_coordinator.h"
#import "ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_coordinator.h"
#import "ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_coordinator_delegate.h"
#import "ios/chrome/browser/ui/first_run/first_run_constants.h"
#import "ios/chrome/browser/ui/first_run/first_run_screen_delegate.h"
#import "ios/chrome/browser/ui/first_run/first_run_util.h"
#import "ios/chrome/browser/ui/first_run/signin/signin_screen_consumer.h"
#import "ios/chrome/browser/ui/first_run/signin/signin_screen_mediator.h"
#import "ios/chrome/browser/ui/first_run/signin/signin_screen_view_controller.h"
#import "ios/chrome/browser/ui/first_run/tos/tos_coordinator.h"
#import "ios/chrome/browser/ui/first_run/uma/uma_coordinator.h"
@interface SigninScreenCoordinator () <IdentityChooserCoordinatorDelegate,
SigninScreenViewControllerDelegate,
TOSCommands,
UMACoordinatorDelegate>
// First run screen delegate.
@property(nonatomic, weak) id<FirstRunScreenDelegate> delegate;
// Sign-in screen view controller.
@property(nonatomic, strong) SigninScreenViewController* viewController;
// Sign-in screen mediator.
@property(nonatomic, strong) SigninScreenMediator* mediator;
// Account manager service.
@property(nonatomic, assign) ChromeAccountManagerService* accountManagerService;
// Authentication service.
@property(nonatomic, assign) AuthenticationService* authenticationService;
// Coordinator used to manage the TOS page.
@property(nonatomic, strong) TOSCoordinator* TOSCoordinator;
// Coordinator to show the metric reportingn dialog.
@property(nonatomic, strong) UMACoordinator* UMACoordinator;
// Coordinator to choose an identity.
@property(nonatomic, strong)
IdentityChooserCoordinator* identityChooserCoordinator;
// Coordinator to add an identity.
@property(nonatomic, strong) SigninCoordinator* addAccountSigninCoordinator;
@property(nonatomic, assign) BOOL UMAReportingUserChoice;
@end
@implementation SigninScreenCoordinator {
signin_metrics::AccessPoint _accessPoint;
signin_metrics::PromoAction _promoAction;
}
@synthesize baseNavigationController = _baseNavigationController;
- (instancetype)
initWithBaseNavigationController:
(UINavigationController*)navigationController
browser:(Browser*)browser
delegate:(id<FirstRunScreenDelegate>)delegate
accessPoint:(signin_metrics::AccessPoint)accessPoint
promoAction:(signin_metrics::PromoAction)promoAction {
self = [super initWithBaseViewController:navigationController
browser:browser];
if (self) {
DCHECK(!browser->GetBrowserState()->IsOffTheRecord());
_baseNavigationController = navigationController;
_delegate = delegate;
_UMAReportingUserChoice = kDefaultMetricsReportingCheckboxValue;
_accessPoint = accessPoint;
_promoAction = promoAction;
}
return self;
}
- (void)start {
[self.browser->GetCommandDispatcher()
startDispatchingToTarget:self
forProtocol:@protocol(TOSCommands)];
id<TOSCommands> TOSHandler =
HandlerForProtocol(self.browser->GetCommandDispatcher(), TOSCommands);
self.viewController = [[SigninScreenViewController alloc] init];
self.viewController.TOSHandler = TOSHandler;
self.viewController.delegate = self;
ChromeBrowserState* browserState = self.browser->GetBrowserState();
self.authenticationService =
AuthenticationServiceFactory::GetForBrowserState(browserState);
self.accountManagerService =
ChromeAccountManagerServiceFactory::GetForBrowserState(browserState);
signin::IdentityManager* identityManager =
IdentityManagerFactory::GetForBrowserState(
self.browser->GetBrowserState());
PrefService* localPrefService = GetApplicationContext()->GetLocalState();
PrefService* prefService = browserState->GetPrefs();
syncer::SyncService* syncService =
SyncServiceFactory::GetForBrowserState(browserState);
self.mediator = [[SigninScreenMediator alloc]
initWithAccountManagerService:self.accountManagerService
authenticationService:self.authenticationService
identityManager:identityManager
localPrefService:localPrefService
prefService:prefService
syncService:syncService
accessPoint:_accessPoint
promoAction:_promoAction];
self.mediator.consumer = self.viewController;
if (self.mediator.ignoreDismissGesture) {
self.viewController.modalInPresentation = YES;
}
BOOL animated = self.baseNavigationController.topViewController != nil;
[self.baseNavigationController setViewControllers:@[ self.viewController ]
animated:animated];
}
- (void)stop {
[self.identityChooserCoordinator stop];
self.delegate = nil;
self.viewController = nil;
[self.mediator disconnect];
self.mediator = nil;
self.accountManagerService = nil;
self.authenticationService = nil;
[super stop];
}
#pragma mark - Private
- (void)stopUMACoordinator {
[self.UMACoordinator stop];
self.UMACoordinator.delegate = nil;
self.UMACoordinator = nil;
}
// Starts the coordinator to present the Add Account module.
- (void)triggerAddAccount {
[self.mediator userAttemptedToSignin];
self.addAccountSigninCoordinator = [SigninCoordinator
addAccountCoordinatorWithBaseViewController:self.viewController
browser:self.browser
accessPoint:signin_metrics::AccessPoint::
ACCESS_POINT_START_PAGE];
__weak __typeof(self) weakSelf = self;
self.addAccountSigninCoordinator.signinCompletion =
^(SigninCoordinatorResult signinResult,
SigninCompletionInfo* signinCompletionInfo) {
[weakSelf addAccountSigninCompleteWithResult:signinResult
completionInfo:signinCompletionInfo];
};
[self.addAccountSigninCoordinator start];
}
// Callback handling the completion of the AddAccount action.
- (void)addAccountSigninCompleteWithResult:(SigninCoordinatorResult)signinResult
completionInfo:
(SigninCompletionInfo*)signinCompletionInfo {
[self.addAccountSigninCoordinator stop];
self.addAccountSigninCoordinator = nil;
if (signinResult == SigninCoordinatorResultSuccess &&
self.accountManagerService->IsValidIdentity(
signinCompletionInfo.identity)) {
self.mediator.selectedIdentity = signinCompletionInfo.identity;
self.mediator.addedAccount = YES;
}
}
// Starts the sign in process.
- (void)startSignIn {
DCHECK(self.mediator.selectedIdentity);
AuthenticationFlow* authenticationFlow =
[[AuthenticationFlow alloc] initWithBrowser:self.browser
identity:self.mediator.selectedIdentity
accessPoint:signin_metrics::AccessPoint::
ACCESS_POINT_START_PAGE
postSignInAction:PostSignInAction::kNone
presentingViewController:self.viewController];
authenticationFlow.dispatcher = HandlerForProtocol(
self.browser->GetCommandDispatcher(), BrowsingDataCommands);
__weak __typeof(self) weakSelf = self;
ProceduralBlock completion = ^() {
[weakSelf finishPresentingWithSignIn:YES];
};
[self.mediator startSignInWithAuthenticationFlow:authenticationFlow
completion:completion];
}
// Calls the mediator and the delegate when the coordinator is finished.
- (void)finishPresentingWithSignIn:(BOOL)signIn {
[self.mediator finishPresentingWithSignIn:signIn];
[self.delegate screenWillFinishPresenting];
}
// Shows the UMA dialog so the user can manage metric reporting.
- (void)showUMADialog {
DCHECK(!self.UMACoordinator);
self.UMACoordinator = [[UMACoordinator alloc]
initWithBaseViewController:self.viewController
browser:self.browser
UMAReportingValue:self.mediator.UMAReportingUserChoice];
self.UMACoordinator.delegate = self;
[self.UMACoordinator start];
}
#pragma mark - IdentityChooserCoordinatorDelegate
- (void)identityChooserCoordinatorDidClose:
(IdentityChooserCoordinator*)coordinator {
CHECK_EQ(self.identityChooserCoordinator, coordinator);
[self.identityChooserCoordinator stop];
self.identityChooserCoordinator = nil;
}
- (void)identityChooserCoordinatorDidTapOnAddAccount:
(IdentityChooserCoordinator*)coordinator {
CHECK_EQ(self.identityChooserCoordinator, coordinator);
DCHECK(!self.addAccountSigninCoordinator);
[self triggerAddAccount];
}
- (void)identityChooserCoordinator:(IdentityChooserCoordinator*)coordinator
didSelectIdentity:(id<SystemIdentity>)identity {
CHECK_EQ(self.identityChooserCoordinator, coordinator);
self.mediator.selectedIdentity = identity;
}
#pragma mark - PromoStyleViewControllerDelegate
- (void)didTapPrimaryActionButton {
switch (self.authenticationService->GetServiceStatus()) {
case AuthenticationService::ServiceStatus::SigninForcedByPolicy:
case AuthenticationService::ServiceStatus::SigninAllowed:
if (self.mediator.selectedIdentity) {
[self startSignIn];
} else {
[self triggerAddAccount];
}
break;
case AuthenticationService::ServiceStatus::SigninDisabledByUser:
case AuthenticationService::ServiceStatus::SigninDisabledByPolicy:
case AuthenticationService::ServiceStatus::SigninDisabledByInternal:
[self finishPresentingWithSignIn:NO];
return;
}
}
- (void)didTapSecondaryActionButton {
__weak __typeof(self) weakSelf = self;
[self.mediator cancelSignInScreenWithCompletion:^{
[weakSelf finishPresentingWithSignIn:NO];
}];
}
- (void)didTapURLInDisclaimer:(NSURL*)URL {
if ([URL.absoluteString isEqualToString:first_run::kTermsOfServiceURL]) {
[self showTOSPage];
} else if ([URL.absoluteString
isEqualToString:first_run::kMetricReportingURL]) {
self.mediator.UMALinkWasTapped = YES;
[self showUMADialog];
} else {
NOTREACHED() << std::string("Unknown URL ")
<< base::SysNSStringToUTF8(URL.absoluteString);
}
}
#pragma mark - SigninScreenViewControllerDelegate
- (void)showAccountPickerFromPoint:(CGPoint)point {
DCHECK(!self.identityChooserCoordinator);
self.identityChooserCoordinator = [[IdentityChooserCoordinator alloc]
initWithBaseViewController:self.viewController
browser:self.browser];
self.identityChooserCoordinator.delegate = self;
self.identityChooserCoordinator.origin = point;
[self.identityChooserCoordinator start];
self.identityChooserCoordinator.selectedIdentity =
self.mediator.selectedIdentity;
}
#pragma mark - TOSCommands
- (void)showTOSPage {
DCHECK(!self.TOSCoordinator);
self.mediator.TOSLinkWasTapped = YES;
self.TOSCoordinator =
[[TOSCoordinator alloc] initWithBaseViewController:self.viewController
browser:self.browser];
[self.TOSCoordinator start];
}
- (void)closeTOSPage {
DCHECK(self.TOSCoordinator);
[self.TOSCoordinator stop];
self.TOSCoordinator = nil;
}
#pragma mark - UMACoordinatorDelegate
- (void)UMACoordinatorDidRemoveWithCoordinator:(UMACoordinator*)coordinator
UMAReportingUserChoice:(BOOL)UMAReportingUserChoice {
DCHECK(self.UMACoordinator);
DCHECK_EQ(self.UMACoordinator, coordinator);
[self stopUMACoordinator];
DCHECK(self.mediator);
self.mediator.UMAReportingUserChoice = UMAReportingUserChoice;
}
@end