Commit 4e8bad04 authored by Nohemi Fernandez's avatar Nohemi Fernandez Committed by Commit Bot

[iOS][MICE] Re-route Settings link in Turn on Sync? page.

Currently the Settings link opens to the Sync & Google Services options.
With this patch the Settings page will be routed directly to Sync
without the option to turn off Sync.

Bug: 1125631
Change-Id: Ic5d38db6d835ffc7ea7b310be5801fb6cb928acc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2463306
Commit-Queue: Nohemi Fernandez <fernandex@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Reviewed-by: default avatarJérôme Lebel <jlebel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817684}
parent bace83ca
......@@ -205,6 +205,7 @@ source_set("eg_test_support+eg2") {
"//ios/chrome/app/strings",
"//ios/chrome/browser/ui/authentication/cells:constants",
"//ios/chrome/browser/ui/authentication/unified_consent:constants",
"//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui_constants",
"//ios/chrome/browser/ui/settings/google_services:constants",
"//ios/chrome/test:eg_test_support+eg2",
"//ios/chrome/test/earl_grey:eg_test_support+eg2",
......
......@@ -27,6 +27,7 @@ source_set("advanced_settings_signin") {
"//ios/chrome/browser/main:public",
"//ios/chrome/browser/signin",
"//ios/chrome/browser/sync",
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/alert_coordinator",
"//ios/chrome/browser/ui/authentication/signin:signin_protected",
"//ios/chrome/browser/ui/settings/google_services",
......@@ -71,3 +72,29 @@ source_set("unit_tests") {
"//ios/web/public/test",
]
}
source_set("eg2_tests") {
defines = [ "CHROME_EARL_GREY_2" ]
configs += [
"//build/config/compiler:enable_arc",
"//build/config/ios:xctest_config",
]
testonly = true
sources = [ "advanced_settings_signin_egtest.mm" ]
deps = [
"//base",
"//base/test:test_support",
"//components/signin/public/base",
"//ios/chrome/app/strings",
"//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
"//ios/chrome/browser/ui/content_suggestions:feature_flags",
"//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui_constants",
"//ios/chrome/browser/ui/settings/google_services:constants",
"//ios/chrome/test/earl_grey:eg_test_support+eg2",
"//ios/public/provider/chrome/browser/signin:fake_chrome_identity",
"//ios/testing/earl_grey:eg_test_support+eg2",
"//ios/third_party/earl_grey2:test_lib",
"//ui/base",
]
frameworks = [ "UIKit.framework" ]
}
......@@ -4,6 +4,7 @@
#import "ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_coordinator.h"
#include "base/mac/foundation_util.h"
#import "base/metrics/user_metrics.h"
#import "ios/chrome/browser/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/main/browser.h"
......@@ -18,6 +19,8 @@
#import "ios/chrome/browser/ui/authentication/signin/signin_coordinator+protected.h"
#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.h"
#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_mode.h"
#import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.h"
#import "ios/chrome/browser/ui/settings/google_services/sync_settings_view_state.h"
#import "ios/chrome/grit/ios_strings.h"
#import "ui/base/l10n/l10n_util_mac.h"
......@@ -31,6 +34,7 @@ using l10n_util::GetNSString;
@interface AdvancedSettingsSigninCoordinator () <
AdvancedSettingsSigninNavigationControllerNavigationDelegate,
ManageSyncSettingsCoordinatorDelegate,
UIAdaptivePresentationControllerDelegate>
// Advanced settings sign-in mediator.
......@@ -39,9 +43,9 @@ using l10n_util::GetNSString;
// View controller presented by this coordinator.
@property(nonatomic, strong) AdvancedSettingsSigninNavigationController*
advancedSettingsSigninNavigationController;
// Google services settings coordinator.
// Coordinator to present Sync settings.
@property(nonatomic, strong)
GoogleServicesSettingsCoordinator* googleServicesSettingsCoordinator;
ChromeCoordinator<SyncSettingsViewState>* syncSettingsCoordinator;
// Confirm cancel sign-in/sync dialog.
@property(nonatomic, strong)
ActionSheetCoordinator* cancelConfirmationAlertCoordinator;
......@@ -64,16 +68,7 @@ using l10n_util::GetNSString;
UIModalPresentationFormSheet;
self.advancedSettingsSigninNavigationController.navigationDelegate = self;
// Init and start Google settings coordinator.
GoogleServicesSettingsMode mode =
GoogleServicesSettingsModeAdvancedSigninSettings;
self.googleServicesSettingsCoordinator =
[[GoogleServicesSettingsCoordinator alloc]
initWithBaseNavigationController:
self.advancedSettingsSigninNavigationController
browser:self.browser
mode:mode];
[self.googleServicesSettingsCoordinator start];
[self startSyncSettingsCoordinator];
// Create the mediator.
SyncSetupService* syncSetupService =
......@@ -101,8 +96,9 @@ using l10n_util::GetNSString;
- (void)interruptWithAction:(SigninCoordinatorInterruptAction)action
completion:(ProceduralBlock)completion {
DCHECK(self.advancedSettingsSigninNavigationController);
[self.googleServicesSettingsCoordinator stop];
self.googleServicesSettingsCoordinator = nil;
[self.syncSettingsCoordinator stop];
self.syncSettingsCoordinator = nil;
switch (action) {
case SigninCoordinatorInterruptActionNoDismiss:
[self finishedWithSigninResult:SigninCoordinatorResultInterrupted];
......@@ -132,6 +128,31 @@ using l10n_util::GetNSString;
#pragma mark - Private
// Displays the Sync or Google services settings page.
- (void)startSyncSettingsCoordinator {
DCHECK(!self.syncSettingsCoordinator);
if (base::FeatureList::IsEnabled(signin::kMobileIdentityConsistency)) {
ManageSyncSettingsCoordinator* manageSyncSettingsCoordinator =
[[ManageSyncSettingsCoordinator alloc]
initWithBaseNavigationController:
self.advancedSettingsSigninNavigationController
browser:self.browser];
manageSyncSettingsCoordinator.delegate = self;
self.syncSettingsCoordinator = manageSyncSettingsCoordinator;
} else {
// Init and start Google settings coordinator.
GoogleServicesSettingsMode mode =
GoogleServicesSettingsModeAdvancedSigninSettings;
self.syncSettingsCoordinator = [[GoogleServicesSettingsCoordinator alloc]
initWithBaseNavigationController:
self.advancedSettingsSigninNavigationController
browser:self.browser
mode:mode];
}
[self.syncSettingsCoordinator start];
}
// Called when a button of |self.cancelConfirmationAlertCoordinator| is pressed.
- (void)cancelConfirmationWithShouldCancelSignin:(BOOL)shouldCancelSignin {
DCHECK(self.cancelConfirmationAlertCoordinator);
......@@ -180,8 +201,8 @@ using l10n_util::GetNSString;
saveUserPreferenceForSigninResult:signinResult];
self.advancedSettingsSigninNavigationController = nil;
self.advancedSettingsSigninMediator = nil;
[self.googleServicesSettingsCoordinator stop];
self.googleServicesSettingsCoordinator = nil;
[self.syncSettingsCoordinator stop];
self.syncSettingsCoordinator = nil;
SyncSetupService* syncSetupService =
SyncSetupServiceFactory::GetForBrowserState(
self.browser->GetBrowserState());
......@@ -207,8 +228,7 @@ using l10n_util::GetNSString;
message:
GetNSString(
IDS_IOS_ADVANCED_SIGNIN_SETTINGS_CANCEL_SYNC_ALERT_MESSAGE)
barButtonItem:self.googleServicesSettingsCoordinator
.viewController.navigationItem
barButtonItem:self.syncSettingsCoordinator.navigationItem
.leftBarButtonItem];
__weak __typeof(self) weakSelf = self;
[self.cancelConfirmationAlertCoordinator
......@@ -253,10 +273,18 @@ using l10n_util::GetNSString;
- (void)presentationControllerDidAttemptToDismiss:
(UIPresentationController*)presentationController {
// Only show cancel confirmation when "Sync and Google Services" is displayed.
if (self.googleServicesSettingsCoordinator
.googleServicesSettingsViewIsShown) {
if (self.syncSettingsCoordinator.isSettingsViewShown) {
[self showCancelConfirmationAlert];
}
}
#pragma mark - ManageSyncSettingsCoordinatorDelegate
- (void)manageSyncSettingsCoordinatorWasRemoved:
(ManageSyncSettingsCoordinator*)coordinator {
DCHECK_EQ(self.syncSettingsCoordinator, coordinator);
[self.syncSettingsCoordinator stop];
self.syncSettingsCoordinator = nil;
}
@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.
#include "base/ios/ios_util.h"
#import "components/signin/public/base/account_consistency_method.h"
#import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
#import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h"
#import "ios/chrome/browser/ui/recent_tabs/recent_tabs_constants.h"
#import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_constants.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/public/provider/chrome/browser/signin/fake_chrome_identity.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#import "ios/testing/earl_grey/matchers.h"
#include "ui/base/l10n/l10n_util_mac.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using chrome_test_util::GoogleServicesSettingsView;
using chrome_test_util::PrimarySignInButton;
using chrome_test_util::SyncSettingsConfirmButton;
using l10n_util::GetNSString;
using testing::ButtonWithAccessibilityLabel;
namespace {
// Timeout in seconds to wait for asynchronous sync operations.
const NSTimeInterval kSyncOperationTimeout = 5.0;
} // namespace
// Interaction tests for advanced settings sign-in with
// |kMobileIdentityConsistency| feature enabled.
@interface AdvancedSettingsSigninTestCase : ChromeTestCase
@end
@implementation AdvancedSettingsSigninTestCase
- (AppLaunchConfiguration)appConfigurationForTestCase {
AppLaunchConfiguration config;
config.features_enabled.push_back(signin::kMobileIdentityConsistency);
return config;
}
// Tests that signing in, tapping the Settings link on the confirmation screen
// and closing the advanced sign-in settings correctly leaves the user signed
// in.
- (void)testSignInOpenSyncSettings {
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[ChromeEarlGreyUI openSettingsMenu];
[ChromeEarlGreyUI tapSettingsMenuButton:PrimarySignInButton()];
[SigninEarlGreyUI tapSettingsLink];
[[EarlGrey selectElementWithMatcher:SyncSettingsConfirmButton()]
performAction:grey_tap()];
// Test the user is signed in.
[SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
}
// Verifies that advanced sign-in shows an alert dialog when being swiped to
// dismiss.
- (void)testSwipeDownToCancelAdvancedSignin {
if (!base::ios::IsRunningOnOrLater(13, 0, 0)) {
EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower.");
}
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[ChromeEarlGreyUI openSettingsMenu];
[ChromeEarlGreyUI tapSettingsMenuButton:PrimarySignInButton()];
[SigninEarlGreyUI tapSettingsLink];
[[EarlGrey
selectElementWithMatcher:grey_accessibilityID(
kManageSyncTableViewAccessibilityIdentifier)]
performAction:grey_swipeFastInDirection(kGREYDirectionDown)];
[[EarlGrey
selectElementWithMatcher:
ButtonWithAccessibilityLabel(GetNSString(
IDS_IOS_ADVANCED_SIGNIN_SETTINGS_CANCEL_SYNC_ALERT_CANCEL_SYNC_BUTTON))]
performAction:grey_tap()];
[SigninEarlGrey verifySignedOut];
}
// Tests interrupting sign-in by opening an URL from another app.
// Sign-in opened from: setting menu.
// Interrupted at: advanced sign-in.
- (void)testInterruptAdvancedSigninSettingsFromAdvancedSigninSettings {
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[ChromeEarlGreyUI openSettingsMenu];
[ChromeEarlGreyUI tapSettingsMenuButton:PrimarySignInButton()];
[ChromeEarlGreyUI waitForAppToIdle];
[SigninEarlGreyUI tapSettingsLink];
[ChromeEarlGreyUI waitForAppToIdle];
[ChromeEarlGrey simulateExternalAppURLOpening];
[ChromeEarlGrey waitForSyncInitialized:NO syncTimeout:kSyncOperationTimeout];
[SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
}
// Tests interrupting sign-in by opening an URL from another app.
// Sign-in opened from: bookmark view.
// Interrupted at: advanced sign-in.
- (void)testInterruptAdvancedSigninBookmarksFromAdvancedSigninSettings {
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[ChromeEarlGreyUI openToolsMenu];
[ChromeEarlGreyUI tapToolsMenuButton:chrome_test_util::BookmarksMenuButton()];
[[EarlGrey selectElementWithMatcher:PrimarySignInButton()]
performAction:grey_tap()];
[SigninEarlGreyUI tapSettingsLink];
[ChromeEarlGreyUI waitForAppToIdle];
[ChromeEarlGrey simulateExternalAppURLOpening];
[ChromeEarlGrey waitForSyncInitialized:NO syncTimeout:kSyncOperationTimeout];
[SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
}
// Tests interrupting sign-in by opening an URL from another app.
// Sign-in opened from: recent tabs.
// Interrupted at: advanced sign-in.
- (void)testInterruptSigninFromRecentTabsFromAdvancedSigninSettings {
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[ChromeEarlGreyUI openToolsMenu];
[ChromeEarlGreyUI
tapToolsMenuButton:chrome_test_util::RecentTabsMenuButton()];
[SigninEarlGreyUI scrollToPrimarySignInButtonInRecentTabs];
[SigninEarlGreyUI tapSettingsLink];
[ChromeEarlGreyUI waitForAppToIdle];
[ChromeEarlGrey simulateExternalAppURLOpening];
[ChromeEarlGrey waitForSyncInitialized:NO syncTimeout:kSyncOperationTimeout];
[SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
}
// Tests interrupting sign-in by opening an URL from another app.
// Sign-in opened from: tab switcher.
// Interrupted at: advanced sign-in.
- (void)testInterruptSigninFromTabSwitcherFromAdvancedSigninSettings {
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::
TabGridOtherDevicesPanelButton()]
performAction:grey_tap()];
[SigninEarlGreyUI collapseRecentlyClosedTabsIfSigninPromoNotVisible];
[SigninEarlGreyUI scrollToPrimarySignInButtonInRecentTabs];
[SigninEarlGreyUI tapSettingsLink];
[ChromeEarlGreyUI waitForAppToIdle];
[ChromeEarlGrey simulateExternalAppURLOpening];
[ChromeEarlGrey waitForSyncInitialized:NO syncTimeout:kSyncOperationTimeout];
[SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
}
@end
......@@ -49,40 +49,6 @@ typedef NS_ENUM(NSInteger, OpenSigninMethod) {
namespace {
// Taps on the primary sign-in button in recent tabs, and scroll first, if
// necessary.
void TapOnPrimarySignInButtonInRecentTabs() {
[[[EarlGrey
selectElementWithMatcher:grey_allOf(PrimarySignInButton(),
grey_sufficientlyVisible(), nil)]
usingSearchAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)
onElementWithMatcher:
grey_allOf(grey_accessibilityID(
kRecentTabsTableViewControllerAccessibilityIdentifier),
grey_sufficientlyVisible(), nil)]
performAction:grey_tap()];
}
// Collapses the recently closed tabs section if the sign in promo is
// inaccessible otherwise.
void CollapseRecentlyClosedTabsSectionIfNecessary() {
NSError* error = nil;
[[EarlGrey selectElementWithMatcher:
grey_accessibilityID(
kRecentTabsTableViewControllerAccessibilityIdentifier)]
assertWithMatcher:chrome_test_util::ContentViewSmallerThanScrollView()
error:&error];
if (error) {
[[EarlGrey selectElementWithMatcher:
grey_allOf(chrome_test_util::ButtonWithAccessibilityLabel(
l10n_util::GetNSString(
IDS_IOS_RECENT_TABS_RECENTLY_CLOSED)),
grey_sufficientlyVisible(), nil)]
performAction:grey_tap()];
}
}
// Returns a matcher for |userEmail| in IdentityChooserViewController.
id<GREYMatcher> identityChooserButtonMatcherWithEmail(NSString* userEmail) {
return grey_allOf(grey_accessibilityID(userEmail),
......@@ -188,28 +154,6 @@ void ChooseImportOrKeepDataSepareteDialog(id<GREYMatcher> choiceButtonMatcher) {
[SigninEarlGreyUI signOutAndClearDataFromDevice];
}
// Tests that signing in, tapping the Settings link on the confirmation screen
// and closing the advanced sign-in settings correctly leaves the user signed
// in.
- (void)testSignInOpenSettings {
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[self openSigninFromView:OpenSigninMethodFromSettings tapSettingsLink:YES];
[[EarlGrey selectElementWithMatcher:SyncSettingsConfirmButton()]
performAction:grey_tap()];
// Test sync is on in the settings view.
id<GREYMatcher> settings_matcher =
chrome_test_util::StaticTextWithAccessibilityLabelId(
IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SYNC_ON);
[[EarlGrey selectElementWithMatcher:settings_matcher]
assertWithMatcher:grey_sufficientlyVisible()];
// Test the user is signed in.
[SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
}
// Opens the sign in screen and then cancel it by opening a new tab. Ensures
// that the sign in screen is correctly dismissed. crbug.com/462200
- (void)testSignInCancelIdentityPicker {
......@@ -456,7 +400,7 @@ void ChooseImportOrKeepDataSepareteDialog(id<GREYMatcher> choiceButtonMatcher) {
[ChromeEarlGreyUI openToolsMenu];
[ChromeEarlGreyUI
tapToolsMenuButton:chrome_test_util::RecentTabsMenuButton()];
TapOnPrimarySignInButtonInRecentTabs();
[SigninEarlGreyUI scrollToPrimarySignInButtonInRecentTabs];
break;
case OpenSigninMethodFromTabSwitcher:
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
......@@ -465,10 +409,8 @@ void ChooseImportOrKeepDataSepareteDialog(id<GREYMatcher> choiceButtonMatcher) {
TabGridOtherDevicesPanelButton()]
performAction:grey_tap()];
// TODO(crbug.com/1131479): Find a way to scroll the view instead.
CollapseRecentlyClosedTabsSectionIfNecessary();
TapOnPrimarySignInButtonInRecentTabs();
[SigninEarlGreyUI collapseRecentlyClosedTabsIfSigninPromoNotVisible];
[SigninEarlGreyUI scrollToPrimarySignInButtonInRecentTabs];
break;
}
if (tapSettingsLink) {
......
......@@ -53,6 +53,15 @@
+ (void)tapRemoveAccountFromDeviceWithFakeIdentity:
(FakeChromeIdentity*)fakeIdentity;
// Scrolls, if necessary, to the primary sign-in button in recent tabs and taps.
// Assumes there is a pre-existing primary identity added to the sign-in.
+ (void)scrollToPrimarySignInButtonInRecentTabs;
// Collapses the recently closed tabs section if the sign in promo is
// inaccessible otherwise.
// TODO(crbug.com/1131479): Find a way to scroll the view instead.
+ (void)collapseRecentlyClosedTabsIfSigninPromoNotVisible;
// Checks that the sign-in promo view (with a close button) is visible using the
// right mode.
+ (void)verifySigninPromoVisibleWithMode:(SigninPromoViewMode)mode;
......
......@@ -9,6 +9,7 @@
#import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
#import "ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.h"
#import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_constants.h"
#import "ios/chrome/browser/ui/recent_tabs/recent_tabs_constants.h"
#import "ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller_constants.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
......@@ -225,6 +226,36 @@ using chrome_test_util::SignOutAccountsButton;
[ChromeEarlGreyUI waitForAppToIdle];
}
+ (void)scrollToPrimarySignInButtonInRecentTabs {
[[[EarlGrey
selectElementWithMatcher:grey_allOf(PrimarySignInButton(),
grey_sufficientlyVisible(), nil)]
usingSearchAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)
onElementWithMatcher:
grey_allOf(grey_accessibilityID(
kRecentTabsTableViewControllerAccessibilityIdentifier),
grey_sufficientlyVisible(), nil)]
performAction:grey_tap()];
}
+ (void)collapseRecentlyClosedTabsIfSigninPromoNotVisible {
NSError* error = nil;
[[EarlGrey selectElementWithMatcher:
grey_accessibilityID(
kRecentTabsTableViewControllerAccessibilityIdentifier)]
assertWithMatcher:chrome_test_util::ContentViewSmallerThanScrollView()
error:&error];
if (error) {
[[EarlGrey selectElementWithMatcher:
grey_allOf(chrome_test_util::ButtonWithAccessibilityLabel(
l10n_util::GetNSString(
IDS_IOS_RECENT_TABS_RECENTLY_CLOSED)),
grey_sufficientlyVisible(), nil)]
performAction:grey_tap()];
}
}
#pragma mark - Private
+ (void)signOutWithButton:(id<GREYMatcher>)buttonMatcher
......
......@@ -29,6 +29,7 @@ source_set("google_services") {
"manage_sync_settings_table_view_controller.mm",
"manage_sync_settings_view_controller_model_delegate.h",
"sync_error_settings_command_handler.h",
"sync_settings_view_state.h",
]
deps = [
":constants",
......
......@@ -7,8 +7,10 @@
#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_mode.h"
#import "ios/chrome/browser/ui/settings/google_services/sync_settings_view_state.h"
@protocol ApplicationCommands;
@protocol SyncSettingsViewState;
@class GoogleServicesSettingsCoordinator;
// Delegate for GoogleServicesSettingsCoordinator.
......@@ -24,7 +26,8 @@
// All the sync changes made by the user are applied when
// -[GoogleServicesSettingsCoordinator stop] is called, or when the
// GoogleServicesSettingsCoordinator instance is deallocated.
@interface GoogleServicesSettingsCoordinator : ChromeCoordinator
@interface GoogleServicesSettingsCoordinator
: ChromeCoordinator <SyncSettingsViewState>
// View controller for the Google services settings.
@property(nonatomic, strong) UIViewController* viewController;
......
......@@ -44,7 +44,8 @@ using signin_metrics::PromoAction;
GoogleServicesSettingsCommandHandler,
GoogleServicesSettingsViewControllerPresentationDelegate,
ManageSyncSettingsCoordinatorDelegate,
SyncErrorSettingsCommandHandler>
SyncErrorSettingsCommandHandler,
SyncSettingsViewState>
// Google services settings mode.
@property(nonatomic, assign, readonly) GoogleServicesSettingsMode mode;
......@@ -62,10 +63,9 @@ using signin_metrics::PromoAction;
ManageSyncSettingsCoordinator* manageSyncSettingsCoordinator;
// YES if stop has been called.
@property(nonatomic, assign) BOOL stopDone;
// YES if the last sign-in has been interrupted. In that case, the coordinator
// is going to be stopped, and the sync setup flag should not be marked as done.
// And the sync should not be marked as disabled. The sync should be kept
// undecided.
// YES if the last sign-in has been interrupted. In that case, the sync UI will
// be dismissed and the sync setup flag should not be marked as done. The sync
// should be kept undecided, not marked as disabled.
@property(nonatomic, assign) BOOL signinInterrupted;
@end
......@@ -168,11 +168,17 @@ using signin_metrics::PromoAction;
self.viewController);
}
- (BOOL)googleServicesSettingsViewIsShown {
#pragma mark - SyncSettingsViewState
- (BOOL)isSettingsViewShown {
return [self.viewController
isEqual:self.baseNavigationController.topViewController];
}
- (UINavigationItem*)navigationItem {
return self.viewController.navigationItem;
}
#pragma mark - SyncErrorSettingsCommandHandler
- (void)restartAuthenticationFlow {
......
......@@ -6,8 +6,10 @@
#define IOS_CHROME_BROWSER_UI_SETTINGS_GOOGLE_SERVICES_MANAGE_SYNC_SETTINGS_COORDINATOR_H_
#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
#import "ios/chrome/browser/ui/settings/google_services/sync_settings_view_state.h"
@class ManageSyncSettingsCoordinator;
@protocol SyncSettingsViewState;
// Delegate for ManageSyncSettingsCoordinator.
@protocol ManageSyncSettingsCoordinatorDelegate <NSObject>
......@@ -21,7 +23,8 @@
// Coordinator for the Manage Sync Settings TableView Controller.
// This class doesn't commit any sync changes made by the user. This class
// relies on GoogleServicesSettingsCoordinator to commit the sync changes.
@interface ManageSyncSettingsCoordinator : ChromeCoordinator
@interface ManageSyncSettingsCoordinator
: ChromeCoordinator <SyncSettingsViewState>
- (instancetype)initWithBaseViewController:(UIViewController*)viewController
browser:(Browser*)browser NS_UNAVAILABLE;
......
......@@ -19,6 +19,7 @@
#import "ios/chrome/browser/signin/authentication_service_factory.h"
#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
#include "ios/chrome/browser/sync/sync_observer_bridge.h"
#include "ios/chrome/browser/sync/sync_setup_service.h"
#include "ios/chrome/browser/sync/sync_setup_service_factory.h"
#import "ios/chrome/browser/ui/authentication/authentication_flow.h"
#import "ios/chrome/browser/ui/commands/application_commands.h"
......@@ -49,7 +50,8 @@ using signin_metrics::PromoAction;
ManageSyncSettingsCommandHandler,
SyncErrorSettingsCommandHandler,
ManageSyncSettingsTableViewControllerPresentationDelegate,
SyncObserverModelBridge> {
SyncObserverModelBridge,
SyncSettingsViewState> {
// Sync observer.
std::unique_ptr<SyncObserverBridge> _syncObserver;
}
......@@ -68,6 +70,10 @@ using signin_metrics::PromoAction;
dismissWebAndAppSettingDetailsControllerBlock;
// Manages the authentication flow for a given identity.
@property(nonatomic, strong) AuthenticationFlow* authenticationFlow;
// YES if the last sign-in has been interrupted. In that case, the sync UI will
// be dismissed and the sync setup flag should not be marked as done. The sync
// should be kept undecided, not marked as disabled.
@property(nonatomic, assign) BOOL signinInterrupted;
@end
......@@ -106,6 +112,23 @@ using signin_metrics::PromoAction;
_syncObserver.reset(new SyncObserverBridge(self, self.syncService));
}
- (void)stop {
// Sync changes should only be commited if the user is authenticated and
// the sign-in has not been interrupted.
if (self.authService->IsAuthenticated() || !self.signinInterrupted) {
SyncSetupService* syncSetupService =
SyncSetupServiceFactory::GetForBrowserState(
self.browser->GetBrowserState());
if (syncSetupService->GetSyncServiceState() ==
SyncSetupService::kSyncSettingsNotConfirmed) {
// If Sync is still in aborted state, this means the user didn't turn on
// sync, and wants Sync off. To acknowledge, Sync has to be turned off.
syncSetupService->SetSyncEnabled(false);
}
syncSetupService->CommitSyncChanges();
}
}
#pragma mark - Properties
- (syncer::SyncService*)syncService {
......@@ -118,6 +141,17 @@ using signin_metrics::PromoAction;
self.browser->GetBrowserState());
}
#pragma mark - SyncSettingsViewState
- (BOOL)isSettingsViewShown {
return [self.viewController
isEqual:self.baseNavigationController.topViewController];
}
- (UINavigationItem*)navigationItem {
return self.viewController.navigationItem;
}
#pragma mark - Private
// Closes the Manage sync settings view controller.
......@@ -133,6 +167,20 @@ using signin_metrics::PromoAction;
}
}
- (void)signinFinishedWithSuccess:(BOOL)success {
DCHECK(self.authenticationFlow);
self.authenticationFlow = nil;
[self.viewController allowUserInteraction];
ChromeIdentity* primaryAccount =
AuthenticationServiceFactory::GetForBrowserState(
self.browser->GetBrowserState())
->GetAuthenticatedIdentity();
// TODO(crbug.com/1101346): SigninCoordinatorResult should be received instead
// of guessing if the sign-in has been interrupted.
self.signinInterrupted = !success && primaryAccount;
}
#pragma mark - ManageSyncSettingsTableViewControllerPresentationDelegate
- (void)manageSyncSettingsTableViewControllerWasRemoved:
......@@ -230,10 +278,7 @@ using signin_metrics::PromoAction;
self.browser->GetCommandDispatcher(), BrowsingDataCommands);
__weak ManageSyncSettingsCoordinator* weakSelf = self;
[self.authenticationFlow startSignInWithCompletion:^(BOOL success) {
// TODO(crbug.com/889919): Needs to add histogram for |success|.
DCHECK(weakSelf.authenticationFlow);
weakSelf.authenticationFlow = nil;
[weakSelf.viewController allowUserInteraction];
[weakSelf signinFinishedWithSuccess:success];
}];
}
......
// 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_SETTINGS_GOOGLE_SERVICES_SYNC_SETTINGS_VIEW_STATE_H_
#define IOS_CHROME_BROWSER_UI_SETTINGS_GOOGLE_SERVICES_SYNC_SETTINGS_VIEW_STATE_H_
// Protocol used to retrieve view properties in Sync settings UI.
@protocol SyncSettingsViewState
// Whether the Sync settings view is displayed. This does not necessarily mean
// the view is visible to the user since it can be obstructed by views that are
// not owned by the navigation stack (e.g. MyGoogle UI).
@property(nonatomic, assign, readonly, getter=isSettingsViewShown)
BOOL settingsViewShown;
// UINavigationItem associated with the Sync settings view.
@property(nonatomic, strong, readonly) UINavigationItem* navigationItem;
@end
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_GOOGLE_SERVICES_SYNC_SETTINGS_VIEW_STATE_H_
......@@ -132,7 +132,10 @@ chrome_ios_eg2_test("ios_chrome_settings_eg2tests_module") {
chrome_ios_eg2_test("ios_chrome_signin_eg2tests_module") {
xcode_test_application_name = "ios_chrome_eg2tests"
deps = [ "//ios/chrome/browser/ui/authentication/signin:eg2_tests" ]
deps = [
"//ios/chrome/browser/ui/authentication/signin:eg2_tests",
"//ios/chrome/browser/ui/authentication/signin/advanced_settings_signin:eg2_tests",
]
data_deps = [ ":ios_chrome_eg2tests" ]
}
......
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