Commit c8a5557b authored by Nohemi Fernandez's avatar Nohemi Fernandez Committed by Commit Bot

[iOS] Add cancel sign-out operation needed for architecture migration.

This patch adds the authentication flow required to cancel a sign-in
operation following a click on the 'Cancel' button in the
'Turn on Sync?' page.

This CL is part of a series of refactors to move the existing sign-in
architecture to the Coordinator-Mediator design paradigm.

Fore more information, see go/chrome-ios-signin-migration.

Bug: 971989
Change-Id: I72e8bf3c8fc15338d419dc2d3a888eecc430b807
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2067076
Commit-Queue: Nohemi Fernandez <fernandex@chromium.org>
Reviewed-by: default avatarJérôme Lebel <jlebel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#744607}
parent b374fd5f
......@@ -9,11 +9,16 @@ source_set("user_signin") {
sources = [
"user_signin_coordinator.h",
"user_signin_coordinator.mm",
"user_signin_mediator.h",
"user_signin_mediator.mm",
"user_signin_view_controller.h",
"user_signin_view_controller.mm",
]
deps = [
"//ios/chrome/app/strings",
"//ios/chrome/browser/signin",
"//ios/chrome/browser/ui/authentication",
"//ios/chrome/browser/ui/authentication/signin:signin_protected",
"//ios/chrome/browser/ui/authentication/unified_consent",
"//ios/chrome/browser/ui/collection_view/cells",
"//ios/chrome/browser/ui/util",
......
......@@ -5,6 +5,11 @@
#import "ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.h"
#import "base/metrics/user_metrics.h"
#import "ios/chrome/browser/signin/authentication_service_factory.h"
#import "ios/chrome/browser/ui/authentication/authentication_flow.h"
#import "ios/chrome/browser/ui/authentication/signin/signin_coordinator+protected.h"
#import "ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_mediator.h"
#import "ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_view_controller.h"
#import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.h"
......@@ -16,7 +21,8 @@ using signin_metrics::AccessPoint;
using signin_metrics::PromoAction;
@interface UserSigninCoordinator () <UnifiedConsentCoordinatorDelegate,
UserSigninViewControllerDelegate>
UserSigninViewControllerDelegate,
UserSigninMediatorDelegate>
// Coordinator that handles the user consent before the user signs in.
@property(nonatomic, strong)
......@@ -25,6 +31,8 @@ using signin_metrics::PromoAction;
@property(nonatomic, strong) SigninCoordinator* addAccountSigninCoordinator;
// View controller that handles the sign-in UI.
@property(nonatomic, strong) UserSigninViewController* viewController;
// Mediator that handles the sign-in authentication state.
@property(nonatomic, strong) UserSigninMediator* mediator;
// Suggested identity shown at sign-in.
@property(nonatomic, strong) ChromeIdentity* defaultIdentity;
// View where the sign-in button was displayed.
......@@ -52,13 +60,18 @@ using signin_metrics::PromoAction;
return self;
}
#pragma mark - ChromeCoordinator
#pragma mark - SigninCoordinator
- (void)start {
[super start];
self.viewController = [[UserSigninViewController alloc] init];
self.viewController.delegate = self;
self.mediator = [[UserSigninMediator alloc]
initWithAuthenticationService:AuthenticationServiceFactory::
GetForBrowserState(self.browserState)];
self.mediator.delegate = self;
self.unifiedConsentCoordinator = [[UnifiedConsentCoordinator alloc]
initWithBaseViewController:nil
browser:self.browser];
......@@ -81,8 +94,6 @@ using signin_metrics::PromoAction;
- (void)stop {
[super stop];
[self.addAccountSigninCoordinator stop];
self.addAccountSigninCoordinator = nil;
self.unifiedConsentCoordinator = nil;
}
......@@ -108,7 +119,7 @@ using signin_metrics::PromoAction;
- (void)unifiedConsentCoordinatorNeedPrimaryButtonUpdate:
(UnifiedConsentCoordinator*)coordinator {
DCHECK_EQ(self.unifiedConsentCoordinator, coordinator);
[self.viewController updatePrimaryButtonStyle];
[self userSigninMediatorNeedPrimaryButtonUpdate];
}
#pragma mark - UserSigninViewControllerDelegate
......@@ -139,4 +150,51 @@ using signin_metrics::PromoAction;
[self.unifiedConsentCoordinator scrollToBottom];
}
- (void)userSigninViewControllerDidTapOnSkipSignin {
[self.mediator cancelSignin];
}
#pragma mark - UserSigninMediatorDelegate
- (void)userSigninMediatorSigninFinishedWithResult:
(SigninCoordinatorResult)signinResult {
[self recordSigninMetricsWithResult:signinResult];
__weak UserSigninCoordinator* weakSelf = self;
ProceduralBlock completion = ^void() {
[weakSelf
runCompletionCallbackWithSigninResult:signinResult
identity:weakSelf.unifiedConsentCoordinator
.selectedIdentity];
};
[self.viewController dismissViewControllerAnimated:YES completion:completion];
self.unifiedConsentCoordinator.delegate = nil;
self.unifiedConsentCoordinator = nil;
}
- (void)userSigninMediatorNeedPrimaryButtonUpdate {
[self.viewController updatePrimaryButtonStyle];
}
- (void)recordSigninMetricsWithResult:(SigninCoordinatorResult)signinResult {
switch (signinResult) {
case SigninCoordinatorResultSuccess: {
signin_metrics::LogSigninAccessPointCompleted(self.accessPoint,
self.promoAction);
break;
}
case SigninCoordinatorResultCanceledByUser: {
base::RecordAction(base::UserMetricsAction("Signin_Undo_Signin"));
break;
}
case SigninCoordinatorResultInterrupted: {
// TODO(crbug.com/951145): Add metric when the sign-in has been
// interrupted.
break;
}
}
}
@end
// Copyright 2020 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.
#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_SIGNIN_USER_SIGNIN_USER_SIGNIN_MEDIATOR_H_
#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_SIGNIN_USER_SIGNIN_USER_SIGNIN_MEDIATOR_H_
#import <Foundation/Foundation.h>
#import "components/signin/public/base/signin_metrics.h"
#import "ios/chrome/browser/ui/authentication/signin/signin_enums.h"
@class AuthenticationFlow;
class AuthenticationService;
// Delegate that handles interactions with unified consent coordinator.
@protocol UserSigninMediatorDelegate
// Updates sign-in state for the UserSigninCoordinator following sign-in
// finishing its workflow.
- (void)userSigninMediatorSigninFinishedWithResult:
(SigninCoordinatorResult)signinResult;
// Updates the primary button for the user sign-in screen.
- (void)userSigninMediatorNeedPrimaryButtonUpdate;
@end
// Mediator that handles the sign-in operation.
@interface UserSigninMediator : NSObject
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithAuthenticationService:
(AuthenticationService*)authenticationService NS_DESIGNATED_INITIALIZER;
// The delegate.
@property(nonatomic, weak) id<UserSigninMediatorDelegate> delegate;
// Property denoting whether the authentication operation is complete.
@property(nonatomic, assign) BOOL isAuthenticationCompleted;
// Reverts the sign-in operation.
- (void)cancelSignin;
@end
#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_SIGNIN_USER_SIGNIN_USER_SIGNIN_MEDIATOR_H_
// Copyright 2020 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/browser/ui/authentication/signin/user_signin/user_signin_mediator.h"
#include <memory>
#include "base/logging.h"
#import "base/metrics/user_metrics.h"
#import "ios/chrome/browser/signin/authentication_service.h"
#import "ios/chrome/browser/ui/authentication/authentication_flow.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface UserSigninMediator ()
// Manager for the authentication flow.
@property(nonatomic, strong) AuthenticationFlow* authenticationFlow;
// Chrome interface to the iOS shared authentication library.
@property(nonatomic, assign) AuthenticationService* authenticationService;
@end
@implementation UserSigninMediator
#pragma mark - Public
- (instancetype)initWithAuthenticationService:
(AuthenticationService*)authenticationService {
self = [super init];
if (self) {
_authenticationService = authenticationService;
}
return self;
}
- (void)cancelSignin {
if (!self.isAuthenticationCompleted) {
[self.delegate userSigninMediatorSigninFinishedWithResult:
SigninCoordinatorResultCanceledByUser];
self.isAuthenticationCompleted = YES;
} else if (self.isAuthenticationInProgress) {
// TODO(crbug.com/971989): Do not remove until the migration has been
// completed to ensure that the metrics calculated remain the same
// throughout the code changes.
base::RecordAction(base::UserMetricsAction("Signin_Undo_Signin"));
[self.authenticationFlow cancelAndDismiss];
self.authenticationService->SignOut(signin_metrics::ABORT_SIGNIN,
/*force_clear_browsing_data=*/false,
nil);
[self.delegate userSigninMediatorNeedPrimaryButtonUpdate];
}
}
#pragma mark - State
- (BOOL)isAuthenticationInProgress {
return self.authenticationFlow != nil;
}
@end
......@@ -20,6 +20,9 @@
// Performs scroll operation on unified consent screen.
- (void)userSigninViewControllerDidScrollOnUnifiedConsent;
// Performs operations to skip sign-in or undo existing sign-in.
- (void)userSigninViewControllerDidTapOnSkipSignin;
@end
// View controller used to show sign-in UI.
......@@ -29,7 +32,7 @@
@property(nonatomic, weak) id<UserSigninViewControllerDelegate> delegate;
// View controller that handles the user consent before the user signs in.
@property UIViewController* unifiedConsentViewController;
@property(nonatomic, weak) UIViewController* unifiedConsentViewController;
// Informs the view controller that the unified consent has reached the bottom
// of the screen.
......
......@@ -257,8 +257,7 @@ enum AuthenticationButtonType {
#pragma mark - Events
- (void)onSkipSigninButtonPressed:(id)sender {
// TODO(crbug.com/971989): Populate action.
NOTIMPLEMENTED();
[self.delegate userSigninViewControllerDidTapOnSkipSignin];
}
- (void)onConfirmationButtonPressed:(id)sender {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment