Handle ListAccount fetches and watching the GAIA cookies from within the GaiaCookieManagerService.
This CL only implements non-ChromeOS features; AboutSigninInterals and the AccountReconcilor. ChromeOS features will come later, as they require more support. This CL also removes the ReconcilorSource as a parameter to ListAccounts. Changes the observed cookie from the LSID cookie to the APISID cookie at nickk@'s suggestion.
Design doc: https://docs.google.com/document/d/1FfmSS7M87L_2tkVuHO3NuruborFm6qHXe2VdktZg-HQ/
BUG=466799, 463611, 471210
Review URL: https://codereview.chromium.org/1075273002
Cr-Commit-Position: refs/heads/master@{#326846}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index c6925c3..709fd0c 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -948,10 +948,10 @@
"sessions/session_restore_test_helper.h",
"sessions/session_service_test_helper.cc",
"sessions/session_service_test_helper.h",
- "signin/fake_account_reconcilor.cc",
- "signin/fake_account_reconcilor.h",
"signin/fake_account_tracker_service.cc",
"signin/fake_account_tracker_service.h",
+ "signin/fake_gaia_cookie_manager_service.cc",
+ "signin/fake_gaia_cookie_manager_service.h",
"signin/fake_profile_oauth2_token_service.cc",
"signin/fake_profile_oauth2_token_service.h",
"signin/fake_profile_oauth2_token_service_builder.cc",
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc
index 1d4ba1e..2debe5b0 100644
--- a/chrome/browser/extensions/api/identity/identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -19,12 +19,12 @@
#include "chrome/browser/extensions/extension_function_test_utils.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/account_reconcilor_factory.h"
#include "chrome/browser/signin/account_tracker_service_factory.h"
-#include "chrome/browser/signin/fake_account_reconcilor.h"
+#include "chrome/browser/signin/fake_gaia_cookie_manager_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
#include "chrome/browser/signin/fake_signin_manager.h"
+#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/ui/browser.h"
@@ -555,8 +555,8 @@
context, &FakeSigninManagerBase::Build);
ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
context, &BuildFakeProfileOAuth2TokenService);
- AccountReconcilorFactory::GetInstance()->SetTestingFactory(
- context, &FakeAccountReconcilor::Build);
+ GaiaCookieManagerServiceFactory::GetInstance()->SetTestingFactory(
+ context, &FakeGaiaCookieManagerService::Build);
}
void SetUpOnMainThread() override {
@@ -570,6 +570,8 @@
ProfileOAuth2TokenServiceFactory::GetInstance()->GetForProfile(
profile()));
ASSERT_TRUE(token_service_);
+ GaiaCookieManagerServiceFactory::GetInstance()->GetForProfile(profile())
+ ->Init();
}
protected:
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 6ccb91d..b20c703 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -39,6 +39,7 @@
#include "chrome/browser/profiles/startup_task_runner_service_factory.h"
#include "chrome/browser/signin/account_reconcilor_factory.h"
#include "chrome/browser/signin/account_tracker_service_factory.h"
+#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
@@ -56,6 +57,7 @@
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/signin/core/browser/account_tracker_service.h"
+#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "components/signin/core/common/profile_management_switches.h"
#include "content/public/browser/browser_thread.h"
@@ -1053,6 +1055,7 @@
DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile)->
MaybeActivateDataReductionProxy(true);
+ GaiaCookieManagerServiceFactory::GetForProfile(profile)->Init();
AccountTrackerServiceFactory::GetForProfile(profile)->EnableNetworkFetches();
AccountReconcilorFactory::GetForProfile(profile);
}
diff --git a/chrome/browser/signin/about_signin_internals_factory.cc b/chrome/browser/signin/about_signin_internals_factory.cc
index 1236d9e..e2091824 100644
--- a/chrome/browser/signin/about_signin_internals_factory.cc
+++ b/chrome/browser/signin/about_signin_internals_factory.cc
@@ -8,6 +8,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_error_controller_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
@@ -27,6 +28,7 @@
BrowserContextDependencyManager::GetInstance()) {
DependsOn(AccountTrackerServiceFactory::GetInstance());
DependsOn(ChromeSigninClientFactory::GetInstance());
+ DependsOn(GaiaCookieManagerServiceFactory::GetInstance());
DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
DependsOn(SigninErrorControllerFactory::GetInstance());
DependsOn(SigninManagerFactory::GetInstance());
@@ -85,7 +87,8 @@
ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
AccountTrackerServiceFactory::GetForProfile(profile),
SigninManagerFactory::GetForProfile(profile),
- SigninErrorControllerFactory::GetForProfile(profile));
+ SigninErrorControllerFactory::GetForProfile(profile),
+ GaiaCookieManagerServiceFactory::GetForProfile(profile));
service->Initialize(ChromeSigninClientFactory::GetForProfile(profile));
return service;
}
diff --git a/chrome/browser/signin/account_reconcilor_unittest.cc b/chrome/browser/signin/account_reconcilor_unittest.cc
index 7d6e9c5a..73d79c1de 100644
--- a/chrome/browser/signin/account_reconcilor_unittest.cc
+++ b/chrome/browser/signin/account_reconcilor_unittest.cc
@@ -13,6 +13,7 @@
#include "chrome/browser/signin/account_reconcilor_factory.h"
#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/fake_gaia_cookie_manager_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
#include "chrome/browser/signin/fake_signin_manager.h"
@@ -88,6 +89,9 @@
FakeProfileOAuth2TokenService* token_service() { return token_service_; }
TestSigninClient* test_signin_client() { return test_signin_client_; }
AccountTrackerService* account_tracker() { return account_tracker_; }
+ FakeGaiaCookieManagerService* cookie_manager_service() {
+ return cookie_manager_service_;
+ }
base::HistogramTester* histogram_tester() { return &histogram_tester_; }
void SetFakeResponse(const std::string& url,
@@ -114,7 +118,6 @@
content_settings::Observer* observer,
const ContentSettingsPattern& primary_pattern);
- GURL list_accounts_url() { return list_accounts_url_; }
GURL get_check_connection_info_url() {
return get_check_connection_info_url_;
}
@@ -126,11 +129,11 @@
FakeProfileOAuth2TokenService* token_service_;
TestSigninClient* test_signin_client_;
AccountTrackerService* account_tracker_;
+ FakeGaiaCookieManagerService* cookie_manager_service_;
MockAccountReconcilor* mock_reconcilor_;
net::FakeURLFetcherFactory url_fetcher_factory_;
scoped_ptr<TestingProfileManager> testing_profile_manager_;
base::HistogramTester histogram_tester_;
- GURL list_accounts_url_;
GURL get_check_connection_info_url_;
DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTest);
@@ -140,6 +143,7 @@
: signin_manager_(NULL),
token_service_(NULL),
test_signin_client_(NULL),
+ cookie_manager_service_(NULL),
mock_reconcilor_(NULL),
url_fetcher_factory_(NULL) {}
@@ -151,16 +155,10 @@
switches::kEnableNewProfileManagement);
}
- list_accounts_url_ = GaiaUrls::GetInstance()->ListAccountsURLWithSource(
- GaiaConstants::kReconcilorSource);
get_check_connection_info_url_ =
GaiaUrls::GetInstance()->GetCheckConnectionInfoURLWithSource(
GaiaConstants::kChromeSource);
- // Specific tests may set a response that includes specific accounts.
- SetFakeResponse(list_accounts_url().spec(), "",
- net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS);
-
testing_profile_manager_.reset(
new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
ASSERT_TRUE(testing_profile_manager_.get()->SetUp());
@@ -171,6 +169,9 @@
factories.push_back(std::make_pair(
ProfileOAuth2TokenServiceFactory::GetInstance(),
BuildFakeProfileOAuth2TokenService));
+ factories.push_back(std::make_pair(
+ GaiaCookieManagerServiceFactory::GetInstance(),
+ FakeGaiaCookieManagerService::Build));
factories.push_back(std::make_pair(SigninManagerFactory::GetInstance(),
FakeSigninManagerBase::Build));
factories.push_back(std::make_pair(AccountReconcilorFactory::GetInstance(),
@@ -195,6 +196,17 @@
signin_manager_ =
static_cast<FakeSigninManagerForTesting*>(
SigninManagerFactory::GetForProfile(profile()));
+
+ test_signin_client_ =
+ static_cast<TestSigninClient*>(
+ ChromeSigninClientFactory::GetForProfile(profile()));
+
+ cookie_manager_service_ =
+ static_cast<FakeGaiaCookieManagerService*>(
+ GaiaCookieManagerServiceFactory::GetForProfile(profile()));
+ cookie_manager_service_->Init(&url_fetcher_factory_);
+
+ cookie_manager_service_->SetListAccountsResponseHttpNotFound();
}
MockAccountReconcilor* AccountReconcilorTest::GetMockReconcilor() {
@@ -303,41 +315,37 @@
TEST_F(AccountReconcilorTest, GetAccountsFromCookieSuccess) {
const std::string account_id =
ConnectProfileToAccount("12345", "[email protected]");
+ cookie_manager_service()->SetListAccountsResponseOneAccountWithExpiry(
+ "[email protected]", true);
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
AccountReconcilor* reconcilor =
AccountReconcilorFactory::GetForProfile(profile());
ASSERT_TRUE(reconcilor);
- SetFakeResponse(list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 0]]]",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
reconcilor->StartReconcile();
- ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
-
base::RunLoop().RunUntilIdle();
- ASSERT_TRUE(reconcilor->AreGaiaAccountsSet());
- const std::vector<std::pair<std::string, bool> >& accounts =
- reconcilor->GetGaiaAccountsForTesting();
+
+ std::vector<std::pair<std::string, bool> > accounts;
+ ASSERT_TRUE(cookie_manager_service()->ListAccounts(&accounts));
ASSERT_EQ(1u, accounts.size());
ASSERT_EQ(account_id, accounts[0].first);
}
TEST_F(AccountReconcilorTest, GetAccountsFromCookieFailure) {
ConnectProfileToAccount("12345", "[email protected]");
+ cookie_manager_service()->SetListAccountsResponseHttpNotFound();
+
AccountReconcilor* reconcilor =
AccountReconcilorFactory::GetForProfile(profile());
ASSERT_TRUE(reconcilor);
- SetFakeResponse(list_accounts_url().spec(), "",
- net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS);
-
reconcilor->StartReconcile();
- ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
-
base::RunLoop().RunUntilIdle();
- ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
+
+ std::vector<std::pair<std::string, bool> > accounts;
+ ASSERT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
+ ASSERT_EQ(0u, accounts.size());
}
TEST_P(AccountReconcilorTest, StartReconcileNoop) {
@@ -348,13 +356,10 @@
AccountReconcilorFactory::GetForProfile(profile());
ASSERT_TRUE(reconcilor);
- SetFakeResponse(list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
+ cookie_manager_service()->SetListAccountsResponseOneAccount("[email protected]");
reconcilor->StartReconcile();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
- ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
@@ -379,9 +384,11 @@
reconcilor->StartReconcile();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
- ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
base::RunLoop().RunUntilIdle();
+ std::vector<std::pair<std::string, bool> > accounts;
+ // This will be the first call to ListAccounts.
+ ASSERT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
ASSERT_FALSE(reconcilor->is_reconcile_started_);
}
@@ -468,17 +475,13 @@
const std::string account_id =
ConnectProfileToAccount("12345", "[email protected]");
+ cookie_manager_service()->SetListAccountsResponseOneAccount(
+ "[email protected]");
AccountReconcilor* reconcilor =
AccountReconcilorFactory::GetForProfile(profile());
ASSERT_TRUE(reconcilor);
- SetFakeResponse(list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
reconcilor->StartReconcile();
- ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
-
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
@@ -493,19 +496,15 @@
ConnectProfileToAccount("12345", "[email protected]");
const std::string account_id2 =
PickAccountIdForAccount("67890", "[email protected]");
+ cookie_manager_service()->SetListAccountsResponseTwoAccounts(
+ "[email protected]", "[email protected]");
token_service()->UpdateCredentials(account_id2, "refresh_token");
AccountReconcilor* reconcilor =
AccountReconcilorFactory::GetForProfile(profile());
ASSERT_TRUE(reconcilor);
- SetFakeResponse(list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1], "
- "[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
reconcilor->StartReconcile();
- ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
@@ -521,6 +520,8 @@
const std::string account_id =
ConnectProfileToAccount("12345", "[email protected]");
token_service()->UpdateCredentials(account_id, "refresh_token");
+ cookie_manager_service()->SetListAccountsResponseOneAccount(
+ "[email protected]");
const std::string account_id2 =
PickAccountIdForAccount("67890", "[email protected]");
@@ -528,10 +529,6 @@
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2));
- SetFakeResponse(list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
AccountReconcilor* reconcilor = GetMockReconcilor();
reconcilor->StartReconcile();
@@ -555,15 +552,12 @@
const std::string account_id =
ConnectProfileToAccount("12345", "[email protected]");
token_service()->UpdateCredentials(account_id, "refresh_token");
+ cookie_manager_service()->SetListAccountsResponseTwoAccounts(
+ "[email protected]", "[email protected]");
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
- SetFakeResponse(list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1], "
- "[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
AccountReconcilor* reconcilor = GetMockReconcilor();
reconcilor->StartReconcile();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
@@ -591,17 +585,13 @@
const std::string account_id3 =
PickAccountIdForAccount("34567", "[email protected]");
+ cookie_manager_service()->SetListAccountsResponseOneAccount(
+ "[email protected]");
token_service()->UpdateCredentials(account_id2, "refresh_token");
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2));
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id3));
- SetFakeResponse(
- list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]",
- net::HTTP_OK,
- net::URLRequestStatus::SUCCESS);
-
AccountReconcilor* reconcilor = GetMockReconcilor();
reconcilor->StartReconcile();
@@ -621,13 +611,10 @@
"Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
// Do another pass after I've added a third account to the token service
+ cookie_manager_service()->SetListAccountsResponseTwoAccounts(
+ "[email protected]", "[email protected]");
+ cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
- SetFakeResponse(
- list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1], "
- "[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]",
- net::HTTP_OK,
- net::URLRequestStatus::SUCCESS);
// This will cause the reconcilor to fire.
token_service()->UpdateCredentials(account_id3, "refresh_token");
base::RunLoop().RunUntilIdle();
@@ -662,16 +649,13 @@
PickAccountIdForAccount("67890", "[email protected]");
token_service()->UpdateCredentials(account_id2, "refresh_token");
+ cookie_manager_service()->SetListAccountsResponseTwoAccounts(
+ "[email protected]", "[email protected]");
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2));
- SetFakeResponse(list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1], "
- "[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
AccountReconcilor* reconcilor = GetMockReconcilor();
reconcilor->StartReconcile();
@@ -697,15 +681,13 @@
TEST_P(AccountReconcilorTest, StartReconcileOnlyOnce) {
const std::string account_id =
ConnectProfileToAccount("12345", "[email protected]");
+ cookie_manager_service()->SetListAccountsResponseOneAccount(
+ "[email protected]");
AccountReconcilor* reconcilor =
AccountReconcilorFactory::GetForProfile(profile());
ASSERT_TRUE(reconcilor);
- SetFakeResponse(list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
ASSERT_FALSE(reconcilor->is_reconcile_started_);
reconcilor->StartReconcile();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
@@ -720,14 +702,11 @@
const std::string account_id2 =
PickAccountIdForAccount("67890", "[email protected]");
token_service()->UpdateCredentials(account_id2, "refresh_token");
+ cookie_manager_service()->SetListAccountsResponseTwoAccountsWithExpiry(
+ "[email protected]", true, "[email protected]", false);
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
- SetFakeResponse(list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 0],"
- "[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
AccountReconcilor* reconcilor =
AccountReconcilorFactory::GetForProfile(profile());
ASSERT_TRUE(reconcilor);
@@ -745,13 +724,11 @@
TEST_F(AccountReconcilorTest, AddAccountToCookieCompletedWithBogusAccount) {
const std::string account_id =
ConnectProfileToAccount("12345", "[email protected]");
+ cookie_manager_service()->SetListAccountsResponseOneAccountWithExpiry(
+ "[email protected]", true);
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
- SetFakeResponse(list_accounts_url().spec(),
- "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 0]]]",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
AccountReconcilor* reconcilor =
AccountReconcilorFactory::GetForProfile(profile());
ASSERT_TRUE(reconcilor);
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc
index debf8eca4..90ddd804 100644
--- a/chrome/browser/signin/chrome_signin_client.cc
+++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -61,8 +61,10 @@
bool ChromeSigninClient::SettingsAllowSigninCookies(
CookieSettings* cookie_settings) {
GURL gaia_url = GaiaUrls::GetInstance()->gaia_url();
+ GURL google_url = GaiaUrls::GetInstance()->google_url();
return cookie_settings &&
- cookie_settings->IsSettingCookieAllowed(gaia_url, gaia_url);
+ cookie_settings->IsSettingCookieAllowed(gaia_url, gaia_url) &&
+ cookie_settings->IsSettingCookieAllowed(google_url, google_url);
}
PrefService* ChromeSigninClient::GetPrefs() { return profile_->GetPrefs(); }
diff --git a/chrome/browser/signin/fake_account_reconcilor.cc b/chrome/browser/signin/fake_account_reconcilor.cc
deleted file mode 100644
index ea1573ef..0000000
--- a/chrome/browser/signin/fake_account_reconcilor.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2014 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 "chrome/browser/signin/fake_account_reconcilor.h"
-
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/chrome_signin_client_factory.h"
-#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
-
-FakeAccountReconcilor::FakeAccountReconcilor(
- ProfileOAuth2TokenService* token_service,
- SigninManagerBase* signin_manager,
- SigninClient* client,
- GaiaCookieManagerService* cookie_manager_service) :
- AccountReconcilor(
- token_service, signin_manager, client, cookie_manager_service) {}
-
-
-// static
-KeyedService* FakeAccountReconcilor::Build(content::BrowserContext* context) {
- Profile* profile = Profile::FromBrowserContext(context);
- AccountReconcilor* reconcilor = new FakeAccountReconcilor(
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
- SigninManagerFactory::GetForProfile(profile),
- ChromeSigninClientFactory::GetForProfile(profile),
- GaiaCookieManagerServiceFactory::GetForProfile(profile));
- reconcilor->Initialize(true /* start_reconcile_if_tokens_available */);
- return reconcilor;
-}
-
-void FakeAccountReconcilor::GetAccountsFromCookie(
- GetAccountsFromCookieCallback callback) {
- std::vector<std::pair<std::string, bool> > gaia_accounts;
- callback.Run(GoogleServiceAuthError::AuthErrorNone(), gaia_accounts);
-}
diff --git a/chrome/browser/signin/fake_account_reconcilor.h b/chrome/browser/signin/fake_account_reconcilor.h
deleted file mode 100644
index 405fda2..0000000
--- a/chrome/browser/signin/fake_account_reconcilor.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 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 CHROME_BROWSER_SIGNIN_FAKE_ACCOUNT_RECONCILOR_H_
-#define CHROME_BROWSER_SIGNIN_FAKE_ACCOUNT_RECONCILOR_H_
-
-#include "components/signin/core/browser/account_reconcilor.h"
-
-namespace content {
-class BrowserContext;
-}
-
-class FakeAccountReconcilor : public AccountReconcilor {
- public:
- FakeAccountReconcilor(ProfileOAuth2TokenService* token_service,
- SigninManagerBase* signin_manager,
- SigninClient* client,
- GaiaCookieManagerService* cookie_manager_service);
-
- // Helper function to be used with KeyedService::SetTestingFactory().
- static KeyedService* Build(content::BrowserContext* context);
-
- protected:
- // Override this method to perform no network call, instead the callback
- // is called immediately
- void GetAccountsFromCookie(GetAccountsFromCookieCallback callback) override;
-
- DISALLOW_COPY_AND_ASSIGN(FakeAccountReconcilor);
-};
-
-#endif // CHROME_BROWSER_SIGNIN_FAKE_ACCOUNT_RECONCILOR_H_
diff --git a/chrome/browser/signin/fake_gaia_cookie_manager_service.cc b/chrome/browser/signin/fake_gaia_cookie_manager_service.cc
new file mode 100644
index 0000000..430f8abb
--- /dev/null
+++ b/chrome/browser/signin/fake_gaia_cookie_manager_service.cc
@@ -0,0 +1,112 @@
+// Copyright 2015 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 "chrome/browser/signin/fake_gaia_cookie_manager_service.h"
+
+#include "base/strings/stringprintf.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "components/signin/core/browser/profile_oauth2_token_service.h"
+#include "google_apis/gaia/gaia_constants.h"
+#include "google_apis/gaia/gaia_urls.h"
+
+FakeGaiaCookieManagerService::FakeGaiaCookieManagerService(
+ OAuth2TokenService* token_service,
+ const std::string& source,
+ SigninClient* client) :
+ GaiaCookieManagerService(token_service, source, client),
+ url_fetcher_factory_(NULL) {}
+
+void FakeGaiaCookieManagerService::Init(
+ net::FakeURLFetcherFactory* url_fetcher_factory) {
+ url_fetcher_factory_ = url_fetcher_factory;
+}
+
+void FakeGaiaCookieManagerService::SetListAccountsResponseHttpNotFound() {
+ DCHECK(url_fetcher_factory_);
+ url_fetcher_factory_->SetFakeResponse(
+ GaiaUrls::GetInstance()->ListAccountsURLWithSource(
+ GaiaConstants::kChromeSource),
+ "",
+ net::HTTP_NOT_FOUND,
+ net::URLRequestStatus::SUCCESS);
+}
+
+void FakeGaiaCookieManagerService::SetListAccountsResponseNoAccounts() {
+ DCHECK(url_fetcher_factory_);
+ url_fetcher_factory_->SetFakeResponse(
+ GaiaUrls::GetInstance()->ListAccountsURLWithSource(
+ GaiaConstants::kChromeSource),
+ "[\"f\", []]",
+ net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+}
+
+void FakeGaiaCookieManagerService::SetListAccountsResponseOneAccount(
+ const char* account) {
+ DCHECK(url_fetcher_factory_);
+ url_fetcher_factory_->SetFakeResponse(
+ GaiaUrls::GetInstance()->ListAccountsURLWithSource(
+ GaiaConstants::kChromeSource),
+ base::StringPrintf(
+ "[\"f\", [[\"b\", 0, \"n\", \"%s\", \"p\", 0, 0, 0, 0, 1]]]",
+ account),
+ net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+}
+
+void FakeGaiaCookieManagerService::SetListAccountsResponseOneAccountWithExpiry(
+ const char* account, bool expired) {
+ DCHECK(url_fetcher_factory_);
+ url_fetcher_factory_->SetFakeResponse(
+ GaiaUrls::GetInstance()->ListAccountsURLWithSource(
+ GaiaConstants::kChromeSource),
+ base::StringPrintf(
+ "[\"f\", [[\"b\", 0, \"n\", \"%s\", \"p\", 0, 0, 0, 0, %d]]]",
+ account, expired ? 0 : 1),
+ net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+}
+
+void FakeGaiaCookieManagerService::SetListAccountsResponseTwoAccounts(
+ const char* account1, const char* account2) {
+ DCHECK(url_fetcher_factory_);
+ url_fetcher_factory_->SetFakeResponse(
+ GaiaUrls::GetInstance()->ListAccountsURLWithSource(
+ GaiaConstants::kChromeSource),
+ base::StringPrintf(
+ "[\"f\", [[\"b\", 0, \"n\", \"%s\", \"p\", 0, 0, 0, 0, 1], "
+ "[\"b\", 0, \"n\", \"%s\", \"p\", 0, 0, 0, 0, 1]]]",
+ account1, account2),
+ net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+}
+
+void FakeGaiaCookieManagerService::SetListAccountsResponseTwoAccountsWithExpiry(
+ const char* account1, bool account1_expired,
+ const char* account2, bool account2_expired) {
+ DCHECK(url_fetcher_factory_);
+ url_fetcher_factory_->SetFakeResponse(
+ GaiaUrls::GetInstance()->ListAccountsURLWithSource(
+ GaiaConstants::kChromeSource),
+ base::StringPrintf(
+ "[\"f\", [[\"b\", 0, \"n\", \"%s\", \"p\", 0, 0, 0, 0, %d], "
+ "[\"b\", 0, \"n\", \"%s\", \"p\", 0, 0, 0, 0, %d]]]",
+ account1, account1_expired ? 0 : 1,
+ account2, account2_expired ? 0 : 1),
+ net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+}
+
+// static
+KeyedService* FakeGaiaCookieManagerService::Build(
+ content::BrowserContext* context) {
+ Profile* profile = Profile::FromBrowserContext(context);
+ FakeGaiaCookieManagerService* service = new FakeGaiaCookieManagerService(
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
+ GaiaConstants::kChromeSource,
+ ChromeSigninClientFactory::GetForProfile(profile));
+ return service;
+}
diff --git a/chrome/browser/signin/fake_gaia_cookie_manager_service.h b/chrome/browser/signin/fake_gaia_cookie_manager_service.h
new file mode 100644
index 0000000..b03750c9
--- /dev/null
+++ b/chrome/browser/signin/fake_gaia_cookie_manager_service.h
@@ -0,0 +1,44 @@
+// Copyright 2015 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 CHROME_BROWSER_SIGNIN_FAKE_GAIA_COOKIE_MANAGER_SERVICE_H_
+#define CHROME_BROWSER_SIGNIN_FAKE_GAIA_COOKIE_MANAGER_SERVICE_H_
+
+#include "components/signin/core/browser/gaia_cookie_manager_service.h"
+
+#include "net/url_request/test_url_fetcher_factory.h"
+
+namespace content {
+class BrowserContext;
+}
+
+class FakeGaiaCookieManagerService : public GaiaCookieManagerService {
+ public:
+ FakeGaiaCookieManagerService(OAuth2TokenService* token_service,
+ const std::string& source,
+ SigninClient* client);
+
+ void Init(net::FakeURLFetcherFactory* url_fetcher_factory);
+
+ void SetListAccountsResponseHttpNotFound();
+ void SetListAccountsResponseNoAccounts();
+ void SetListAccountsResponseOneAccount(const char* account);
+ void SetListAccountsResponseOneAccountWithExpiry(
+ const char* account, bool expired);
+ void SetListAccountsResponseTwoAccounts(const char* account1,
+ const char* account2);
+ void SetListAccountsResponseTwoAccountsWithExpiry(
+ const char* account1, bool account1_expired,
+ const char* account2, bool account2_expired);
+
+ // Helper function to be used with KeyedService::SetTestingFactory().
+ static KeyedService* Build(content::BrowserContext* context);
+
+ private:
+ // Provide a fake response for calls to /ListAccounts.
+ net::FakeURLFetcherFactory* url_fetcher_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeGaiaCookieManagerService);
+};
+
+#endif // CHROME_BROWSER_SIGNIN_FAKE_GAIA_COOKIE_MANAGER_SERVICE_H_
diff --git a/chrome/browser/signin/signin_tracker_factory.cc b/chrome/browser/signin/signin_tracker_factory.cc
index 0c9f3da..0e1a5372 100644
--- a/chrome/browser/signin/signin_tracker_factory.cc
+++ b/chrome/browser/signin/signin_tracker_factory.cc
@@ -4,7 +4,6 @@
#include "chrome/browser/signin/signin_tracker_factory.h"
-#include "chrome/browser/signin/account_reconcilor_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
@@ -18,15 +17,9 @@
scoped_ptr<SigninTracker> SigninTrackerFactory::CreateForProfile(
Profile* profile,
SigninTracker::Observer* observer) {
- // Determine whether to use the AccountReconcilor.
- AccountReconcilor* account_reconcilor = NULL;
- if (switches::IsEnableAccountConsistency())
- account_reconcilor = AccountReconcilorFactory::GetForProfile(profile);
-
return scoped_ptr<SigninTracker>(new SigninTracker(
ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
SigninManagerFactory::GetForProfile(profile),
- account_reconcilor,
GaiaCookieManagerServiceFactory::GetForProfile(profile),
ChromeSigninClientFactory::GetForProfile(profile),
observer));
diff --git a/chrome/browser/ui/webui/signin_internals_ui.cc b/chrome/browser/ui/webui/signin_internals_ui.cc
index f01cac7..a709e406 100644
--- a/chrome/browser/ui/webui/signin_internals_ui.cc
+++ b/chrome/browser/ui/webui/signin_internals_ui.cc
@@ -8,8 +8,10 @@
#include "base/profiler/scoped_tracker.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/about_signin_internals_factory.h"
+#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
#include "chrome/common/url_constants.h"
#include "components/signin/core/browser/about_signin_internals.h"
+#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "grit/signin_internals_resources.h"
@@ -70,7 +72,15 @@
web_ui()->CallJavascriptFunction(
"chrome.signin.getSigninInfo.handleReply",
*about_signin_internals->GetSigninStatus());
- about_signin_internals->GetCookieAccountsAsync();
+
+ std::vector<std::pair<std::string, bool>> cookie_accounts;
+ GaiaCookieManagerService* cookie_manager_service =
+ GaiaCookieManagerServiceFactory::GetForProfile(profile);
+ if (cookie_manager_service->ListAccounts(&cookie_accounts)) {
+ about_signin_internals->OnGaiaAccountsInCookieUpdated(
+ cookie_accounts,
+ GoogleServiceAuthError(GoogleServiceAuthError::NONE));
+ }
return true;
}
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index a5ac421..26b63fa 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1687,10 +1687,10 @@
'browser/sessions/session_restore_test_helper.h',
'browser/sessions/session_service_test_helper.cc',
'browser/sessions/session_service_test_helper.h',
- 'browser/signin/fake_account_reconcilor.cc',
- 'browser/signin/fake_account_reconcilor.h',
'browser/signin/fake_account_tracker_service.cc',
'browser/signin/fake_account_tracker_service.h',
+ 'browser/signin/fake_gaia_cookie_manager_service.cc',
+ 'browser/signin/fake_gaia_cookie_manager_service.h',
'browser/signin/fake_profile_oauth2_token_service.cc',
'browser/signin/fake_profile_oauth2_token_service.h',
'browser/signin/fake_profile_oauth2_token_service_builder.cc',
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc
index 81a7e614..74c3979 100644
--- a/components/signin/core/browser/about_signin_internals.cc
+++ b/components/signin/core/browser/about_signin_internals.cc
@@ -20,11 +20,6 @@
#include "components/signin/core/browser/signin_manager.h"
#include "components/signin/core/common/profile_management_switches.h"
#include "components/signin/core/common/signin_switches.h"
-#include "google_apis/gaia/gaia_auth_fetcher.h"
-#include "google_apis/gaia/gaia_auth_util.h"
-#include "google_apis/gaia/gaia_constants.h"
-#include "google_apis/gaia/gaia_urls.h"
-#include "net/cookies/canonical_cookie.h"
using base::Time;
using namespace signin_internals_util;
@@ -135,12 +130,14 @@
ProfileOAuth2TokenService* token_service,
AccountTrackerService* account_tracker,
SigninManagerBase* signin_manager,
- SigninErrorController* signin_error_controller)
+ SigninErrorController* signin_error_controller,
+ GaiaCookieManagerService* cookie_manager_service)
: token_service_(token_service),
account_tracker_(account_tracker),
signin_manager_(signin_manager),
client_(NULL),
- signin_error_controller_(signin_error_controller) {}
+ signin_error_controller_(signin_error_controller),
+ cookie_manager_service_(cookie_manager_service) {}
AboutSigninInternals::~AboutSigninInternals() {}
@@ -211,18 +208,14 @@
signin_error_controller_->AddObserver(this);
signin_manager_->AddSigninDiagnosticsObserver(this);
token_service_->AddDiagnosticsObserver(this);
- cookie_changed_subscription_ = client_->AddCookieChangedCallback(
- GaiaUrls::GetInstance()->gaia_url(),
- "LSID",
- base::Bind(&AboutSigninInternals::OnCookieChanged,
- base::Unretained(this)));
+ cookie_manager_service_->AddObserver(this);
}
void AboutSigninInternals::Shutdown() {
signin_error_controller_->RemoveObserver(this);
signin_manager_->RemoveSigninDiagnosticsObserver(this);
token_service_->RemoveDiagnosticsObserver(this);
- cookie_changed_subscription_.reset();
+ cookie_manager_service_->RemoveObserver(this);
}
void AboutSigninInternals::NotifyObservers() {
@@ -329,48 +322,10 @@
NotifySigninValueChanged(AUTHENTICATION_RESULT_RECEIVED, status);
}
-void AboutSigninInternals::OnCookieChanged(const net::CanonicalCookie& cookie,
- bool removed) {
- DCHECK_EQ("LSID", cookie.Name());
- DCHECK_EQ(GaiaUrls::GetInstance()->gaia_url().host(), cookie.Domain());
- if (cookie.IsSecure() && cookie.IsHttpOnly()) {
- GetCookieAccountsAsync();
- }
-}
-
void AboutSigninInternals::OnErrorChanged() {
NotifyObservers();
}
-void AboutSigninInternals::GetCookieAccountsAsync() {
- // Don't bother calling /ListAccounts if no one will observe the response.
- if (!gaia_fetcher_ && signin_observers_.might_have_observers()) {
- // There is no list account request in flight.
- gaia_fetcher_.reset(new GaiaAuthFetcher(
- this, GaiaConstants::kChromeSource, client_->GetURLRequestContext()));
- gaia_fetcher_->StartListAccounts();
- }
-}
-
-void AboutSigninInternals::OnListAccountsSuccess(const std::string& data) {
- gaia_fetcher_.reset();
-
- // Get account information from response data.
- std::vector<std::pair<std::string, bool> > gaia_accounts;
- bool valid_json = gaia::ParseListAccountsData(data, &gaia_accounts);
- if (!valid_json) {
- VLOG(1) << "AboutSigninInternals::OnListAccountsSuccess: parsing error";
- } else {
- OnListAccountsComplete(gaia_accounts);
- }
-}
-
-void AboutSigninInternals::OnListAccountsFailure(
- const GoogleServiceAuthError& error) {
- gaia_fetcher_.reset();
- VLOG(1) << "AboutSigninInternals::OnListAccountsFailure:" << error.ToString();
-}
-
void AboutSigninInternals::GoogleSigninFailed(
const GoogleServiceAuthError& error) {
NotifyObservers();
@@ -387,8 +342,12 @@
NotifyObservers();
}
-void AboutSigninInternals::OnListAccountsComplete(
- std::vector<std::pair<std::string, bool> >& gaia_accounts) {
+void AboutSigninInternals::OnGaiaAccountsInCookieUpdated(
+ const std::vector<std::pair<std::string, bool> >& gaia_accounts,
+ const GoogleServiceAuthError& error) {
+ if (error.state() != GoogleServiceAuthError::NONE)
+ return;
+
base::DictionaryValue cookie_status;
base::ListValue* cookie_info = new base::ListValue();
cookie_status.Set("cookie_info", cookie_info);
diff --git a/components/signin/core/browser/about_signin_internals.h b/components/signin/core/browser/about_signin_internals.h
index e5850d1..a2c1d23 100644
--- a/components/signin/core/browser/about_signin_internals.h
+++ b/components/signin/core/browser/about_signin_internals.h
@@ -13,11 +13,11 @@
#include "base/observer_list.h"
#include "base/values.h"
#include "components/keyed_service/core/keyed_service.h"
+#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/core/browser/signin_client.h"
#include "components/signin/core/browser/signin_error_controller.h"
#include "components/signin/core/browser/signin_internals_util.h"
#include "components/signin/core/browser/signin_manager.h"
-#include "google_apis/gaia/gaia_auth_consumer.h"
#include "google_apis/gaia/oauth2_token_service.h"
class AccountTrackerService;
@@ -35,7 +35,7 @@
: public KeyedService,
public signin_internals_util::SigninDiagnosticsObserver,
public OAuth2TokenService::DiagnosticsObserver,
- public GaiaAuthConsumer,
+ public GaiaCookieManagerService::Observer,
SigninManagerBase::Observer,
SigninErrorController::Observer {
public:
@@ -52,7 +52,8 @@
AboutSigninInternals(ProfileOAuth2TokenService* token_service,
AccountTrackerService* account_tracker,
SigninManagerBase* signin_manager,
- SigninErrorController* signin_error_controller);
+ SigninErrorController* signin_error_controller,
+ GaiaCookieManagerService* cookie_manager_service);
~AboutSigninInternals() override;
// Each instance of SigninInternalsUI adds itself as an observer to be
@@ -87,9 +88,10 @@
// }
scoped_ptr<base::DictionaryValue> GetSigninStatus();
- // Triggers a ListAccounts call to acquire a list of the email addresses
- // corresponding to the cookies residing on the current cookie jar.
- void GetCookieAccountsAsync();
+ // GaiaCookieManagerService::Observer implementations.
+ void OnGaiaAccountsInCookieUpdated(
+ const std::vector<std::pair<std::string, bool> >& gaia_accounts,
+ const GoogleServiceAuthError& error) override;
private:
// Encapsulates diagnostic information about tokens for different services.
@@ -173,10 +175,6 @@
void OnTokenRemoved(const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes) override;
- // GaiaAuthConsumer implementations.
- void OnListAccountsSuccess(const std::string& data) override;
- void OnListAccountsFailure(const GoogleServiceAuthError& error) override;
-
// SigninManagerBase::Observer implementations.
void GoogleSigninFailed(const GoogleServiceAuthError& error) override;
void GoogleSigninSucceeded(const std::string& account_id,
@@ -187,15 +185,6 @@
void NotifyObservers();
- // Callback for ListAccounts. Once the email addresses are fetched from GAIA,
- // they are pushed to the signin_internals_ui.
- void OnListAccountsComplete(
- std::vector<std::pair<std::string, bool> >& gaia_accounts);
-
- // Called when a cookie changes. If the cookie relates to a GAIA LSID cookie,
- // then we call ListAccounts and update the UI element.
- void OnCookieChanged(const net::CanonicalCookie& cookie, bool removed);
-
// SigninErrorController::Observer implementation
void OnErrorChanged() override;
@@ -214,8 +203,8 @@
// Weak pointer to the SigninErrorController
SigninErrorController* signin_error_controller_;
- // Fetcher for information about accounts in the cookie jar from GAIA.
- scoped_ptr<GaiaAuthFetcher> gaia_fetcher_;
+ // Weak pointer to the GaiaCookieManagerService
+ GaiaCookieManagerService* cookie_manager_service_;
// Encapsulates the actual signin and token related values.
// Most of the values are mirrored in the prefs for persistence.
@@ -223,9 +212,6 @@
ObserverList<Observer> signin_observers_;
- scoped_ptr<SigninClient::CookieChangedSubscription>
- cookie_changed_subscription_;
-
DISALLOW_COPY_AND_ASSIGN(AboutSigninInternals);
};
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc
index efe594db..aecbe9b1 100644
--- a/components/signin/core/browser/account_reconcilor.cc
+++ b/components/signin/core/browser/account_reconcilor.cc
@@ -16,12 +16,9 @@
#include "components/signin/core/browser/signin_client.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "components/signin/core/common/profile_management_switches.h"
-#include "google_apis/gaia/gaia_auth_fetcher.h"
#include "google_apis/gaia/gaia_auth_util.h"
-#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_oauth_client.h"
#include "google_apis/gaia/gaia_urls.h"
-#include "net/cookies/canonical_cookie.h"
namespace {
@@ -67,7 +64,6 @@
registered_with_content_settings_(false),
is_reconcile_started_(false),
first_execution_(true),
- are_gaia_accounts_set_(false),
chrome_accounts_changed_(false) {
VLOG(1) << "AccountReconcilor::AccountReconcilor";
}
@@ -87,7 +83,6 @@
// wait for signin.
if (IsProfileConnected()) {
RegisterWithCookieManagerService();
- RegisterForCookieChanges();
RegisterWithContentSettings();
RegisterWithTokenService();
@@ -101,29 +96,12 @@
void AccountReconcilor::Shutdown() {
VLOG(1) << "AccountReconcilor::Shutdown";
- gaia_fetcher_.reset();
- get_gaia_accounts_callbacks_.clear();
UnregisterWithCookieManagerService();
UnregisterWithSigninManager();
UnregisterWithTokenService();
- UnregisterForCookieChanges();
UnregisterWithContentSettings();
}
-void AccountReconcilor::RegisterForCookieChanges() {
- // First clear any existing registration to avoid DCHECKs that can otherwise
- // go off in some embedders on reauth (e.g., ChromeSigninClient).
- UnregisterForCookieChanges();
- cookie_changed_subscription_ = client_->AddCookieChangedCallback(
- GaiaUrls::GetInstance()->gaia_url(),
- "LSID",
- base::Bind(&AccountReconcilor::OnCookieChanged, base::Unretained(this)));
-}
-
-void AccountReconcilor::UnregisterForCookieChanges() {
- cookie_changed_subscription_.reset();
-}
-
void AccountReconcilor::RegisterWithSigninManager() {
signin_manager_->AddObserver(this);
}
@@ -198,24 +176,6 @@
return signin_manager_->IsAuthenticated();
}
-void AccountReconcilor::OnCookieChanged(const net::CanonicalCookie& cookie,
- bool removed) {
- DCHECK_EQ("LSID", cookie.Name());
- DCHECK_EQ(GaiaUrls::GetInstance()->gaia_url().host(), cookie.Domain());
- if (cookie.IsSecure() && cookie.IsHttpOnly()) {
- VLOG(1) << "AccountReconcilor::OnCookieChanged: LSID changed";
-
- // It is possible that O2RT is not available at this moment.
- if (!token_service_->GetAccounts().size()) {
- VLOG(1) << "AccountReconcilor::OnCookieChanged: cookie change is ingored"
- "because O2RT is not available yet.";
- return;
- }
-
- StartReconcile();
- }
-}
-
void AccountReconcilor::OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
@@ -249,7 +209,6 @@
const std::string& password) {
VLOG(1) << "AccountReconcilor::GoogleSigninSucceeded: signed in";
RegisterWithCookieManagerService();
- RegisterForCookieChanges();
RegisterWithContentSettings();
RegisterWithTokenService();
}
@@ -257,12 +216,9 @@
void AccountReconcilor::GoogleSignedOut(const std::string& account_id,
const std::string& username) {
VLOG(1) << "AccountReconcilor::GoogleSignedOut: signed out";
- gaia_fetcher_.reset();
- get_gaia_accounts_callbacks_.clear();
AbortReconcile();
UnregisterWithCookieManagerService();
UnregisterWithTokenService();
- UnregisterForCookieChanges();
UnregisterWithContentSettings();
PerformLogoutAllAccountsAction();
}
@@ -289,13 +245,12 @@
return;
}
- if (is_reconcile_started_ || get_gaia_accounts_callbacks_.size() > 0)
+ if (is_reconcile_started_)
return;
is_reconcile_started_ = true;
// Reset state for validating gaia cookie.
- are_gaia_accounts_set_ = false;
gaia_accounts_.clear();
// Reset state for validating oauth2 tokens.
@@ -304,78 +259,24 @@
add_to_cookie_.clear();
ValidateAccountsFromTokenService();
- GetAccountsFromCookie(base::Bind(
- &AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts,
- base::Unretained(this)));
-}
-
-void AccountReconcilor::GetAccountsFromCookie(
- GetAccountsFromCookieCallback callback) {
- get_gaia_accounts_callbacks_.push_back(callback);
- if (!gaia_fetcher_)
- MayBeDoNextListAccounts();
-}
-
-void AccountReconcilor::OnListAccountsSuccess(const std::string& data) {
- gaia_fetcher_.reset();
-
- // Get account information from response data.
- std::vector<std::pair<std::string, bool> > gaia_accounts;
- bool valid_json = gaia::ParseListAccountsData(data, &gaia_accounts);
- if (!valid_json) {
- VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: parsing error";
- } else if (gaia_accounts.size() > 0) {
- VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: "
- << "Gaia " << gaia_accounts.size() << " accounts, "
- << "Primary is '" << gaia_accounts[0].first << "'";
- } else {
- VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: No accounts";
- }
-
- // There must be at least one callback waiting for result.
- DCHECK(!get_gaia_accounts_callbacks_.empty());
-
- GoogleServiceAuthError error =
- !valid_json ? GoogleServiceAuthError(
- GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE)
- : GoogleServiceAuthError::AuthErrorNone();
- get_gaia_accounts_callbacks_.front().Run(error, gaia_accounts);
- get_gaia_accounts_callbacks_.pop_front();
-
- MayBeDoNextListAccounts();
-}
-
-void AccountReconcilor::OnListAccountsFailure(
- const GoogleServiceAuthError& error) {
- gaia_fetcher_.reset();
- VLOG(1) << "AccountReconcilor::OnListAccountsFailure: " << error.ToString();
- std::vector<std::pair<std::string, bool> > empty_accounts;
-
- // There must be at least one callback waiting for result.
- DCHECK(!get_gaia_accounts_callbacks_.empty());
-
- get_gaia_accounts_callbacks_.front().Run(error, empty_accounts);
- get_gaia_accounts_callbacks_.pop_front();
-
- MayBeDoNextListAccounts();
-}
-
-void AccountReconcilor::MayBeDoNextListAccounts() {
- if (!get_gaia_accounts_callbacks_.empty()) {
- gaia_fetcher_.reset(new GaiaAuthFetcher(
- this, GaiaConstants::kReconcilorSource,
- client_->GetURLRequestContext()));
- gaia_fetcher_->StartListAccounts();
+ // Rely on the GCMS to manage calls to and responses from ListAccounts.
+ if (cookie_manager_service_->ListAccounts(&gaia_accounts_)) {
+ OnGaiaAccountsInCookieUpdated(
+ gaia_accounts_, GoogleServiceAuthError(GoogleServiceAuthError::NONE));
}
}
-void AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts(
- const GoogleServiceAuthError& error,
- const std::vector<std::pair<std::string, bool> >& accounts) {
+void AccountReconcilor::OnGaiaAccountsInCookieUpdated(
+ const std::vector<std::pair<std::string, bool> >& accounts,
+ const GoogleServiceAuthError& error) {
if (error.state() == GoogleServiceAuthError::NONE) {
gaia_accounts_ = accounts;
- are_gaia_accounts_set_ = true;
- FinishReconcile();
+
+ // It is possible that O2RT is not available at this moment.
+ if (token_service_->GetAccounts().empty())
+ return;
+
+ is_reconcile_started_ ? FinishReconcile() : StartReconcile();
} else {
AbortReconcile();
}
@@ -407,7 +308,6 @@
void AccountReconcilor::FinishReconcile() {
VLOG(1) << "AccountReconcilor::FinishReconcile";
- DCHECK(are_gaia_accounts_set_);
DCHECK(add_to_cookie_.empty());
int number_gaia_accounts = gaia_accounts_.size();
bool are_primaries_equal = number_gaia_accounts > 0 &&
diff --git a/components/signin/core/browser/account_reconcilor.h b/components/signin/core/browser/account_reconcilor.h
index 1350aa3a..8dbe06c 100644
--- a/components/signin/core/browser/account_reconcilor.h
+++ b/components/signin/core/browser/account_reconcilor.h
@@ -23,7 +23,6 @@
#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/core/browser/signin_client.h"
#include "components/signin/core/browser/signin_manager.h"
-#include "google_apis/gaia/gaia_auth_consumer.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_token_service.h"
@@ -37,7 +36,6 @@
class AccountReconcilor : public KeyedService,
public content_settings::Observer,
- public GaiaAuthConsumer,
public GaiaCookieManagerService::Observer,
public OAuth2TokenService::Observer,
public SigninManagerBase::Observer {
@@ -58,23 +56,11 @@
// KeyedService implementation.
void Shutdown() override;
- protected:
- // Used during GetAccountsFromCookie.
- // Stores a callback for the next action to perform.
- typedef base::Callback<
- void(const GoogleServiceAuthError& error,
- const std::vector<std::pair<std::string, bool> >&)>
- GetAccountsFromCookieCallback;
-
- virtual void GetAccountsFromCookie(GetAccountsFromCookieCallback callback);
-
private:
bool IsRegisteredWithTokenService() const {
return registered_with_token_service_;
}
- bool AreGaiaAccountsSet() const { return are_gaia_accounts_set_; }
-
const std::vector<std::pair<std::string, bool> >& GetGaiaAccountsForTesting()
const {
return gaia_accounts_;
@@ -112,8 +98,6 @@
AddAccountToCookieCompletedWithBogusAccount);
// Register and unregister with dependent services.
- void RegisterForCookieChanges();
- void UnregisterForCookieChanges();
void RegisterWithSigninManager();
void UnregisterWithSigninManager();
void RegisterWithTokenService();
@@ -137,15 +121,10 @@
void CalculateIfReconcileIsDone();
void ScheduleStartReconcileIfChromeAccountsChanged();
- void ContinueReconcileActionAfterGetGaiaAccounts(
- const GoogleServiceAuthError& error,
- const std::vector<std::pair<std::string, bool> >& accounts);
void ValidateAccountsFromTokenService();
// Note internally that this |account_id| is added to the cookie jar.
bool MarkAccountAsAddedToCookie(const std::string& account_id);
- void OnCookieChanged(const net::CanonicalCookie& cookie, bool removed);
-
// Overriden from content_settings::Observer.
void OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern,
@@ -153,14 +132,13 @@
ContentSettingsType content_type,
std::string resource_identifier) override;
- // Overriden from GaiaAuthConsumer.
- void OnListAccountsSuccess(const std::string& data) override;
- void OnListAccountsFailure(const GoogleServiceAuthError& error) override;
-
- // Overriden from MergeSessionHelper::Observer.
+ // Overriden from GaiaGookieManagerService::Observer.
void OnAddAccountToCookieCompleted(
const std::string& account_id,
const GoogleServiceAuthError& error) override;
+ void OnGaiaAccountsInCookieUpdated(
+ const std::vector<std::pair<std::string, bool> >& accounts,
+ const GoogleServiceAuthError& error) override;
// Overriden from OAuth2TokenService::Observer.
void OnEndBatchChanges() override;
@@ -172,8 +150,6 @@
void GoogleSignedOut(const std::string& account_id,
const std::string& username) override;
- void MayBeDoNextListAccounts();
-
// The ProfileOAuth2TokenService associated with this reconcilor.
ProfileOAuth2TokenService* token_service_;
@@ -186,7 +162,6 @@
// The GaiaCookieManagerService associated with this reconcilor.
GaiaCookieManagerService* cookie_manager_service_;
- scoped_ptr<GaiaAuthFetcher> gaia_fetcher_;
bool registered_with_token_service_;
bool registered_with_cookie_manager_service_;
bool registered_with_content_settings_;
@@ -205,7 +180,6 @@
// a pair that holds the email address of the account and a boolean that
// indicates whether the account is valid or not. The accounts in the vector
// are ordered the in same way as the gaia cookie.
- bool are_gaia_accounts_set_;
std::vector<std::pair<std::string, bool> > gaia_accounts_;
// Used during reconcile action.
@@ -215,11 +189,6 @@
std::vector<std::string> add_to_cookie_;
bool chrome_accounts_changed_;
- std::deque<GetAccountsFromCookieCallback> get_gaia_accounts_callbacks_;
-
- scoped_ptr<SigninClient::CookieChangedSubscription>
- cookie_changed_subscription_;
-
DISALLOW_COPY_AND_ASSIGN(AccountReconcilor);
};
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.cc b/components/signin/core/browser/gaia_cookie_manager_service.cc
index 1aef48f..ccea52aa 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service.cc
+++ b/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -15,6 +15,7 @@
#include "base/values.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "google_apis/gaia/gaia_auth_fetcher.h"
+#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/oauth2_token_service.h"
@@ -72,12 +73,9 @@
GaiaCookieManagerService::GaiaCookieRequest::GaiaCookieRequest(
GaiaCookieRequestType request_type,
- const std::string& account_id,
- const GaiaCookieManagerService::ListAccountsCallback&
- list_accounts_callback)
+ const std::string& account_id)
: request_type_(request_type),
- account_id_(account_id),
- list_accounts_callback_(list_accounts_callback) {}
+ account_id_(account_id) {}
GaiaCookieManagerService::GaiaCookieRequest::~GaiaCookieRequest() {
}
@@ -87,28 +85,21 @@
GaiaCookieManagerService::GaiaCookieRequest::CreateAddAccountRequest(
const std::string& account_id) {
return GaiaCookieManagerService::GaiaCookieRequest(
- GaiaCookieManagerService::GaiaCookieRequestType::ADD_ACCOUNT,
- account_id,
- GaiaCookieManagerService::ListAccountsCallback());
+ GaiaCookieManagerService::GaiaCookieRequestType::ADD_ACCOUNT, account_id);
}
// static
GaiaCookieManagerService::GaiaCookieRequest
GaiaCookieManagerService::GaiaCookieRequest::CreateLogOutRequest() {
return GaiaCookieManagerService::GaiaCookieRequest(
- GaiaCookieManagerService::GaiaCookieRequestType::LOG_OUT,
- std::string(),
- GaiaCookieManagerService::ListAccountsCallback());
+ GaiaCookieManagerService::GaiaCookieRequestType::LOG_OUT, std::string());
}
GaiaCookieManagerService::GaiaCookieRequest
-GaiaCookieManagerService::GaiaCookieRequest::CreateListAccountsRequest(
- const GaiaCookieManagerService::ListAccountsCallback&
- list_accounts_callback) {
+GaiaCookieManagerService::GaiaCookieRequest::CreateListAccountsRequest() {
return GaiaCookieManagerService::GaiaCookieRequest(
GaiaCookieManagerService::GaiaCookieRequestType::LIST_ACCOUNTS,
- std::string(),
- list_accounts_callback);
+ std::string());
}
GaiaCookieManagerService::ExternalCcResultFetcher::ExternalCcResultFetcher(
@@ -295,7 +286,8 @@
gaia_auth_fetcher_backoff_(&kBackoffPolicy),
gaia_auth_fetcher_retries_(0),
source_(source),
- external_cc_result_fetched_(false) {
+ external_cc_result_fetched_(false),
+ list_accounts_fetched_once_(false) {
}
GaiaCookieManagerService::~GaiaCookieManagerService() {
@@ -303,8 +295,26 @@
DCHECK(requests_.empty());
}
+void GaiaCookieManagerService::Init() {
+ cookie_changed_subscription_ = signin_client_->AddCookieChangedCallback(
+ GaiaUrls::GetInstance()->google_url(),
+ "APISID",
+ base::Bind(&GaiaCookieManagerService::OnCookieChanged,
+ base::Unretained(this)));
+}
+
+void GaiaCookieManagerService::Shutdown() {
+ cookie_changed_subscription_.reset();
+}
+
void GaiaCookieManagerService::AddAccountToCookie(
const std::string& account_id) {
+ if (!signin_client_->AreSigninCookiesAllowed()) {
+ SignalComplete(account_id,
+ GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
+ return;
+ }
+
DCHECK(!account_id.empty());
VLOG(1) << "GaiaCookieManagerService::AddAccountToCookie: " << account_id;
requests_.push_back(GaiaCookieRequest::CreateAddAccountRequest(account_id));
@@ -312,25 +322,26 @@
StartFetchingUbertoken();
}
-void GaiaCookieManagerService::ListAccounts(
- const ListAccountsCallback& callback) {
- // Not implemented yet.
- NOTREACHED();
+bool GaiaCookieManagerService::ListAccounts(
+ std::vector<std::pair<std::string,bool> >* accounts) {
+ DCHECK(accounts);
+ accounts->clear();
- // TODO(mlerman): Once this service listens to all GAIA cookie changes, cache
- // the results of ListAccounts, and return them here if the GAIA cookie
- // hasn't changed since the last call.
+ // There is a fetch currently executing (the results being provided in the
+ // parameter don't align with the fetches that have been started), or the list
+ // of accounts haven't been fetched even once.
+ if (!requests_.empty())
+ return false;
- // If there's a GAIA call being executed, wait for it to complete. If it was
- // another /ListAccounts then we'll use the results it caches.
- if (gaia_auth_fetcher_)
- return;
+ if (!list_accounts_fetched_once_) {
+ gaia_auth_fetcher_retries_ = 0;
+ requests_.push_back(GaiaCookieRequest::CreateListAccountsRequest());
+ StartFetchingListAccounts();
+ return false;
+ }
- VLOG(1) << "GaiaCookieManagerService::ListAccounts";
- gaia_auth_fetcher_.reset(
- new GaiaAuthFetcher(this, source_,
- signin_client_->GetURLRequestContext()));
- gaia_auth_fetcher_->StartListAccounts();
+ accounts->assign(listed_accounts_.begin(), listed_accounts_.end());
+ return true;
}
void GaiaCookieManagerService::LogOutAllAccounts() {
@@ -394,6 +405,41 @@
gaia_auth_fetcher_timer_.Stop();
}
+// It is unknown if the cookie was changed because of processing initiated by
+// this class or other (such as the user clearing all cookies or a cookie being
+// evicted).
+void GaiaCookieManagerService::OnCookieChanged(
+ const net::CanonicalCookie& cookie,
+ bool removed) {
+ DCHECK_EQ("APISID", cookie.Name());
+ DCHECK_EQ(GaiaUrls::GetInstance()->google_url().host(), cookie.Domain());
+ gaia_auth_fetcher_retries_ = 0;
+ if (requests_.empty()) {
+ requests_.push_back(GaiaCookieRequest::CreateListAccountsRequest());
+ StartFetchingListAccounts();
+ } else {
+ // Remove all pending ListAccount calls; for efficiency, only call
+ // after all pending requests are processed.
+ // Track requests to keep; all other unstarted requests will be removed.
+ std::vector<GaiaCookieRequest> requests_to_keep;
+
+ // Check all pending, non-executing requests.
+ for (auto it = requests_.begin() + 1; it != requests_.end(); ++it) {
+ // Keep all requests except for LIST_ACCOUNTS.
+ if (it->request_type() != GaiaCookieRequestType::LIST_ACCOUNTS)
+ requests_to_keep.push_back(*it);
+ }
+
+ // Remove all but the executing request. Re-add all requests being kept.
+ if (requests_.size() > 1) {
+ requests_.erase(requests_.begin() + 1, requests_.end());
+ requests_.insert(
+ requests_.end(), requests_to_keep.begin(), requests_to_keep.end());
+ }
+ requests_.push_back(GaiaCookieRequest::CreateListAccountsRequest());
+ }
+}
+
void GaiaCookieManagerService::SignalComplete(
const std::string& account_id,
const GoogleServiceAuthError& error) {
@@ -446,6 +492,8 @@
void GaiaCookieManagerService::OnMergeSessionSuccess(const std::string& data) {
VLOG(1) << "MergeSession successful account="
<< requests_.front().account_id();
+ DCHECK(requests_.front().request_type() ==
+ GaiaCookieRequestType::ADD_ACCOUNT);
const std::string account_id = requests_.front().account_id();
HandleNextRequest();
SignalComplete(account_id, GoogleServiceAuthError::AuthErrorNone());
@@ -456,10 +504,11 @@
void GaiaCookieManagerService::OnMergeSessionFailure(
const GoogleServiceAuthError& error) {
+ DCHECK(requests_.front().request_type() ==
+ GaiaCookieRequestType::ADD_ACCOUNT);
VLOG(1) << "Failed MergeSession"
<< " account=" << requests_.front().account_id()
<< " error=" << error.ToString();
-
if (++gaia_auth_fetcher_retries_ < kMaxGaiaAuthFetcherRetries &&
IsTransientError(error)) {
gaia_auth_fetcher_backoff_.InformOfRequest(false);
@@ -475,6 +524,46 @@
SignalComplete(account_id, error);
}
+void GaiaCookieManagerService::OnListAccountsSuccess(const std::string& data) {
+ VLOG(1) << "ListAccounts successful";
+ DCHECK(requests_.front().request_type() ==
+ GaiaCookieRequestType::LIST_ACCOUNTS);
+ gaia_auth_fetcher_backoff_.InformOfRequest(true);
+
+ if (!gaia::ParseListAccountsData(data, &listed_accounts_)) {
+ listed_accounts_.clear();
+ OnListAccountsFailure(GoogleServiceAuthError(
+ GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE));
+ return;
+ }
+
+ list_accounts_fetched_once_ = true;
+ FOR_EACH_OBSERVER(Observer, observer_list_,
+ OnGaiaAccountsInCookieUpdated(
+ listed_accounts_,
+ GoogleServiceAuthError(GoogleServiceAuthError::NONE)));
+ HandleNextRequest();
+}
+
+void GaiaCookieManagerService::OnListAccountsFailure(
+ const GoogleServiceAuthError& error) {
+ VLOG(1) << "ListAccounts failed";
+ DCHECK(requests_.front().request_type() ==
+ GaiaCookieRequestType::LIST_ACCOUNTS);
+ if (++gaia_auth_fetcher_retries_ < kMaxGaiaAuthFetcherRetries &&
+ IsTransientError(error)) {
+ gaia_auth_fetcher_backoff_.InformOfRequest(false);
+ gaia_auth_fetcher_timer_.Start(
+ FROM_HERE, gaia_auth_fetcher_backoff_.GetTimeUntilRelease(), this,
+ &GaiaCookieManagerService::StartFetchingListAccounts);
+ return;
+ }
+
+ FOR_EACH_OBSERVER(Observer, observer_list_,
+ OnGaiaAccountsInCookieUpdated(listed_accounts_, error));
+ HandleNextRequest();
+}
+
void GaiaCookieManagerService::StartFetchingUbertoken() {
VLOG(1) << "GaiaCookieManagerService::StartFetching account_id="
<< requests_.front().account_id();
@@ -494,6 +583,14 @@
external_cc_result_fetcher_.GetExternalCcResult());
}
+void GaiaCookieManagerService::StartFetchingListAccounts() {
+ VLOG(1) << "GaiaCookieManagerService::ListAccounts";
+ gaia_auth_fetcher_.reset(
+ new GaiaAuthFetcher(this, source_,
+ signin_client_->GetURLRequestContext()));
+ gaia_auth_fetcher_->StartListAccounts();
+}
+
void GaiaCookieManagerService::OnURLFetchComplete(
const net::URLFetcher* source) {
DCHECK(requests_.front().request_type() == GaiaCookieRequestType::LOG_OUT);
@@ -503,8 +600,20 @@
void GaiaCookieManagerService::HandleNextRequest() {
VLOG(1) << "GaiaCookieManagerService::HandleNextRequest";
- requests_.pop_front();
+ if (requests_.front().request_type() ==
+ GaiaCookieRequestType::LIST_ACCOUNTS) {
+ // This and any directly subsequent list accounts would return the same.
+ while (!requests_.empty() && requests_.front().request_type() ==
+ GaiaCookieRequestType::LIST_ACCOUNTS) {
+ requests_.pop_front();
+ }
+ } else {
+ // Pop the completed request.
+ requests_.pop_front();
+ }
+
gaia_auth_fetcher_.reset();
+ gaia_auth_fetcher_retries_ = 0;
if (requests_.empty()) {
VLOG(1) << "GaiaCookieManagerService::HandleNextRequest: no more";
uber_token_fetcher_.reset();
@@ -517,6 +626,8 @@
StartLogOutUrlFetch();
break;
case GaiaCookieRequestType::LIST_ACCOUNTS:
+ uber_token_fetcher_.reset();
+ StartFetchingListAccounts();
break;
};
}
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.h b/components/signin/core/browser/gaia_cookie_manager_service.h
index ff9d4b0..74df85d 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service.h
+++ b/components/signin/core/browser/gaia_cookie_manager_service.h
@@ -16,6 +16,7 @@
#include "net/url_request/url_fetcher_delegate.h"
class GaiaAuthFetcher;
+class GaiaCookieRequest;
class GoogleServiceAuthError;
class OAuth2TokenService;
@@ -36,11 +37,6 @@
public UbertokenConsumer,
public net::URLFetcherDelegate {
public:
- typedef base::Callback<void(const std::string& data,
- const GoogleServiceAuthError& error)>
- ListAccountsCallback;
-
-
enum GaiaCookieRequestType {
ADD_ACCOUNT,
LOG_OUT,
@@ -54,28 +50,19 @@
GaiaCookieRequestType request_type() const { return request_type_; }
const std::string& account_id() const {return account_id_; }
- const GaiaCookieManagerService::ListAccountsCallback&
- list_accounts_callback() const {
- return list_accounts_callback_;
- }
static GaiaCookieRequest CreateAddAccountRequest(
const std::string& account_id);
static GaiaCookieRequest CreateLogOutRequest();
- static GaiaCookieRequest CreateListAccountsRequest(
- const GaiaCookieManagerService::ListAccountsCallback&
- list_accounts_callback);
+ static GaiaCookieRequest CreateListAccountsRequest();
private:
GaiaCookieRequest(
GaiaCookieRequestType request_type,
- const std::string& account_id,
- const GaiaCookieManagerService::ListAccountsCallback&
- list_accounts_callback);
+ const std::string& account_id);
GaiaCookieRequestType request_type_;
std::string account_id_;
- GaiaCookieManagerService::ListAccountsCallback list_accounts_callback_;
};
class Observer {
@@ -85,7 +72,18 @@
// GoogleServiceAuthError::AuthErrorNone() then the merge succeeeded.
virtual void OnAddAccountToCookieCompleted(
const std::string& account_id,
- const GoogleServiceAuthError& error) = 0;
+ const GoogleServiceAuthError& error) {}
+
+ // Called whenever the GaiaCookieManagerService's list of GAIA accounts is
+ // updated. The GCMS monitors the APISID cookie and triggers a /ListAccounts
+ // call on change. The GCMS will also call ListAccounts upon the first call
+ // to ListAccounts(). The GCMS will delay calling ListAccounts if other
+ // requests are in queue that would modify the APISID cookie.
+ // If the ListAccounts call fails and the GCMS cannot recover, the reason
+ // is passed in |error|.
+ virtual void OnGaiaAccountsInCookieUpdated(
+ const std::vector<std::pair<std::string, bool> >& accounts,
+ const GoogleServiceAuthError& error) {}
protected:
virtual ~Observer() {}
@@ -158,9 +156,16 @@
SigninClient* signin_client);
~GaiaCookieManagerService() override;
+ void Init();
+ void Shutdown() override;
+
void AddAccountToCookie(const std::string& account_id);
- void ListAccounts(const ListAccountsCallback& callback);
+ // Returns if the listed accounts are up to date or not (ignore the out
+ // parameter if return is false). The parameter will be assigned the current
+ // cached accounts. If the accounts are not up to date, a ListAccounts fetch
+ // is sent GAIA and Observer::OnGaiaAccountsInCookieUpdated will be called.
+ bool ListAccounts(std::vector<std::pair<std::string,bool> >* accounts);
// Add or remove observers of this helper.
void AddObserver(Observer* observer);
@@ -186,11 +191,19 @@
return &external_cc_result_fetcher_;
}
+ void set_list_accounts_fetched_once_for_testing(bool fetched) {
+ list_accounts_fetched_once_ = fetched;
+ }
+
private:
net::URLRequestContextGetter* request_context() {
return signin_client_->GetURLRequestContext();
}
+ // Called when a cookie changes. If the cookie relates to a GAIA APISID
+ // cookie, then we call ListAccounts and fire OnGaiaAccountsInCookieUpdated.
+ void OnCookieChanged(const net::CanonicalCookie& cookie, bool removed);
+
// Overridden from UbertokenConsumer.
void OnUbertokenSuccess(const std::string& token) override;
void OnUbertokenFailure(const GoogleServiceAuthError& error) override;
@@ -198,6 +211,8 @@
// Overridden from GaiaAuthConsumer.
void OnMergeSessionSuccess(const std::string& data) override;
void OnMergeSessionFailure(const GoogleServiceAuthError& error) override;
+ void OnListAccountsSuccess(const std::string& data) override;
+ void OnListAccountsFailure(const GoogleServiceAuthError& error) override;
// Starts the proess of fetching the uber token and performing a merge session
// for the next account. Virtual so that it can be overriden in tests.
@@ -209,6 +224,9 @@
// Virtual for testing purpose.
virtual void StartLogOutUrlFetch();
+ // Virtual for testing purposes.
+ virtual void StartFetchingListAccounts();
+
// Start the next request, if needed.
void HandleNextRequest();
@@ -229,6 +247,10 @@
// The last fetched ubertoken, for use in MergeSession retries.
std::string uber_token_;
+ // Subscription to be called whenever the GAIA cookies change.
+ scoped_ptr<SigninClient::CookieChangedSubscription>
+ cookie_changed_subscription_;
+
// A worklist for this class. Stores any pending requests that couldn't be
// executed right away, since this class only permits one request to be
// executed at a time.
@@ -244,6 +266,10 @@
// True once the ExternalCCResultFetcher has completed once.
bool external_cc_result_fetched_;
+ std::vector<std::pair<std::string, bool> > listed_accounts_;
+
+ bool list_accounts_fetched_once_;
+
DISALLOW_COPY_AND_ASSIGN(GaiaCookieManagerService);
};
diff --git a/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc b/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
index cc04452..170a17a 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
+++ b/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
@@ -31,8 +31,9 @@
MOCK_METHOD2(OnAddAccountToCookieCompleted,
void(const std::string&, const GoogleServiceAuthError&));
- MOCK_METHOD1(GetCheckConnectionInfoCompleted, void(bool));
-
+ MOCK_METHOD2(OnGaiaAccountsInCookieUpdated,
+ void(const std::vector<std::pair<std::string, bool> >&,
+ const GoogleServiceAuthError&));
private:
GaiaCookieManagerService* helper_;
@@ -59,6 +60,7 @@
virtual ~InstrumentedGaiaCookieManagerService() { total--; }
MOCK_METHOD0(StartFetchingUbertoken, void());
+ MOCK_METHOD0(StartFetchingListAccounts, void());
MOCK_METHOD0(StartFetchingMergeSession, void());
MOCK_METHOD0(StartLogOutUrlFetch, void());
@@ -74,7 +76,7 @@
canceled_(GoogleServiceAuthError::REQUEST_CANCELED) {}
OAuth2TokenService* token_service() { return &token_service_; }
- SigninClient* signin_client() { return &signin_client_; }
+ TestSigninClient* signin_client() { return &signin_client_; }
void SimulateUbertokenSuccess(UbertokenConsumer* consumer,
const std::string& uber_token) {
@@ -96,6 +98,11 @@
consumer->OnMergeSessionFailure(error);
}
+ void SimulateListAccountsSuccess(GaiaAuthConsumer* consumer,
+ const std::string& data) {
+ consumer->OnListAccountsSuccess(data);
+ }
+
void SimulateLogoutSuccess(net::URLFetcherDelegate* consumer) {
consumer->OnURLFetchComplete(NULL);
}
@@ -164,6 +171,17 @@
DCHECK(!helper.is_running());
}
+TEST_F(GaiaCookieManagerServiceTest, AddAccountCookiesDisabled) {
+ InstrumentedGaiaCookieManagerService helper(token_service(), signin_client());
+ MockObserver observer(&helper);
+ signin_client()->set_are_signin_cookies_allowed(false);
+
+ EXPECT_CALL(observer, OnAddAccountToCookieCompleted("[email protected]",
+ canceled()));
+
+ helper.AddAccountToCookie("[email protected]");
+}
+
TEST_F(GaiaCookieManagerServiceTest, MergeSessionRetried) {
InstrumentedGaiaCookieManagerService helper(token_service(), signin_client());
MockObserver observer(&helper);
@@ -378,7 +396,6 @@
EXPECT_CALL(helper, StartLogOutUrlFetch());
EXPECT_CALL(observer, OnAddAccountToCookieCompleted("[email protected]",
no_error()));
-
helper.AddAccountToCookie("[email protected]");
SimulateMergeSessionSuccess(&helper, "token1");
@@ -445,8 +462,6 @@
InstrumentedGaiaCookieManagerService helper(token_service(), signin_client());
MockObserver observer(&helper);
- std::vector<std::string> current_accounts;
-
EXPECT_CALL(helper, StartFetchingUbertoken());
EXPECT_CALL(observer, OnAddAccountToCookieCompleted("[email protected]",
canceled()));
@@ -462,6 +477,37 @@
SimulateLogoutSuccess(&helper);
}
+TEST_F(GaiaCookieManagerServiceTest, ListAccountsFirstReturnsEmpty) {
+ InstrumentedGaiaCookieManagerService helper(token_service(), signin_client());
+ MockObserver observer(&helper);
+
+ std::vector<std::pair<std::string, bool> > list_accounts;
+
+ EXPECT_CALL(helper, StartFetchingListAccounts());
+
+ ASSERT_FALSE(helper.ListAccounts(&list_accounts));
+ ASSERT_TRUE(list_accounts.empty());
+}
+
+TEST_F(GaiaCookieManagerServiceTest, ListAccountsFindsOneAccount) {
+ InstrumentedGaiaCookieManagerService helper(token_service(), signin_client());
+ MockObserver observer(&helper);
+
+ std::vector<std::pair<std::string, bool> > list_accounts;
+ std::vector<std::pair<std::string, bool> > expected_accounts;
+ expected_accounts.push_back(std::pair<std::string, bool>(
+ "[email protected]", true));
+
+ EXPECT_CALL(helper, StartFetchingListAccounts());
+ EXPECT_CALL(observer, OnGaiaAccountsInCookieUpdated(expected_accounts,
+ no_error()));
+
+ ASSERT_FALSE(helper.ListAccounts(&list_accounts));
+
+ SimulateListAccountsSuccess(&helper,
+ "[\"f\", [[\"b\", 0, \"n\", \"[email protected]\", \"p\", 0, 0, 0, 0, 1]]]");
+}
+
TEST_F(GaiaCookieManagerServiceTest, ExternalCcResultFetcher) {
InstrumentedGaiaCookieManagerService helper(token_service(), signin_client());
GaiaCookieManagerService::ExternalCcResultFetcher result_fetcher(&helper);
diff --git a/components/signin/core/browser/signin_tracker.cc b/components/signin/core/browser/signin_tracker.cc
index ad5954f6..9e76b86 100644
--- a/components/signin/core/browser/signin_tracker.cc
+++ b/components/signin/core/browser/signin_tracker.cc
@@ -4,7 +4,6 @@
#include "components/signin/core/browser/signin_tracker.h"
-#include "components/signin/core/browser/account_reconcilor.h"
#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_client.h"
@@ -12,13 +11,11 @@
SigninTracker::SigninTracker(ProfileOAuth2TokenService* token_service,
SigninManagerBase* signin_manager,
- AccountReconcilor* account_reconcilor,
GaiaCookieManagerService* cookie_manager_service,
SigninClient* client,
Observer* observer)
: token_service_(token_service),
signin_manager_(signin_manager),
- account_reconcilor_(account_reconcilor),
cookie_manager_service_(cookie_manager_service),
client_(client),
observer_(observer) {
diff --git a/components/signin/core/browser/signin_tracker.h b/components/signin/core/browser/signin_tracker.h
index 2dcd5c91..5f82bd00 100644
--- a/components/signin/core/browser/signin_tracker.h
+++ b/components/signin/core/browser/signin_tracker.h
@@ -10,7 +10,6 @@
#include "components/signin/core/browser/signin_manager.h"
#include "google_apis/gaia/google_service_auth_error.h"
-class AccountReconcilor;
class ProfileOAuth2TokenService;
class SigninClient;
@@ -75,7 +74,6 @@
// non-null.
SigninTracker(ProfileOAuth2TokenService* token_service,
SigninManagerBase* signin_manager,
- AccountReconcilor* account_reconcilor,
GaiaCookieManagerService* cookie_manager_service,
SigninClient* client,
Observer* observer);
@@ -100,7 +98,6 @@
// The classes whose collective signin status we are tracking.
ProfileOAuth2TokenService* token_service_;
SigninManagerBase* signin_manager_;
- AccountReconcilor* account_reconcilor_;
GaiaCookieManagerService* cookie_manager_service_;
// The client associated with this instance.
diff --git a/components/signin/ios/browser/merge_session_observer_bridge.h b/components/signin/ios/browser/merge_session_observer_bridge.h
index 6703ab72..8137dbbf1 100644
--- a/components/signin/ios/browser/merge_session_observer_bridge.h
+++ b/components/signin/ios/browser/merge_session_observer_bridge.h
@@ -12,7 +12,6 @@
#include "base/macros.h"
#include "components/signin/core/browser/gaia_cookie_manager_service.h"
-class AccountReconcilor;
class GoogleServiceAuthError;
@protocol MergeSessionObserverBridgeDelegate
diff --git a/google_apis/gaia/gaia_constants.cc b/google_apis/gaia/gaia_constants.cc
index 4c00536..d3d0cd9 100644
--- a/google_apis/gaia/gaia_constants.cc
+++ b/google_apis/gaia/gaia_constants.cc
@@ -11,7 +11,6 @@
// Gaia uses this for accounting where login is coming from.
const char kChromeOSSource[] = "chromeos";
const char kChromeSource[] = "ChromiumBrowser";
-const char kReconcilorSource[] = "ChromiumReconcilor";
// Service name for Gaia. Used to convert to cookie auth.
const char kGaiaService[] = "gaia";
diff --git a/google_apis/gaia/gaia_constants.h b/google_apis/gaia/gaia_constants.h
index d7ffb97..4786ac88 100644
--- a/google_apis/gaia/gaia_constants.h
+++ b/google_apis/gaia/gaia_constants.h
@@ -12,7 +12,6 @@
// Gaia sources for accounting
extern const char kChromeOSSource[];
extern const char kChromeSource[];
-extern const char kReconcilorSource[];
// Gaia services for requesting
extern const char kGaiaService[]; // uber token
diff --git a/google_apis/gaia/gaia_switches.cc b/google_apis/gaia/gaia_switches.cc
index a1879d1..3e46829 100644
--- a/google_apis/gaia/gaia_switches.cc
+++ b/google_apis/gaia/gaia_switches.cc
@@ -6,6 +6,7 @@
namespace switches {
+const char kGoogleUrl[] = "google-url";
const char kGaiaUrl[] = "gaia-url";
const char kGoogleApisUrl[] = "google-apis-url";
const char kLsoUrl[] = "lso-url";
diff --git a/google_apis/gaia/gaia_switches.h b/google_apis/gaia/gaia_switches.h
index bc69ebe..63921a04 100644
--- a/google_apis/gaia/gaia_switches.h
+++ b/google_apis/gaia/gaia_switches.h
@@ -7,6 +7,10 @@
namespace switches {
+// Specifies the domain of the APISID cookie. The default value is
+// "http://.google.com".
+extern const char kGoogleUrl[];
+
// Specifies the path for GAIA authentication URL. The default value is
// "https://accounts.google.com".
extern const char kGaiaUrl[];
diff --git a/google_apis/gaia/gaia_urls.cc b/google_apis/gaia/gaia_urls.cc
index 6545d564..95d5245 100644
--- a/google_apis/gaia/gaia_urls.cc
+++ b/google_apis/gaia/gaia_urls.cc
@@ -13,6 +13,7 @@
namespace {
// Gaia service constants
+const char kDefaultGoogleUrl[] = "http://.google.com";
const char kDefaultGaiaUrl[] = "https://accounts.google.com";
const char kDefaultGoogleApisBaseUrl[] = "https://www.googleapis.com";
@@ -76,6 +77,8 @@
}
GaiaUrls::GaiaUrls() {
+ google_url_ = GetURLSwitchValueWithDefault(switches::kGoogleUrl,
+ kDefaultGoogleUrl);
gaia_url_ = GetURLSwitchValueWithDefault(switches::kGaiaUrl, kDefaultGaiaUrl);
lso_origin_url_ =
GetURLSwitchValueWithDefault(switches::kLsoUrl, kDefaultGaiaUrl);
@@ -137,6 +140,10 @@
GaiaUrls::~GaiaUrls() {
}
+const GURL& GaiaUrls::google_url() const {
+ return google_url_;
+}
+
const GURL& GaiaUrls::gaia_url() const {
return gaia_url_;
}
diff --git a/google_apis/gaia/gaia_urls.h b/google_apis/gaia/gaia_urls.h
index b5453f2..bbb21177 100644
--- a/google_apis/gaia/gaia_urls.h
+++ b/google_apis/gaia/gaia_urls.h
@@ -16,6 +16,7 @@
static GaiaUrls* GetInstance();
// The URLs for different calls in the Google Accounts programmatic login API.
+ const GURL& google_url() const;
const GURL& gaia_url() const;
const GURL& captcha_base_url() const;
const GURL& client_login_url() const;
@@ -57,6 +58,7 @@
friend struct DefaultSingletonTraits<GaiaUrls>;
+ GURL google_url_;
GURL gaia_url_;
GURL captcha_base_url_;