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