1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file. 48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "components/signin/core/browser/account_reconcilor.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <algorithm> 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/json/json_reader.h" 111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/logging.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/time/time.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h" 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_client.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/signin/core/browser/signin_metrics.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/signin/core/common/profile_management_switches.h" 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_fetcher.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "google_apis/gaia/gaia_constants.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/gaia_oauth_client.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/gaia_urls.h" 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/cookies/canonical_cookie.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace { 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class EmailEqualToFunc : public std::equal_to<std::pair<std::string, bool> > { 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public: 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool operator()(const std::pair<std::string, bool>& p1, 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::pair<std::string, bool>& p2) const; 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}; 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool EmailEqualToFunc::operator()( 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::pair<std::string, bool>& p1, 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::pair<std::string, bool>& p2) const { 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return p1.second == p2.second && gaia::AreEmailsSame(p1.first, p2.first); 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass AreEmailsSameFunc : public std::equal_to<std::string> { 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool operator()(const std::string& p1, 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& p2) const; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool AreEmailsSameFunc::operator()( 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& p1, 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& p2) const { 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return gaia::AreEmailsSame(p1, p2); 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochAccountReconcilor::AccountReconcilor(ProfileOAuth2TokenService* token_service, 58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SigninManagerBase* signin_manager, 59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SigninClient* client) 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : token_service_(token_service), 61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch signin_manager_(signin_manager), 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch client_(client), 63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch merge_session_helper_(token_service_, 64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch client->GetURLRequestContext(), 65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch this), 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registered_with_token_service_(false), 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_reconcile_started_(false), 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) first_execution_(true), 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci are_gaia_accounts_set_(false) { 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::AccountReconcilor"; 711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)AccountReconcilor::~AccountReconcilor() { 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "AccountReconcilor::~AccountReconcilor"; 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Make sure shutdown was called first. 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!registered_with_token_service_); 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) { 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "AccountReconcilor::Initialize"; 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RegisterWithSigninManager(); 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // If this user is not signed in, the reconcilor should do nothing but 84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // wait for signin. 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsProfileConnected()) { 86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch RegisterForCookieChanges(); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RegisterWithTokenService(); 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Start a reconcile if the tokens are already loaded. 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (start_reconcile_if_tokens_available && 91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch token_service_->GetAccounts().size() > 0) { 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StartReconcile(); 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AccountReconcilor::Shutdown() { 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::Shutdown"; 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.CancelAll(); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.RemoveObserver(this); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gaia_fetcher_.reset(); 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) get_gaia_accounts_callbacks_.clear(); 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UnregisterWithSigninManager(); 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UnregisterWithTokenService(); 105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch UnregisterForCookieChanges(); 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::AddMergeSessionObserver( 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MergeSessionHelper::Observer* observer) { 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.AddObserver(observer); 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::RemoveMergeSessionObserver( 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MergeSessionHelper::Observer* observer) { 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.RemoveObserver(observer); 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid AccountReconcilor::RegisterForCookieChanges() { 119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // First clear any existing registration to avoid DCHECKs that can otherwise 120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // go off in some embedders on reauth (e.g., ChromeSigninClient). 121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch UnregisterForCookieChanges(); 1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cookie_changed_subscription_ = client_->AddCookieChangedCallback( 123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::Bind(&AccountReconcilor::OnCookieChanged, base::Unretained(this))); 1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid AccountReconcilor::UnregisterForCookieChanges() { 1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cookie_changed_subscription_.reset(); 1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::RegisterWithSigninManager() { 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch signin_manager_->AddObserver(this); 1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::UnregisterWithSigninManager() { 135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch signin_manager_->RemoveObserver(this); 1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::RegisterWithTokenService() { 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::RegisterWithTokenService"; 1404ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // During re-auth, the reconcilor will get a callback about successful signin 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // even when the profile is already connected. Avoid re-registering 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // with the token service since this will DCHECK. 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (registered_with_token_service_) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch token_service_->AddObserver(this); 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registered_with_token_service_ = true; 1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::UnregisterWithTokenService() { 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!registered_with_token_service_) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch token_service_->RemoveObserver(this); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registered_with_token_service_ = false; 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool AccountReconcilor::IsProfileConnected() { 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return signin_manager_->IsAuthenticated(); 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid AccountReconcilor::OnCookieChanged(const net::CanonicalCookie* cookie) { 163e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (cookie->Name() == "LSID" && 164e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch cookie->Domain() == GaiaUrls::GetInstance()->gaia_url().host() && 165e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch cookie->IsSecure() && cookie->IsHttpOnly()) { 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnCookieChanged: LSID changed"; 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // It is possible that O2RT is not available at this moment. 169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!token_service_->GetAccounts().size()) { 170e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch VLOG(1) << "AccountReconcilor::OnCookieChanged: cookie change is ingored" 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "because O2RT is not available yet."; 172e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 173e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartReconcile(); 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AccountReconcilor::OnEndBatchChanges() { 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VLOG(1) << "AccountReconcilor::OnEndBatchChanges"; 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch StartReconcile(); 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AccountReconcilor::GoogleSigninSucceeded(const std::string& account_id, 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& username, 186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& password) { 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::GoogleSigninSucceeded: signed in"; 188e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch RegisterForCookieChanges(); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RegisterWithTokenService(); 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AccountReconcilor::GoogleSignedOut(const std::string& account_id, 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& username) { 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::GoogleSignedOut: signed out"; 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gaia_fetcher_.reset(); 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) get_gaia_accounts_callbacks_.clear(); 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AbortReconcile(); 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UnregisterWithTokenService(); 199e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch UnregisterForCookieChanges(); 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PerformLogoutAllAccountsAction(); 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::PerformMergeAction(const std::string& account_id) { 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!switches::IsEnableAccountConsistency()) { 2056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) MarkAccountAsAddedToCookie(account_id); 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 2076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::PerformMergeAction: " << account_id; 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.LogIn(account_id); 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::PerformLogoutAllAccountsAction() { 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!switches::IsEnableAccountConsistency()) 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::PerformLogoutAllAccountsAction"; 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.LogOutAllAccounts(); 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::StartReconcile() { 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!IsProfileConnected() || is_reconcile_started_ || 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch get_gaia_accounts_callbacks_.size() > 0 || 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch merge_session_helper_.is_running()) 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_reconcile_started_ = true; 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) StartFetchingExternalCcResult(); 2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reset state for validating gaia cookie. 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) are_gaia_accounts_set_ = false; 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gaia_accounts_.clear(); 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetAccountsFromCookie(base::Bind( 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts, 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Unretained(this))); 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reset state for validating oauth2 tokens. 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) primary_account_.clear(); 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome_accounts_.clear(); 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_cookie_.clear(); 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ValidateAccountsFromTokenService(); 2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::GetAccountsFromCookie( 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetAccountsFromCookieCallback callback) { 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_gaia_accounts_callbacks_.push_back(callback); 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!gaia_fetcher_) { 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There is no list account request in flight. 248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gaia_fetcher_.reset(new GaiaAuthFetcher( 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch this, GaiaConstants::kChromeSource, client_->GetURLRequestContext())); 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gaia_fetcher_->StartListAccounts(); 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void AccountReconcilor::StartFetchingExternalCcResult() { 2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) merge_session_helper_.StartFetchingExternalCcResult(); 2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AccountReconcilor::OnListAccountsSuccess(const std::string& data) { 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gaia_fetcher_.reset(); 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Get account information from response data. 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::pair<std::string, bool> > gaia_accounts; 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool valid_json = gaia::ParseListAccountsData(data, &gaia_accounts); 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!valid_json) { 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: parsing error"; 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (gaia_accounts.size() > 0) { 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: " 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Gaia " << gaia_accounts.size() << " accounts, " 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Primary is '" << gaia_accounts[0].first << "'"; 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: No accounts"; 272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There must be at least one callback waiting for result. 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!get_gaia_accounts_callbacks_.empty()); 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GoogleServiceAuthError error = 278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch !valid_json ? GoogleServiceAuthError( 279c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE) 280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : GoogleServiceAuthError::AuthErrorNone(); 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_gaia_accounts_callbacks_.front().Run(error, gaia_accounts); 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_gaia_accounts_callbacks_.pop_front(); 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MayBeDoNextListAccounts(); 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AccountReconcilor::OnListAccountsFailure( 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const GoogleServiceAuthError& error) { 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gaia_fetcher_.reset(); 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnListAccountsFailure: " << error.ToString(); 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::pair<std::string, bool> > empty_accounts; 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There must be at least one callback waiting for result. 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!get_gaia_accounts_callbacks_.empty()); 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_gaia_accounts_callbacks_.front().Run(error, empty_accounts); 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_gaia_accounts_callbacks_.pop_front(); 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MayBeDoNextListAccounts(); 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::MayBeDoNextListAccounts() { 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!get_gaia_accounts_callbacks_.empty()) { 304c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gaia_fetcher_.reset(new GaiaAuthFetcher( 305c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch this, GaiaConstants::kChromeSource, client_->GetURLRequestContext())); 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gaia_fetcher_->StartListAccounts(); 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts( 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GoogleServiceAuthError& error, 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::vector<std::pair<std::string, bool> >& accounts) { 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error.state() == GoogleServiceAuthError::NONE) { 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gaia_accounts_ = accounts; 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) are_gaia_accounts_set_ = true; 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FinishReconcile(); 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AbortReconcile(); 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AccountReconcilor::ValidateAccountsFromTokenService() { 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci primary_account_ = signin_manager_->GetAuthenticatedAccountId(); 324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!primary_account_.empty()); 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 326c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch chrome_accounts_ = token_service_->GetAccounts(); 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::ValidateAccountsFromTokenService: " 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Chrome " << chrome_accounts_.size() << " accounts, " 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Primary is '" << primary_account_ << "'"; 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AccountReconcilor::OnNewProfileManagementFlagChanged( 334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool new_flag_status) { 335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (new_flag_status) { 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // The reconciler may have been newly created just before this call, or may 337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // have already existed and in mid-reconcile. To err on the safe side, force 338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // a restart. 339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Shutdown(); 340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Initialize(true); 341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Shutdown(); 343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::FinishReconcile() { 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::FinishReconcile"; 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(are_gaia_accounts_set_); 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(add_to_cookie_.empty()); 3506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) int number_gaia_accounts = gaia_accounts_.size(); 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool are_primaries_equal = number_gaia_accounts > 0 && 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gaia::AreEmailsSame(primary_account_, gaia_accounts_[0].first); 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If there are any accounts in the gaia cookie but not in chrome, then 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // those accounts need to be removed from the cookie. This means we need 3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // to blow the cookie away. 3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int removed_from_cookie = 0; 3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0; i < gaia_accounts_.size(); ++i) { 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& gaia_account = gaia_accounts_[i].first; 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (gaia_accounts_[i].second && 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome_accounts_.end() == 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::find_if(chrome_accounts_.begin(), 3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome_accounts_.end(), 3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::bind1st(AreEmailsSameFunc(), gaia_account))) { 3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++removed_from_cookie; 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool rebuild_cookie = !are_primaries_equal || removed_from_cookie > 0; 3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<std::pair<std::string, bool> > original_gaia_accounts = 3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gaia_accounts_; 3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rebuild_cookie) { 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie"; 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Really messed up state. Blow away the gaia cookie completely and 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // rebuild it, making sure the primary account as specified by the 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // SigninManager is the first session in the gaia cookie. 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PerformLogoutAllAccountsAction(); 378010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gaia_accounts_.clear(); 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 381010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Create a list of accounts that need to be added to the gaia cookie. 382010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The primary account must be first to make sure it becomes the default 383010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // account in the case where chrome is completely rebuilding the cookie. 384010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) add_to_cookie_.push_back(primary_account_); 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0; i < chrome_accounts_.size(); ++i) { 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (chrome_accounts_[i] != primary_account_) 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci add_to_cookie_.push_back(chrome_accounts_[i]); 388010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 389010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 390010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // For each account known to chrome, PerformMergeAction() if the account is 391010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // not already in the cookie jar or its state is invalid, or signal merge 392010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // completed otherwise. Make a copy of |add_to_cookie_| since calls to 393010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // SignalComplete() will change the array. 394010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::vector<std::string> add_to_cookie_copy = add_to_cookie_; 395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int added_to_cookie = 0; 3966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool external_cc_result_completed = 3976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) !merge_session_helper_.StillFetchingExternalCcResult(); 398010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (size_t i = 0; i < add_to_cookie_copy.size(); ++i) { 399010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (gaia_accounts_.end() != 400010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::find_if(gaia_accounts_.begin(), 401010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gaia_accounts_.end(), 402010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::bind1st(EmailEqualToFunc(), 403010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::make_pair(add_to_cookie_copy[i], 404010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) true)))) { 405010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) merge_session_helper_.SignalComplete( 406010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) add_to_cookie_copy[i], 407010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GoogleServiceAuthError::AuthErrorNone()); 408010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) PerformMergeAction(add_to_cookie_copy[i]); 4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (original_gaia_accounts.end() == 4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::find_if(original_gaia_accounts.begin(), 4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci original_gaia_accounts.end(), 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::bind1st(EmailEqualToFunc(), 4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::make_pair(add_to_cookie_copy[i], 4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci true)))) { 4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci added_to_cookie++; 4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 418010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 419010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Log whether the external connection checks were completed when we tried 4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // to add the accounts to the cookie. 4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rebuild_cookie || added_to_cookie > 0) 4246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) signin_metrics::LogExternalCcResultFetches(external_cc_result_completed); 4256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci signin_metrics::LogSigninAccountReconciliation(chrome_accounts_.size(), 427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) added_to_cookie, 4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci removed_from_cookie, 429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) are_primaries_equal, 4306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) first_execution_, 4316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) number_gaia_accounts); 432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) first_execution_ = false; 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CalculateIfReconcileIsDone(); 434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScheduleStartReconcileIfChromeAccountsChanged(); 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::AbortReconcile() { 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::AbortReconcile: we'll try again later"; 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_cookie_.clear(); 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CalculateIfReconcileIsDone(); 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::CalculateIfReconcileIsDone() { 4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_reconcile_started_ = !add_to_cookie_.empty(); 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!is_reconcile_started_) 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::CalculateIfReconcileIsDone: done"; 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccountReconcilor::ScheduleStartReconcileIfChromeAccountsChanged() { 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (is_reconcile_started_) 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Start a reconcile as the token accounts have changed. 454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "AccountReconcilor::StartReconcileIfChromeAccountsChanged"; 455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string> reconciled_accounts(chrome_accounts_); 456c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::vector<std::string> new_chrome_accounts(token_service_->GetAccounts()); 457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::sort(reconciled_accounts.begin(), reconciled_accounts.end()); 458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::sort(new_chrome_accounts.begin(), new_chrome_accounts.end()); 459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (reconciled_accounts != new_chrome_accounts) { 460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MessageLoop::current()->PostTask( 461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&AccountReconcilor::StartReconcile, base::Unretained(this))); 463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 4666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Remove the account from the list that is being merged. 467116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool AccountReconcilor::MarkAccountAsAddedToCookie( 4686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const std::string& account_id) { 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::vector<std::string>::iterator i = add_to_cookie_.begin(); 470c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch i != add_to_cookie_.end(); 471c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ++i) { 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (account_id == *i) { 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_cookie_.erase(i); 474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 4786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void AccountReconcilor::MergeSessionCompleted( 4816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const std::string& account_id, 4826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const GoogleServiceAuthError& error) { 4836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) VLOG(1) << "AccountReconcilor::MergeSessionCompleted: account_id=" 4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << account_id << " error=" << error.ToString(); 4856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (MarkAccountAsAddedToCookie(account_id)) { 487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CalculateIfReconcileIsDone(); 488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScheduleStartReconcileIfChromeAccountsChanged(); 489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 491