Commit 753c2f64 authored by Nohemi Fernandez's avatar Nohemi Fernandez Committed by Commit Bot

[iOS] Add feature to intercept sign-in on Google web.

Intercepts a user tap on sign-in to display an account consistency
promo that is to be defined.

Bug: 1125631
Change-Id: Id8c84e066b0f9c5a3c61dd88de6716da75320bb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2398523
Commit-Queue: Nohemi Fernandez <fernandex@chromium.org>
Reviewed-by: default avatarSylvain Defresne <sdefresne@chromium.org>
Reviewed-by: default avatarAlice Wang <aliceywang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805321}
parent 72b35a8c
...@@ -33,7 +33,7 @@ const char kIsSamlAttrName[] = "is_saml"; ...@@ -33,7 +33,7 @@ const char kIsSamlAttrName[] = "is_saml";
const char kProfileModeAttrName[] = "mode"; const char kProfileModeAttrName[] = "mode";
const char kServiceTypeAttrName[] = "action"; const char kServiceTypeAttrName[] = "action";
const char kSourceAttrName[] = "source"; const char kSourceAttrName[] = "source";
#if defined(OS_ANDROID) #if defined(OS_ANDROID) || defined(OS_IOS)
const char kEligibleForConsistency[] = "eligible_for_consistency"; const char kEligibleForConsistency[] = "eligible_for_consistency";
const char kShowConsistencyPromo[] = "show_consistency_promo"; const char kShowConsistencyPromo[] = "show_consistency_promo";
#endif #endif
...@@ -96,7 +96,7 @@ ManageAccountsParams ChromeConnectedHeaderHelper::BuildManageAccountsParams( ...@@ -96,7 +96,7 @@ ManageAccountsParams ChromeConnectedHeaderHelper::BuildManageAccountsParams(
params.continue_url = value; params.continue_url = value;
} else if (key_name == kIsSameTabAttrName) { } else if (key_name == kIsSameTabAttrName) {
params.is_same_tab = value == "true"; params.is_same_tab = value == "true";
#if defined(OS_ANDROID) #if defined(OS_ANDROID) || defined(OS_IOS)
} else if (key_name == kShowConsistencyPromo) { } else if (key_name == kShowConsistencyPromo) {
params.show_consistency_promo = value == "true"; params.show_consistency_promo = value == "true";
#endif #endif
...@@ -188,20 +188,20 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader( ...@@ -188,20 +188,20 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
} }
// If we are on mobile or desktop, an empty |account_id| corresponds to the user // If we are on mobile or desktop, an empty |account_id| corresponds to the user
// not signed into Sync. Do not enforce account consistency, unless Mice is // not signed into Sync. Do not enforce account consistency, unless Mice is
// enabled on Android. // enabled on mobile (Android or iOS).
// On Chrome OS, an empty |account_id| corresponds to Public Sessions, Guest // On Chrome OS, an empty |account_id| corresponds to Public Sessions, Guest
// Sessions and Active Directory logins. Guest Sessions have already been // Sessions and Active Directory logins. Guest Sessions have already been
// filtered upstream and we want to enforce account consistency in Public // filtered upstream and we want to enforce account consistency in Public
// Sessions and Active Directory logins. // Sessions and Active Directory logins.
#if !defined(OS_CHROMEOS) #if !defined(OS_CHROMEOS)
if (!force_account_consistency && gaia_id.empty()) { if (!force_account_consistency && gaia_id.empty()) {
#if defined(OS_ANDROID) #if defined(OS_ANDROID) || defined(OS_IOS)
if (base::FeatureList::IsEnabled(kMobileIdentityConsistency)) { if (base::FeatureList::IsEnabled(kMobileIdentityConsistency)) {
parts.push_back( parts.push_back(
base::StringPrintf("%s=%s", kEligibleForConsistency, "true")); base::StringPrintf("%s=%s", kEligibleForConsistency, "true"));
return base::JoinString(parts, is_header_request ? "," : ":"); return base::JoinString(parts, is_header_request ? "," : ":");
} }
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID) || defined(OS_IOS)
return std::string(); return std::string();
} }
#endif // !defined(OS_CHROMEOS) #endif // !defined(OS_CHROMEOS)
......
...@@ -77,7 +77,7 @@ struct ManageAccountsParams { ...@@ -77,7 +77,7 @@ struct ManageAccountsParams {
std::string continue_url; std::string continue_url;
// Whether the continue URL should be loaded in the same tab. // Whether the continue URL should be loaded in the same tab.
bool is_same_tab; bool is_same_tab;
#if defined(OS_ANDROID) #if defined(OS_ANDROID) || defined(OS_IOS)
// Whether to show consistency promo. // Whether to show consistency promo.
bool show_consistency_promo; bool show_consistency_promo;
#endif #endif
......
...@@ -160,10 +160,11 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdChromeOS) { ...@@ -160,10 +160,11 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdChromeOS) {
"consistency_enabled_by_default=false"); "consistency_enabled_by_default=false");
} }
#else // !defined(OS_CHROMEOS) #else // !defined(OS_CHROMEOS)
#if defined(OS_ANDROID) #if defined(OS_ANDROID) || defined(OS_IOS)
// Tests that Mirror request is returned on Android for Public Sessions (no // Tests that Mirror request is returned on mobile (Android, iOS) for Public
// account id), when the Mobile Identity Consistency feature is enabled. // Sessions (no account id), when the Mobile Identity Consistency feature is
TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdAndroid) { // enabled.
TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdMobile) {
base::test::ScopedFeatureList feature_list; base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(kMobileIdentityConsistency); feature_list.InitAndEnableFeature(kMobileIdentityConsistency);
...@@ -176,7 +177,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdAndroid) { ...@@ -176,7 +177,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdAndroid) {
// Tests that the full Mirror request is returned when the // Tests that the full Mirror request is returned when the
// force_account_consistency param is true. // force_account_consistency param is true.
TEST_F(SigninHeaderHelperTest, TestForceAccountConsistencyAndroid) { TEST_F(SigninHeaderHelperTest, TestForceAccountConsistencyMobile) {
base::test::ScopedFeatureList feature_list; base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(kMobileIdentityConsistency); feature_list.InitAndEnableFeature(kMobileIdentityConsistency);
...@@ -187,7 +188,7 @@ TEST_F(SigninHeaderHelperTest, TestForceAccountConsistencyAndroid) { ...@@ -187,7 +188,7 @@ TEST_F(SigninHeaderHelperTest, TestForceAccountConsistencyAndroid) {
"source=TestSource,mode=0,enable_account_consistency=true," "source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false"); "consistency_enabled_by_default=false");
} }
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID) || defined(OS_IOS)
// Tests that no Mirror request is returned when the user is not signed in (no // Tests that no Mirror request is returned when the user is not signed in (no
// account id), for non Chrome OS platforms. // account id), for non Chrome OS platforms.
...@@ -592,6 +593,7 @@ TEST_F(SigninHeaderHelperTest, TestInvalidManageAccountsParams) { ...@@ -592,6 +593,7 @@ TEST_F(SigninHeaderHelperTest, TestInvalidManageAccountsParams) {
EXPECT_EQ(GAIA_SERVICE_TYPE_NONE, params.service_type); EXPECT_EQ(GAIA_SERVICE_TYPE_NONE, params.service_type);
} }
// Tests that managed accounts' header is parsed correctly from string input.
TEST_F(SigninHeaderHelperTest, TestBuildManageAccountsParams) { TEST_F(SigninHeaderHelperTest, TestBuildManageAccountsParams) {
const char kContinueURL[] = "https://www.example.com/continue"; const char kContinueURL[] = "https://www.example.com/continue";
const char kEmail[] = "foo@example.com"; const char kEmail[] = "foo@example.com";
...@@ -600,7 +602,7 @@ TEST_F(SigninHeaderHelperTest, TestBuildManageAccountsParams) { ...@@ -600,7 +602,7 @@ TEST_F(SigninHeaderHelperTest, TestBuildManageAccountsParams) {
"action=ADDSESSION,email=%s,is_saml=true," "action=ADDSESSION,email=%s,is_saml=true,"
"is_same_tab=true,continue_url=%s", "is_same_tab=true,continue_url=%s",
kEmail, kContinueURL); kEmail, kContinueURL);
#if defined(OS_ANDROID) #if defined(OS_ANDROID) || defined(OS_IOS)
header += ",show_consistency_promo=true"; header += ",show_consistency_promo=true";
#endif #endif
...@@ -610,7 +612,7 @@ TEST_F(SigninHeaderHelperTest, TestBuildManageAccountsParams) { ...@@ -610,7 +612,7 @@ TEST_F(SigninHeaderHelperTest, TestBuildManageAccountsParams) {
EXPECT_EQ(true, params.is_saml); EXPECT_EQ(true, params.is_saml);
EXPECT_EQ(true, params.is_same_tab); EXPECT_EQ(true, params.is_same_tab);
EXPECT_EQ(GURL(kContinueURL), params.continue_url); EXPECT_EQ(GURL(kContinueURL), params.continue_url);
#if defined(OS_ANDROID) #if defined(OS_ANDROID) || defined(OS_IOS)
EXPECT_EQ(true, params.show_consistency_promo); EXPECT_EQ(true, params.show_consistency_promo);
#endif #endif
} }
......
...@@ -115,7 +115,8 @@ void AccountConsistencyHandler::ShouldAllowResponse( ...@@ -115,7 +115,8 @@ void AccountConsistencyHandler::ShouldAllowResponse(
return; return;
} }
NSString* manage_accounts_header = [[http_response allHeaderFields] NSString* manage_accounts_header = [[http_response allHeaderFields]
objectForKey:@"X-Chrome-Manage-Accounts"]; objectForKey:
[NSString stringWithUTF8String:signin::kChromeManageAccountsHeader]];
if (!manage_accounts_header) { if (!manage_accounts_header) {
std::move(callback).Run(PolicyDecision::Allow()); std::move(callback).Run(PolicyDecision::Allow());
return; return;
...@@ -135,7 +136,11 @@ void AccountConsistencyHandler::ShouldAllowResponse( ...@@ -135,7 +136,11 @@ void AccountConsistencyHandler::ShouldAllowResponse(
} }
case signin::GAIA_SERVICE_TYPE_SIGNUP: case signin::GAIA_SERVICE_TYPE_SIGNUP:
case signin::GAIA_SERVICE_TYPE_ADDSESSION: case signin::GAIA_SERVICE_TYPE_ADDSESSION:
[delegate_ onAddAccount]; if (params.show_consistency_promo) {
[delegate_ onShowConsistencyPromo];
} else {
[delegate_ onAddAccount];
}
break; break;
case signin::GAIA_SERVICE_TYPE_SIGNOUT: case signin::GAIA_SERVICE_TYPE_SIGNOUT:
case signin::GAIA_SERVICE_TYPE_DEFAULT: case signin::GAIA_SERVICE_TYPE_DEFAULT:
......
...@@ -440,6 +440,61 @@ TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsDefault) { ...@@ -440,6 +440,61 @@ TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsDefault) {
EXPECT_OCMOCK_VERIFY(delegate); EXPECT_OCMOCK_VERIFY(delegate);
} }
// Tests that the ManageAccountsDelegate is notified when a navigation on Gaia
// signon realm returns with a X-Chrome-Manage-Accounts header with show
// consistency promo and ADDSESSION action.
TEST_F(AccountConsistencyServiceTest,
ChromeManageAccountsShowConsistencyPromo) {
id delegate =
[OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)];
[[delegate expect] onShowConsistencyPromo];
NSDictionary* headers = [NSDictionary
dictionaryWithObject:@"action=ADDSESSION,show_consistency_promo=true"
forKey:@"X-Chrome-Manage-Accounts"];
NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
statusCode:200
HTTPVersion:@"HTTP/1.1"
headerFields:headers];
account_consistency_service_->SetWebStateHandler(&web_state_, delegate);
EXPECT_CALL(*account_reconcilor_, OnReceivedManageAccountsResponse(
signin::GAIA_SERVICE_TYPE_ADDSESSION))
.Times(1);
EXPECT_FALSE(
web_state_.ShouldAllowResponse(response, /* for_main_frame = */ true));
web_state_.WebStateDestroyed();
EXPECT_OCMOCK_VERIFY(delegate);
}
// Tests that the ManageAccountsDelegate is notified when a navigation on Gaia
// signon realm returns with a X-Chrome-Manage-Accounts header with ADDSESSION
// action.
TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsShowAddAccount) {
id delegate =
[OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)];
[[delegate expect] onAddAccount];
NSDictionary* headers =
[NSDictionary dictionaryWithObject:@"action=ADDSESSION"
forKey:@"X-Chrome-Manage-Accounts"];
NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
statusCode:200
HTTPVersion:@"HTTP/1.1"
headerFields:headers];
account_consistency_service_->SetWebStateHandler(&web_state_, delegate);
EXPECT_CALL(*account_reconcilor_, OnReceivedManageAccountsResponse(
signin::GAIA_SERVICE_TYPE_ADDSESSION))
.Times(1);
EXPECT_FALSE(
web_state_.ShouldAllowResponse(response, /* for_main_frame = */ true));
web_state_.WebStateDestroyed();
EXPECT_OCMOCK_VERIFY(delegate);
}
// Tests that domains with cookie are correctly loaded from the prefs on service // Tests that domains with cookie are correctly loaded from the prefs on service
// startup. // startup.
TEST_F(AccountConsistencyServiceTest, DomainsWithCookieLoadedFromPrefs) { TEST_F(AccountConsistencyServiceTest, DomainsWithCookieLoadedFromPrefs) {
......
...@@ -16,6 +16,10 @@ class GURL; ...@@ -16,6 +16,10 @@ class GURL;
// Called when the user taps on an add account button in a Google web property. // Called when the user taps on an add account button in a Google web property.
- (void)onAddAccount; - (void)onAddAccount;
// Called when the user taps a sign-in or add account button in a Google web
// property with signin::kMobileIdentityConsistency enabled.
- (void)onShowConsistencyPromo;
// Called when the user taps on go incognito button in a Google web property. // Called when the user taps on go incognito button in a Google web property.
// |url| is the continuation URL received from the server. If it is valid, // |url| is the continuation URL received from the server. If it is valid,
// then this delegate should open an incognito tab and navigate to |url|. // then this delegate should open an incognito tab and navigate to |url|.
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
namespace signin { namespace signin {
// Do not merge the two feature flags.
// Experiments for MICE will be run independently per platform (Android, iOS).
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
const base::Feature kMobileIdentityConsistency{ const base::Feature kMobileIdentityConsistency{
"MobileIdentityConsistency", base::FEATURE_DISABLED_BY_DEFAULT}; "MobileIdentityConsistency", base::FEATURE_DISABLED_BY_DEFAULT};
......
...@@ -465,6 +465,10 @@ class PreloadJavaScriptDialogPresenter : public web::JavaScriptDialogPresenter { ...@@ -465,6 +465,10 @@ class PreloadJavaScriptDialogPresenter : public web::JavaScriptDialogPresenter {
[self schedulePrerenderCancel]; [self schedulePrerenderCancel];
} }
- (void)onShowConsistencyPromo {
[self schedulePrerenderCancel];
}
- (void)onAddAccount { - (void)onAddAccount {
[self schedulePrerenderCancel]; [self schedulePrerenderCancel];
} }
......
...@@ -4689,6 +4689,13 @@ NSString* const kBrowserViewControllerSnackbarCategory = ...@@ -4689,6 +4689,13 @@ NSString* const kBrowserViewControllerSnackbarCategory =
[self.dispatcher showAccountsSettingsFromViewController:self]; [self.dispatcher showAccountsSettingsFromViewController:self];
} }
- (void)onShowConsistencyPromo {
signin_metrics::LogAccountReconcilorStateOnGaiaResponse(
ios::AccountReconcilorFactory::GetForBrowserState(self.browserState)
->GetState());
[self.dispatcher showConsistencyPromoFromViewController:self];
}
- (void)onAddAccount { - (void)onAddAccount {
signin_metrics::LogAccountReconcilorStateOnGaiaResponse( signin_metrics::LogAccountReconcilorStateOnGaiaResponse(
ios::AccountReconcilorFactory::GetForBrowserState(self.browserState) ios::AccountReconcilorFactory::GetForBrowserState(self.browserState)
......
...@@ -136,6 +136,12 @@ enum class KeyRetrievalTriggerForUMA; ...@@ -136,6 +136,12 @@ enum class KeyRetrievalTriggerForUMA;
// Shows the Add Account UI, presenting from |baseViewController|. // Shows the Add Account UI, presenting from |baseViewController|.
- (void)showAddAccountFromViewController:(UIViewController*)baseViewController; - (void)showAddAccountFromViewController:(UIViewController*)baseViewController;
// TODO(crbug.com/779791) : Do not pass baseViewController through dispatcher.
// Shows the consistency promo UI that allows users to sign in to Chrome using
// the default accounts on the device.
- (void)showConsistencyPromoFromViewController:
(UIViewController*)baseViewController;
// Sets whether the UI is displaying incognito content. // Sets whether the UI is displaying incognito content.
- (void)setIncognitoContentVisible:(BOOL)incognitoContentVisible; - (void)setIncognitoContentVisible:(BOOL)incognitoContentVisible;
......
...@@ -994,6 +994,12 @@ const char kMultiWindowOpenInNewWindowHistogram[] = ...@@ -994,6 +994,12 @@ const char kMultiWindowOpenInNewWindowHistogram[] =
[self startSigninCoordinatorWithCompletion:nil]; [self startSigninCoordinatorWithCompletion:nil];
} }
- (void)showConsistencyPromoFromViewController:
(UIViewController*)baseViewController {
DCHECK(!self.signinCoordinator);
// TODO(crbug.com/1125631): Add new consistency promo UI to enable sign-in.
}
- (void)setIncognitoContentVisible:(BOOL)incognitoContentVisible { - (void)setIncognitoContentVisible:(BOOL)incognitoContentVisible {
_incognitoContentVisible = incognitoContentVisible; _incognitoContentVisible = incognitoContentVisible;
} }
......
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