| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/signin/core/browser/account_reconcilor.h" | 5 #include "components/signin/core/browser/account_reconcilor.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
| 14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/thread_task_runner_handle.h" | 15 #include "base/thread_task_runner_handle.h" |
| 16 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 16 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
| 17 #include "components/signin/core/browser/signin_client.h" | 17 #include "components/signin/core/browser/signin_client.h" |
| 18 #include "components/signin/core/browser/signin_metrics.h" | 18 #include "components/signin/core/browser/signin_metrics.h" |
| 19 #include "components/signin/core/common/profile_management_switches.h" | 19 #include "components/signin/core/common/profile_management_switches.h" |
| 20 #include "google_apis/gaia/gaia_auth_util.h" | 20 #include "google_apis/gaia/gaia_auth_util.h" |
| 21 #include "google_apis/gaia/gaia_oauth_client.h" | 21 #include "google_apis/gaia/gaia_oauth_client.h" |
| 22 #include "google_apis/gaia/gaia_urls.h" | 22 #include "google_apis/gaia/gaia_urls.h" |
| 23 | 23 |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 class EmailEqualToFunc : public std::equal_to<std::pair<std::string, bool> > { | 27 class EmailEqualToFunc : public std::equal_to<gaia::ListedAccount> { |
| 28 public: | 28 public: |
| 29 bool operator()(const std::pair<std::string, bool>& p1, | 29 bool operator()(const gaia::ListedAccount& p1, |
| 30 const std::pair<std::string, bool>& p2) const; | 30 const gaia::ListedAccount& p2) const; |
| 31 }; | 31 }; |
| 32 | 32 |
| 33 bool EmailEqualToFunc::operator()( | 33 bool EmailEqualToFunc::operator()( |
| 34 const std::pair<std::string, bool>& p1, | 34 const gaia::ListedAccount& p1, |
| 35 const std::pair<std::string, bool>& p2) const { | 35 const gaia::ListedAccount& p2) const { |
| 36 return p1.second == p2.second && gaia::AreEmailsSame(p1.first, p2.first); | 36 return p1.valid == p2.valid && gaia::AreEmailsSame(p1.email, p2.email); |
| 37 } | 37 } |
| 38 | 38 |
| 39 class AreEmailsSameFunc : public std::equal_to<std::string> { | 39 class AreEmailsSameFunc : public std::equal_to<std::string> { |
| 40 public: | 40 public: |
| 41 bool operator()(const std::string& p1, | 41 bool operator()(const std::string& p1, |
| 42 const std::string& p2) const; | 42 const std::string& p2) const; |
| 43 }; | 43 }; |
| 44 | 44 |
| 45 bool AreEmailsSameFunc::operator()( | 45 bool AreEmailsSameFunc::operator()( |
| 46 const std::string& p1, | 46 const std::string& p1, |
| 47 const std::string& p2) const { | 47 const std::string& p2) const { |
| 48 return gaia::AreEmailsSame(p1, p2); | 48 return gaia::AreEmailsSame(p1, p2); |
| 49 } | 49 } |
| 50 | 50 |
| 51 gaia::ListedAccount AccountFromEmail(const std::string& email) { |
| 52 gaia::ListedAccount account; |
| 53 account.email = email; |
| 54 account.gaia_id = std::string(); |
| 55 account.valid = true; |
| 56 return account; |
| 57 } |
| 58 |
| 51 } // namespace | 59 } // namespace |
| 52 | 60 |
| 53 | 61 |
| 54 AccountReconcilor::AccountReconcilor( | 62 AccountReconcilor::AccountReconcilor( |
| 55 ProfileOAuth2TokenService* token_service, | 63 ProfileOAuth2TokenService* token_service, |
| 56 SigninManagerBase* signin_manager, | 64 SigninManagerBase* signin_manager, |
| 57 SigninClient* client, | 65 SigninClient* client, |
| 58 GaiaCookieManagerService* cookie_manager_service) | 66 GaiaCookieManagerService* cookie_manager_service) |
| 59 : token_service_(token_service), | 67 : token_service_(token_service), |
| 60 signin_manager_(signin_manager), | 68 signin_manager_(signin_manager), |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 ValidateAccountsFromTokenService(); | 282 ValidateAccountsFromTokenService(); |
| 275 | 283 |
| 276 // Rely on the GCMS to manage calls to and responses from ListAccounts. | 284 // Rely on the GCMS to manage calls to and responses from ListAccounts. |
| 277 if (cookie_manager_service_->ListAccounts(&gaia_accounts_)) { | 285 if (cookie_manager_service_->ListAccounts(&gaia_accounts_)) { |
| 278 OnGaiaAccountsInCookieUpdated( | 286 OnGaiaAccountsInCookieUpdated( |
| 279 gaia_accounts_, GoogleServiceAuthError(GoogleServiceAuthError::NONE)); | 287 gaia_accounts_, GoogleServiceAuthError(GoogleServiceAuthError::NONE)); |
| 280 } | 288 } |
| 281 } | 289 } |
| 282 | 290 |
| 283 void AccountReconcilor::OnGaiaAccountsInCookieUpdated( | 291 void AccountReconcilor::OnGaiaAccountsInCookieUpdated( |
| 284 const std::vector<std::pair<std::string, bool> >& accounts, | 292 const std::vector<gaia::ListedAccount>& accounts, |
| 285 const GoogleServiceAuthError& error) { | 293 const GoogleServiceAuthError& error) { |
| 286 VLOG(1) << "AccountReconcilor::OnGaiaAccountsInCookieUpdated: " | 294 VLOG(1) << "AccountReconcilor::OnGaiaAccountsInCookieUpdated: " |
| 287 << "CookieJar " << accounts.size() << " accounts, " | 295 << "CookieJar " << accounts.size() << " accounts, " |
| 288 << "Reconcilor's state is " << is_reconcile_started_ << ", " | 296 << "Reconcilor's state is " << is_reconcile_started_ << ", " |
| 289 << "Error was " << error.ToString(); | 297 << "Error was " << error.ToString(); |
| 290 if (error.state() == GoogleServiceAuthError::NONE) { | 298 if (error.state() == GoogleServiceAuthError::NONE) { |
| 291 gaia_accounts_ = accounts; | 299 gaia_accounts_ = accounts; |
| 292 | 300 |
| 293 // It is possible that O2RT is not available at this moment. | 301 // It is possible that O2RT is not available at this moment. |
| 294 if (token_service_->GetAccounts().empty()) | 302 if (token_service_->GetAccounts().empty()) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 324 } else { | 332 } else { |
| 325 Shutdown(); | 333 Shutdown(); |
| 326 } | 334 } |
| 327 } | 335 } |
| 328 | 336 |
| 329 void AccountReconcilor::FinishReconcile() { | 337 void AccountReconcilor::FinishReconcile() { |
| 330 VLOG(1) << "AccountReconcilor::FinishReconcile"; | 338 VLOG(1) << "AccountReconcilor::FinishReconcile"; |
| 331 DCHECK(add_to_cookie_.empty()); | 339 DCHECK(add_to_cookie_.empty()); |
| 332 int number_gaia_accounts = gaia_accounts_.size(); | 340 int number_gaia_accounts = gaia_accounts_.size(); |
| 333 bool are_primaries_equal = number_gaia_accounts > 0 && | 341 bool are_primaries_equal = number_gaia_accounts > 0 && |
| 334 gaia::AreEmailsSame(primary_account_, gaia_accounts_[0].first); | 342 gaia::AreEmailsSame(primary_account_, gaia_accounts_[0].email); |
| 335 | 343 |
| 336 // If there are any accounts in the gaia cookie but not in chrome, then | 344 // If there are any accounts in the gaia cookie but not in chrome, then |
| 337 // those accounts need to be removed from the cookie. This means we need | 345 // those accounts need to be removed from the cookie. This means we need |
| 338 // to blow the cookie away. | 346 // to blow the cookie away. |
| 339 int removed_from_cookie = 0; | 347 int removed_from_cookie = 0; |
| 340 for (size_t i = 0; i < gaia_accounts_.size(); ++i) { | 348 for (size_t i = 0; i < gaia_accounts_.size(); ++i) { |
| 341 const std::string& gaia_account = gaia_accounts_[i].first; | 349 const std::string& gaia_account = gaia_accounts_[i].email; |
| 342 if (gaia_accounts_[i].second && | 350 if (gaia_accounts_[i].valid && |
| 343 chrome_accounts_.end() == | 351 chrome_accounts_.end() == |
| 344 std::find_if(chrome_accounts_.begin(), | 352 std::find_if(chrome_accounts_.begin(), |
| 345 chrome_accounts_.end(), | 353 chrome_accounts_.end(), |
| 346 std::bind1st(AreEmailsSameFunc(), gaia_account))) { | 354 std::bind1st(AreEmailsSameFunc(), gaia_account))) { |
| 347 ++removed_from_cookie; | 355 ++removed_from_cookie; |
| 348 } | 356 } |
| 349 } | 357 } |
| 350 | 358 |
| 351 bool rebuild_cookie = !are_primaries_equal || removed_from_cookie > 0; | 359 bool rebuild_cookie = !are_primaries_equal || removed_from_cookie > 0; |
| 352 std::vector<std::pair<std::string, bool> > original_gaia_accounts = | 360 std::vector<gaia::ListedAccount> original_gaia_accounts = |
| 353 gaia_accounts_; | 361 gaia_accounts_; |
| 354 if (rebuild_cookie) { | 362 if (rebuild_cookie) { |
| 355 VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie"; | 363 VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie"; |
| 356 // Really messed up state. Blow away the gaia cookie completely and | 364 // Really messed up state. Blow away the gaia cookie completely and |
| 357 // rebuild it, making sure the primary account as specified by the | 365 // rebuild it, making sure the primary account as specified by the |
| 358 // SigninManager is the first session in the gaia cookie. | 366 // SigninManager is the first session in the gaia cookie. |
| 359 PerformLogoutAllAccountsAction(); | 367 PerformLogoutAllAccountsAction(); |
| 360 gaia_accounts_.clear(); | 368 gaia_accounts_.clear(); |
| 361 } | 369 } |
| 362 | 370 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 373 // not already in the cookie jar or its state is invalid, or signal merge | 381 // not already in the cookie jar or its state is invalid, or signal merge |
| 374 // completed otherwise. Make a copy of |add_to_cookie_| since calls to | 382 // completed otherwise. Make a copy of |add_to_cookie_| since calls to |
| 375 // SignalComplete() will change the array. | 383 // SignalComplete() will change the array. |
| 376 std::vector<std::string> add_to_cookie_copy = add_to_cookie_; | 384 std::vector<std::string> add_to_cookie_copy = add_to_cookie_; |
| 377 int added_to_cookie = 0; | 385 int added_to_cookie = 0; |
| 378 for (size_t i = 0; i < add_to_cookie_copy.size(); ++i) { | 386 for (size_t i = 0; i < add_to_cookie_copy.size(); ++i) { |
| 379 if (gaia_accounts_.end() != | 387 if (gaia_accounts_.end() != |
| 380 std::find_if(gaia_accounts_.begin(), | 388 std::find_if(gaia_accounts_.begin(), |
| 381 gaia_accounts_.end(), | 389 gaia_accounts_.end(), |
| 382 std::bind1st(EmailEqualToFunc(), | 390 std::bind1st(EmailEqualToFunc(), |
| 383 std::make_pair(add_to_cookie_copy[i], | 391 AccountFromEmail(add_to_cookie_copy[i] |
| 384 true)))) { | 392 )))) { |
| 385 cookie_manager_service_->SignalComplete( | 393 cookie_manager_service_->SignalComplete( |
| 386 add_to_cookie_copy[i], | 394 add_to_cookie_copy[i], |
| 387 GoogleServiceAuthError::AuthErrorNone()); | 395 GoogleServiceAuthError::AuthErrorNone()); |
| 388 } else { | 396 } else { |
| 389 PerformMergeAction(add_to_cookie_copy[i]); | 397 PerformMergeAction(add_to_cookie_copy[i]); |
| 390 if (original_gaia_accounts.end() == | 398 if (original_gaia_accounts.end() == |
| 391 std::find_if(original_gaia_accounts.begin(), | 399 std::find_if(original_gaia_accounts.begin(), |
| 392 original_gaia_accounts.end(), | 400 original_gaia_accounts.end(), |
| 393 std::bind1st(EmailEqualToFunc(), | 401 std::bind1st(EmailEqualToFunc(), |
| 394 std::make_pair(add_to_cookie_copy[i], | 402 AccountFromEmail(add_to_cookie_copy[i] |
| 395 true)))) { | 403 )))) { |
| 396 added_to_cookie++; | 404 added_to_cookie++; |
| 397 } | 405 } |
| 398 } | 406 } |
| 399 } | 407 } |
| 400 | 408 |
| 401 signin_metrics::LogSigninAccountReconciliation(chrome_accounts_.size(), | 409 signin_metrics::LogSigninAccountReconciliation(chrome_accounts_.size(), |
| 402 added_to_cookie, | 410 added_to_cookie, |
| 403 removed_from_cookie, | 411 removed_from_cookie, |
| 404 are_primaries_equal, | 412 are_primaries_equal, |
| 405 first_execution_, | 413 first_execution_, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 << "Account added: " << account_id << ", " | 464 << "Account added: " << account_id << ", " |
| 457 << "Error was " << error.ToString(); | 465 << "Error was " << error.ToString(); |
| 458 // Always listens to GaiaCookieManagerService. Only proceed if reconciling. | 466 // Always listens to GaiaCookieManagerService. Only proceed if reconciling. |
| 459 if (is_reconcile_started_ && MarkAccountAsAddedToCookie(account_id)) { | 467 if (is_reconcile_started_ && MarkAccountAsAddedToCookie(account_id)) { |
| 460 if (error.state() != GoogleServiceAuthError::State::NONE) | 468 if (error.state() != GoogleServiceAuthError::State::NONE) |
| 461 error_during_last_reconcile_ = true; | 469 error_during_last_reconcile_ = true; |
| 462 CalculateIfReconcileIsDone(); | 470 CalculateIfReconcileIsDone(); |
| 463 ScheduleStartReconcileIfChromeAccountsChanged(); | 471 ScheduleStartReconcileIfChromeAccountsChanged(); |
| 464 } | 472 } |
| 465 } | 473 } |
| OLD | NEW |