Commit fd08783c authored by Nohemi Fernandez's avatar Nohemi Fernandez Committed by Chromium LUCI CQ

[iOS][MICE] Add Sync promo for signed-in users with Sync disabled.

The new promo will only be shown on the Settings page with
|kMobileIdentityConsistency| enabled. This patch does not update
interactions with promo dismissals.

Bug: 1151289
Change-Id: I5ca5701415023cca5e20cfbef6427ff16dca8888
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2565574
Commit-Queue: Nohemi Fernandez <fernandex@chromium.org>
Reviewed-by: default avatarSylvain Defresne <sdefresne@chromium.org>
Reviewed-by: default avatarJérôme Lebel <jlebel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844521}
parent b7b5cc2e
......@@ -111,6 +111,7 @@ source_set("unit_tests") {
"//components/prefs",
"//components/signin/public/base",
"//components/signin/public/identity_manager",
"//components/sync/driver:test_support",
"//components/sync_preferences",
"//components/sync_preferences:test_support",
"//components/version_info",
......@@ -123,6 +124,7 @@ source_set("unit_tests") {
"//ios/chrome/browser/signin",
"//ios/chrome/browser/signin:test_support",
"//ios/chrome/browser/sync",
"//ios/chrome/browser/sync:test_support",
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/authentication/cells",
"//ios/chrome/browser/ui/authentication/unified_consent:unified_consent_ui",
......
......@@ -216,6 +216,9 @@ const CGFloat kImageViewWidthHeight = 32;
case IdentityPromoViewModeSigninWithAccount:
[self activateSigninWithAccountMode];
return;
case IdentityPromoViewModeSyncWithPrimaryAccount:
[self activateSyncWithPrimaryAccountMode];
return;
}
NOTREACHED();
}
......@@ -238,8 +241,13 @@ const CGFloat kImageViewWidthHeight = 32;
_secondaryButton.hidden = NO;
}
- (void)activateSyncWithPrimaryAccountMode {
DCHECK_EQ(_mode, IdentityPromoViewModeSyncWithPrimaryAccount);
_secondaryButton.hidden = YES;
}
- (void)setProfileImage:(UIImage*)image {
DCHECK_EQ(IdentityPromoViewModeSigninWithAccount, _mode);
DCHECK_NE(_mode, IdentityPromoViewModeNoAccounts);
self.imageView.image = CircularImageFromImage(image, kProfileImageFixedSize);
}
......@@ -268,6 +276,9 @@ const CGFloat kImageViewWidthHeight = 32;
case IdentityPromoViewModeSigninWithAccount:
[_delegate signinPromoViewDidTapSigninWithDefaultAccount:self];
break;
case IdentityPromoViewModeSyncWithPrimaryAccount:
[_delegate signinPromoViewDidTapSyncWithDefaultAccount:self];
break;
}
}
......
......@@ -64,6 +64,9 @@ using l10n_util::GetNSStringF;
signinPromoView.closeButton.hidden = !self.hasCloseButton;
signinPromoView.mode = self.identityPromoViewMode;
NSString* name =
self.userFullName.length ? self.userFullName : self.userEmail;
base::string16 name16 = SysNSStringToUTF16(name);
switch (self.identityPromoViewMode) {
case IdentityPromoViewModeNoAccounts: {
NSString* signInString =
......@@ -71,12 +74,9 @@ using l10n_util::GetNSStringF;
signinPromoView.accessibilityLabel = signInString;
[signinPromoView.primaryButton setTitle:signInString
forState:UIControlStateNormal];
break;
return;
}
case IdentityPromoViewModeSigninWithAccount: {
NSString* name =
self.userFullName.length ? self.userFullName : self.userEmail;
base::string16 name16 = SysNSStringToUTF16(name);
[signinPromoView.primaryButton
setTitle:GetNSStringF(IDS_IOS_SIGNIN_PROMO_CONTINUE_AS, name16)
forState:UIControlStateNormal];
......@@ -85,16 +85,26 @@ using l10n_util::GetNSStringF;
[signinPromoView.secondaryButton
setTitle:GetNSString(IDS_IOS_SIGNIN_PROMO_CHANGE_ACCOUNT)
forState:UIControlStateNormal];
UIImage* image = self.userImage;
if (!image) {
image = ios::GetChromeBrowserProvider()
->GetSigninResourcesProvider()
->GetDefaultAvatar();
}
[signinPromoView setProfileImage:image];
break;
}
case IdentityPromoViewModeSyncWithPrimaryAccount: {
[signinPromoView.primaryButton
setTitle:GetNSString(IDS_IOS_TAB_SWITCHER_ENABLE_SYNC_BUTTON)
forState:UIControlStateNormal];
signinPromoView.accessibilityLabel =
GetNSStringF(IDS_IOS_SIGNIN_PROMO_ACCESSIBILITY_LABEL, name16);
break;
}
}
DCHECK_NE(self.identityPromoViewMode, IdentityPromoViewModeNoAccounts);
UIImage* image = self.userImage;
if (!image) {
image = ios::GetChromeBrowserProvider()
->GetSigninResourcesProvider()
->GetDefaultAvatar();
}
[signinPromoView setProfileImage:image];
}
@end
......@@ -13,6 +13,8 @@ typedef NS_ENUM(NSInteger, IdentityPromoViewMode) {
// At least one identity is available on the device and the user can sign in
// without entering their credentials.
IdentityPromoViewModeSigninWithAccount,
// The user is signed in to Chrome and can enable Sync on the primary account.
IdentityPromoViewModeSyncWithPrimaryAccount,
};
extern NSString* const kSigninPromoViewId;
......
......@@ -11,18 +11,22 @@
@protocol SigninPromoViewDelegate <NSObject>
// Called by SigninPromoView when the user taps the primary button in cold state
// mode.
// Called by SigninPromoView when the user taps the primary button with no
// identities on the device.
- (void)signinPromoViewDidTapSigninWithNewAccount:(SigninPromoView*)view;
// Called by SigninPromoView when the user taps the primary button in warm state
// mode.
// Called by SigninPromoView when the user taps the primary button with one
// or more identities on the device.
- (void)signinPromoViewDidTapSigninWithDefaultAccount:(SigninPromoView*)view;
// Called by SigninPromoView when the user taps the secondary button in warm
// state mode.
// Called by SigninPromoView when the user taps the secondary button with one
// or more identities on the device.
- (void)signinPromoViewDidTapSigninWithOtherAccount:(SigninPromoView*)view;
// Called by SigninPromoView when the signed-in user taps the primary button
// to enable syncing with the default account.
- (void)signinPromoViewDidTapSyncWithDefaultAccount:(SigninPromoView*)view;
// Called by SigninPromoView when the user taps the close button.
- (void)signinPromoViewCloseButtonWasTapped:(SigninPromoView*)view;
......
......@@ -34,6 +34,13 @@ TEST_F(SigninPromoViewTest, ChromiumLogoImage) {
// The image should be different than the one set, since a circular background
// should have been added.
EXPECT_NE(customImage, view.imageView.image);
view.mode = IdentityPromoViewModeSyncWithPrimaryAccount;
EXPECT_NE(nil, view.imageView.image);
// The image should has been changed from the logo.
EXPECT_NE(chromiumLogo, view.imageView.image);
// The image should be different than the one set, since a circular background
// should have been added.
EXPECT_NE(customImage, view.imageView.image);
}
TEST_F(SigninPromoViewTest, SecondaryButtonVisibility) {
......@@ -45,4 +52,6 @@ TEST_F(SigninPromoViewTest, SecondaryButtonVisibility) {
EXPECT_TRUE(view.secondaryButton.hidden);
view.mode = IdentityPromoViewModeSigninWithAccount;
EXPECT_FALSE(view.secondaryButton.hidden);
view.mode = IdentityPromoViewModeSyncWithPrimaryAccount;
EXPECT_TRUE(view.secondaryButton.hidden);
}
......@@ -32,6 +32,10 @@ using chrome_test_util::WebStateScrollViewMatcher;
// Sign-in interaction tests that work with |kMobileIdentityConsistency|
// enabled.
@interface SigninCoordinatorMICETestCase : ChromeTestCase
// Signs in to the primary user account and disables Sync.
- (void)primaryAccountSignInWithSyncDisabled;
@end
@implementation SigninCoordinatorMICETestCase
......@@ -50,6 +54,20 @@ using chrome_test_util::WebStateScrollViewMatcher;
[ChromeEarlGrey clearBrowsingHistory];
}
// Simulates an interrupted sign-in flow in order to emulate signing in a
// default account with the Sync feature turned off.
- (void)primaryAccountSignInWithSyncDisabled {
[ChromeEarlGreyUI openSettingsMenu];
[ChromeEarlGreyUI tapSettingsMenuButton:PrimarySignInButton()];
// Select advanced Sync Settings link.
[SigninEarlGreyUI tapSettingsLink];
[ChromeEarlGreyUI waitForAppToIdle];
// Open new tab to cancel sign-in.
[ChromeEarlGrey simulateExternalAppURLOpening];
}
// Tests that opening the sign-in screen from the Settings and signing in works
// correctly when there is already an identity on the device.
- (void)testSignInFromSettingsMenu {
......@@ -78,15 +96,8 @@ using chrome_test_util::WebStateScrollViewMatcher;
- (void)testSignInFromSyncOffLink {
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[ChromeEarlGreyUI openSettingsMenu];
[ChromeEarlGreyUI tapSettingsMenuButton:PrimarySignInButton()];
// Select advanced Sync Settings link.
[SigninEarlGreyUI tapSettingsLink];
[ChromeEarlGreyUI waitForAppToIdle];
// Open new tab to cancel sign-in.
[ChromeEarlGrey simulateExternalAppURLOpening];
[self primaryAccountSignInWithSyncDisabled];
[ChromeEarlGreyUI openSettingsMenu];
// Check Sync Off label is visible and user is signed in.
......@@ -116,4 +127,87 @@ using chrome_test_util::WebStateScrollViewMatcher;
[ChromeEarlGreyUI waitForToolbarVisible:YES];
}
// Tests that the sign-in promo for no identities is displayed in Settings when
// the user is signed out and has not added any identities to the device.
- (void)testSigninPromoWithNoIdentitiesOnDevice {
[ChromeEarlGreyUI openSettingsMenu];
[SigninEarlGrey verifySignedOut];
[SigninEarlGreyUI
verifySigninPromoVisibleWithMode:IdentityPromoViewModeNoAccounts];
}
// Tests that the sign-in promo with user name is displayed in Settings when the
// user is signed out.
- (void)testSigninPromoWhenSignedOut {
// Add identity to the device.
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[ChromeEarlGreyUI openSettingsMenu];
[SigninEarlGrey verifySignedOut];
[SigninEarlGreyUI
verifySigninPromoVisibleWithMode:IdentityPromoViewModeSigninWithAccount];
}
// Tests that the sign-in promo is removed from Settings when the user
// is signed out and has closed the sign-in promo with user name.
- (void)testSigninPromoClosedWhenSignedOut {
// Add identity to the device.
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[ChromeEarlGreyUI openSettingsMenu];
[SigninEarlGreyUI
verifySigninPromoVisibleWithMode:IdentityPromoViewModeSigninWithAccount
closeButton:YES];
[[EarlGrey
selectElementWithMatcher:grey_allOf(grey_accessibilityID(
kSigninPromoCloseButtonId),
grey_sufficientlyVisible(), nil)]
performAction:grey_tap()];
[SigninEarlGrey verifySignedOut];
[SigninEarlGreyUI verifySigninPromoNotVisible];
}
// Tests that the sign-in promo for Sync is displayed when the user is signed in
// with Sync off.
- (void)testSigninPromoWhenSyncOff {
// Add identity to the device.
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[self primaryAccountSignInWithSyncDisabled];
[ChromeEarlGreyUI openSettingsMenu];
[SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
[SigninEarlGreyUI verifySigninPromoVisibleWithMode:
IdentityPromoViewModeSyncWithPrimaryAccount];
}
// Tests that no sign-in promo for Sync is displayed when the user is signed in
// with Sync off and has closed the sign-in promo for Sync.
- (void)testSigninPromoClosedWhenSyncOff {
// Add identity to the device.
FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
[SigninEarlGrey addFakeIdentity:fakeIdentity];
[self primaryAccountSignInWithSyncDisabled];
[ChromeEarlGreyUI openSettingsMenu];
[SigninEarlGreyUI verifySigninPromoVisibleWithMode:
IdentityPromoViewModeSyncWithPrimaryAccount];
// Tap on dismiss button.
[[EarlGrey
selectElementWithMatcher:grey_allOf(grey_accessibilityID(
kSigninPromoCloseButtonId),
grey_sufficientlyVisible(), nil)]
performAction:grey_tap()];
[SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
[SigninEarlGreyUI verifySigninPromoNotVisible];
}
@end
......@@ -168,6 +168,7 @@ using chrome_test_util::SignOutAccountsButton;
assertWithMatcher:grey_notNil()];
switch (mode) {
case IdentityPromoViewModeNoAccounts:
case IdentityPromoViewModeSyncWithPrimaryAccount:
[[EarlGrey
selectElementWithMatcher:grey_allOf(SecondarySignInButton(),
grey_sufficientlyVisible(), nil)]
......
......@@ -435,8 +435,14 @@ const char* AlreadySeenSigninViewPreferenceKey(
BOOL hasCloseButton =
AlreadySeenSigninViewPreferenceKey(self.accessPoint) != nullptr;
if (_defaultIdentity) {
AuthenticationService* authService =
AuthenticationServiceFactory::GetForBrowserState(_browserState);
IdentityPromoViewMode viewMode =
authService->IsAuthenticated()
? IdentityPromoViewModeSyncWithPrimaryAccount
: IdentityPromoViewModeSigninWithAccount;
return [[SigninPromoViewConfigurator alloc]
initWithIdentityPromoViewMode:IdentityPromoViewModeSigninWithAccount
initWithIdentityPromoViewMode:viewMode
userEmail:_defaultIdentity.userEmail
userFullName:_defaultIdentity.userFullName
userImage:self.identityAvatar
......@@ -676,6 +682,17 @@ const char* AlreadySeenSigninViewPreferenceKey(
[self showSigninWithIdentity:_defaultIdentity promoAction:promo_action];
}
- (void)signinPromoViewDidTapSyncWithDefaultAccount:
(SigninPromoView*)signinPromoView {
DCHECK(_defaultIdentity);
DCHECK(self.signinPromoViewVisible);
DCHECK(!self.invalidClosedOrNeverVisible);
// TODO(crbug.com/1166232): Record Sync impressions.
[self showSigninWithIdentity:_defaultIdentity
promoAction:signin_metrics::PromoAction::
PROMO_ACTION_WITH_DEFAULT];
}
- (void)signinPromoViewDidTapSigninWithOtherAccount:
(SigninPromoView*)signinPromoView {
DCHECK(_defaultIdentity);
......
......@@ -12,12 +12,18 @@
#include "components/prefs/pref_service.h"
#include "components/signin/public/base/signin_metrics.h"
#import "components/signin/public/base/signin_pref_names.h"
#import "components/sync/driver/mock_sync_service.h"
#import "components/sync_preferences/pref_service_mock_factory.h"
#import "components/sync_preferences/pref_service_syncable.h"
#import "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#import "ios/chrome/browser/chrome_switches.h"
#import "ios/chrome/browser/prefs/browser_prefs.h"
#import "ios/chrome/browser/signin/authentication_service_factory.h"
#import "ios/chrome/browser/signin/authentication_service_fake.h"
#include "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h"
#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
#import "ios/chrome/browser/sync/sync_setup_service_factory.h"
#import "ios/chrome/browser/sync/sync_setup_service_mock.h"
#import "ios/chrome/browser/ui/authentication/cells/signin_promo_view.h"
#import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h"
#import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_constants.h"
......@@ -47,12 +53,27 @@ using user_prefs::PrefRegistrySyncable;
using web::WebTaskEnvironment;
namespace {
std::unique_ptr<KeyedService> BuildMockSyncService(web::BrowserState* context) {
return std::make_unique<syncer::MockSyncService>();
}
class SigninPromoViewMediatorTest : public PlatformTest {
protected:
void SetUp() override {
user_full_name_ = @"John Doe";
close_button_hidden_ = YES;
TestChromeBrowserState::Builder builder;
builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
base::BindRepeating(&BuildMockSyncService));
builder.AddTestingFactory(
SyncSetupServiceFactory::GetInstance(),
base::BindRepeating(&SyncSetupServiceMock::CreateKeyedService));
builder.AddTestingFactory(
AuthenticationServiceFactory::GetInstance(),
base::BindRepeating(
&AuthenticationServiceFake::CreateAuthenticationService));
chrome_browser_state_ = builder.Build();
}
void TearDown() override {
......@@ -73,10 +94,10 @@ class SigninPromoViewMediatorTest : public PlatformTest {
void CreateMediator(signin_metrics::AccessPoint accessPoint) {
consumer_ = OCMStrictProtocolMock(@protocol(SigninPromoViewConsumer));
mediator_ =
[[SigninPromoViewMediator alloc] initWithBrowserState:nil
accessPoint:accessPoint
presenter:nil];
mediator_ = [[SigninPromoViewMediator alloc]
initWithBrowserState:chrome_browser_state_.get()
accessPoint:accessPoint
presenter:nil];
mediator_.consumer = consumer_;
signin_promo_view_ = OCMStrictClassMock([SigninPromoView class]);
......@@ -209,6 +230,7 @@ class SigninPromoViewMediatorTest : public PlatformTest {
// Task environment.
WebTaskEnvironment task_environment_;
std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
// Mediator used for the tests.
SigninPromoViewMediator* mediator_;
......
......@@ -115,10 +115,10 @@ using chrome_test_util::SecondarySignInButton;
[BookmarkEarlGrey verifyPromoAlreadySeen:YES];
}
// Tests the tapping on the primary button of sign-in promo view in a cold
// state makes the sign-in sheet appear, and the promo still appears after
// dismissing the sheet.
- (void)testSignInPromoWithColdStateUsingPrimaryButton {
// Tests the tapping on the primary button of sign-in promo view with no
// identities on device makes the sign-in sheet appear, and the promo still
// appears after dismissing the sheet.
- (void)testSignInPromoWithNoIdentitiesUsingPrimaryButton {
[BookmarkEarlGreyUI openBookmarks];
// Check that sign-in promo view are visible.
......@@ -142,10 +142,10 @@ using chrome_test_util::SecondarySignInButton;
verifySigninPromoVisibleWithMode:IdentityPromoViewModeNoAccounts];
}
// Tests the tapping on the primary button of sign-in promo view in a warm
// state makes the confirmaiton sheet appear, and the promo still appears after
// dismissing the sheet.
- (void)testSignInPromoWithWarmStateUsingPrimaryButton {
// Tests the tapping on the primary button of sign-in promo view with identities
// on device makes the confirmaiton sheet appear, and the promo still appears
// after dismissing the sheet.
- (void)testSignInPromoWithIdentitiesUsingPrimaryButton {
[BookmarkEarlGrey setupStandardBookmarks];
[BookmarkEarlGreyUI openBookmarks];
......@@ -175,10 +175,10 @@ using chrome_test_util::SecondarySignInButton;
[BookmarkEarlGrey verifyPromoAlreadySeen:NO];
}
// Tests the tapping on the secondary button of sign-in promo view in a warm
// state makes the sign-in sheet appear, and the promo still appears after
// dismissing the sheet.
- (void)testSignInPromoWithWarmStateUsingSecondaryButton {
// Tests the tapping on the secondary button of sign-in promo view with
// identities on device makes the sign-in sheet appear, and the promo still
// appears after dismissing the sheet.
- (void)testSignInPromoWithIdentitiesUsingSecondaryButton {
[BookmarkEarlGrey setupStandardBookmarks];
[BookmarkEarlGreyUI openBookmarks];
......
......@@ -290,7 +290,7 @@ GURL TestPageURL() {
}
}
// Tests that the Cold Mode Signin promo is visible in the Other Devices section
// Tests that the Signin promo is visible in the Other Devices section
// (and with illustrated-empty-states enabled, there is the illustrated cell)
- (void)testOtherDevicesDefaultEmptyState {
OpenRecentTabsPanel();
......
......@@ -392,63 +392,9 @@ SyncState GetSyncStateFromBrowserState(ChromeBrowserState* browserState) {
TableViewModel<TableViewItem*>* model = self.tableViewModel;
AuthenticationService* authService =
AuthenticationServiceFactory::GetForBrowserState(_browserState);
// If sign-in is disabled by policy, replace the sign-in / account section
// with an info button view item.
if (!signin::IsSigninAllowed(_browserState->GetPrefs())) {
[model addSectionWithIdentifier:SettingsSectionIdentifierSignIn];
[model addItem:[self signinDisabledTextItem]
toSectionWithIdentifier:SettingsSectionIdentifierSignIn];
} else if (!authService->IsAuthenticated()) {
// Sign in section
[model addSectionWithIdentifier:SettingsSectionIdentifierSignIn];
if ([SigninPromoViewMediator
shouldDisplaySigninPromoViewWithAccessPoint:
signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS
browserState:_browserState]) {
if (!_signinPromoViewMediator) {
_signinPromoViewMediator = [[SigninPromoViewMediator alloc]
initWithBrowserState:_browserState
accessPoint:signin_metrics::AccessPoint::
ACCESS_POINT_SETTINGS
presenter:self /* id<SigninPresenter> */];
_signinPromoViewMediator.consumer = self;
}
} else {
[_signinPromoViewMediator signinPromoViewIsRemoved];
_signinPromoViewMediator = nil;
}
[model addItem:[self signInTextItem]
toSectionWithIdentifier:SettingsSectionIdentifierSignIn];
} else {
// Account section
[model addSectionWithIdentifier:SettingsSectionIdentifierAccount];
_hasRecordedSigninImpression = NO;
[_signinPromoViewMediator signinPromoViewIsRemoved];
_signinPromoViewMediator = nil;
[model addItem:[self accountCellItem]
toSectionWithIdentifier:SettingsSectionIdentifierAccount];
}
if (![model
hasSectionForSectionIdentifier:SettingsSectionIdentifierAccount]) {
// Add the Account section for the Sync & Google services cell, if the user
// is signed-out.
[model addSectionWithIdentifier:SettingsSectionIdentifierAccount];
}
// Adds experimental Google Services item separate from Sync.
if (base::FeatureList::IsEnabled(signin::kMobileIdentityConsistency)) {
if (authService->IsAuthenticated()) {
[model addItem:[self googleSyncDetailItem]
toSectionWithIdentifier:SettingsSectionIdentifierAccount];
}
[model addItem:[self googleServicesCellItem]
toSectionWithIdentifier:SettingsSectionIdentifierAccount];
} else {
[model addItem:[self syncAndGoogleServicesCellItem]
toSectionWithIdentifier:SettingsSectionIdentifierAccount];
}
[self addPromoToIdentitySection];
[self addAccountProfileToIdentitySection];
[self addSyncAndGoogleServicesToIdentitySection];
// Defaults section.
if (@available(iOS 14, *)) {
......@@ -531,6 +477,138 @@ SyncState GetSyncStateFromBrowserState(ChromeBrowserState* browserState) {
#endif // BUILDFLAG(CHROMIUM_BRANDING) && !defined(NDEBUG)
}
// Adds the identity promo to promote the sign-in or sync state.
- (void)addPromoToIdentitySection {
TableViewModel<TableViewItem*>* model = self.tableViewModel;
[model addSectionWithIdentifier:SettingsSectionIdentifierSignIn];
AuthenticationService* authService =
AuthenticationServiceFactory::GetForBrowserState(_browserState);
if ((authService->IsAuthenticated() && self.shouldDisplaySyncPromo) ||
(!authService->IsAuthenticated() && self.shouldDisplaySigninPromo)) {
if (!_signinPromoViewMediator) {
_signinPromoViewMediator = [[SigninPromoViewMediator alloc]
initWithBrowserState:_browserState
accessPoint:signin_metrics::AccessPoint::
ACCESS_POINT_SETTINGS
presenter:self /* id<SigninPresenter> */];
_signinPromoViewMediator.consumer = self;
}
TableViewSigninPromoItem* identityPromoItem =
[[TableViewSigninPromoItem alloc]
initWithType:SettingsItemTypeSigninPromo];
identityPromoItem.text =
l10n_util::GetNSString(IDS_IOS_SIGNIN_PROMO_SETTINGS_WITH_UNITY);
identityPromoItem.configurator =
[_signinPromoViewMediator createConfigurator];
identityPromoItem.delegate = _signinPromoViewMediator;
[_signinPromoViewMediator signinPromoViewIsVisible];
[model addItem:identityPromoItem
toSectionWithIdentifier:SettingsSectionIdentifierSignIn];
} else if (!authService->IsAuthenticated()) {
[_signinPromoViewMediator signinPromoViewIsRemoved];
_signinPromoViewMediator = nil;
if (!_hasRecordedSigninImpression) {
// Once the Settings are open, this button impression will at most be
// recorded once until they are closed.
signin_metrics::RecordSigninImpressionUserActionForAccessPoint(
signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS);
_hasRecordedSigninImpression = YES;
}
}
}
// Adds the account profile to the Identity section if the user is signed in and
// sign-in is not disabled by policy.
- (void)addAccountProfileToIdentitySection {
// If sign-in is disabled by policy, replace the sign-in / account section
// with an info button view item.
TableViewModel<TableViewItem*>* model = self.tableViewModel;
if (!signin::IsSigninAllowed(_browserState->GetPrefs())) {
[model addItem:[self signinDisabledTextItem]
toSectionWithIdentifier:SettingsSectionIdentifierSignIn];
return;
}
AuthenticationService* authService =
AuthenticationServiceFactory::GetForBrowserState(_browserState);
if (authService->IsAuthenticated()) {
// Account profile item.
[model addSectionWithIdentifier:SettingsSectionIdentifierAccount];
[model addItem:[self accountCellItem]
toSectionWithIdentifier:SettingsSectionIdentifierAccount];
_hasRecordedSigninImpression = NO;
} else if (!authService->IsAuthenticated() &&
!self.shouldDisplaySigninPromo) {
// Signed-out default
AccountSignInItem* signInTextItem =
[[AccountSignInItem alloc] initWithType:SettingsItemTypeSignInButton];
signInTextItem.accessibilityIdentifier = kSettingsSignInCellId;
signInTextItem.detailText =
l10n_util::GetNSString(IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SUBTITLE);
[model addItem:signInTextItem
toSectionWithIdentifier:SettingsSectionIdentifierSignIn];
}
}
// Adds the Sync & Google Services options to the Identity section.
- (void)addSyncAndGoogleServicesToIdentitySection {
// Add the Account section for the Sync & Google services cell, if the
// user is signed-out.
TableViewModel<TableViewItem*>* model = self.tableViewModel;
if (![model
hasSectionForSectionIdentifier:SettingsSectionIdentifierAccount]) {
[model addSectionWithIdentifier:SettingsSectionIdentifierAccount];
}
if (base::FeatureList::IsEnabled(signin::kMobileIdentityConsistency)) {
AuthenticationService* authService =
AuthenticationServiceFactory::GetForBrowserState(_browserState);
// Sync item.
if (authService->IsAuthenticated()) {
[model addItem:[self googleSyncDetailItem]
toSectionWithIdentifier:SettingsSectionIdentifierAccount];
}
// Google Services item.
[model addItem:[self googleServicesCellItem]
toSectionWithIdentifier:SettingsSectionIdentifierAccount];
} else {
// Sync & Google Services item.
[model addItem:[self syncAndGoogleServicesCellItem]
toSectionWithIdentifier:SettingsSectionIdentifierAccount];
}
}
#pragma mark - Properties
// Returns YES if the sign-in promo has not previously been closed or seen
// too many times by a single user account (as defined in
// SigninPromoViewMediator).
- (BOOL)shouldDisplaySigninPromo {
return [SigninPromoViewMediator
shouldDisplaySigninPromoViewWithAccessPoint:signin_metrics::AccessPoint::
ACCESS_POINT_SETTINGS
browserState:_browserState];
}
// Returns YES if the Sync service is available and all promos have not been
// previously closed or seen too many times by a single user account.
- (BOOL)shouldDisplaySyncPromo {
syncer::SyncService* syncService =
ProfileSyncServiceFactory::GetForBrowserState(_browserState);
return base::FeatureList::IsEnabled(signin::kMobileIdentityConsistency) &&
// TODO(crbug.com/1166232): Replace with Sync specific metrics.
[SigninPromoViewMediator
shouldDisplaySigninPromoViewWithAccessPoint:
signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS
browserState:_browserState] &&
(!syncService->IsSyncFeatureActive() &&
syncService->GetTransportState() !=
syncer::SyncService::TransportState::INITIALIZING);
}
#pragma mark - Model Items
- (TableViewItem*)signInTextItem {
......
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