OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/sync/profile_sync_service.h" | 5 #include "chrome/browser/sync/profile_sync_service.h" |
6 | 6 |
7 #include <cstddef> | 7 #include <cstddef> |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <utility> | 10 #include <utility> |
(...skipping 30 matching lines...) Expand all Loading... | |
41 #include "chrome/browser/sync/js/js_event_details.h" | 41 #include "chrome/browser/sync/js/js_event_details.h" |
42 #include "chrome/browser/sync/profile_sync_components_factory_impl.h" | 42 #include "chrome/browser/sync/profile_sync_components_factory_impl.h" |
43 #include "chrome/browser/sync/sync_global_error.h" | 43 #include "chrome/browser/sync/sync_global_error.h" |
44 #include "chrome/browser/sync/util/cryptographer.h" | 44 #include "chrome/browser/sync/util/cryptographer.h" |
45 #include "chrome/browser/sync/util/oauth.h" | 45 #include "chrome/browser/sync/util/oauth.h" |
46 #include "chrome/browser/ui/browser.h" | 46 #include "chrome/browser/ui/browser.h" |
47 #include "chrome/browser/ui/browser_list.h" | 47 #include "chrome/browser/ui/browser_list.h" |
48 #include "chrome/browser/ui/browser_window.h" | 48 #include "chrome/browser/ui/browser_window.h" |
49 #include "chrome/browser/ui/global_error_service.h" | 49 #include "chrome/browser/ui/global_error_service.h" |
50 #include "chrome/browser/ui/global_error_service_factory.h" | 50 #include "chrome/browser/ui/global_error_service_factory.h" |
51 #include "chrome/browser/ui/webui/signin/login_ui_service.h" | |
52 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" | |
51 #include "chrome/common/chrome_notification_types.h" | 53 #include "chrome/common/chrome_notification_types.h" |
52 #include "chrome/common/chrome_switches.h" | 54 #include "chrome/common/chrome_switches.h" |
53 #include "chrome/common/chrome_version_info.h" | 55 #include "chrome/common/chrome_version_info.h" |
54 #include "chrome/common/net/gaia/gaia_constants.h" | 56 #include "chrome/common/net/gaia/gaia_constants.h" |
55 #include "chrome/common/time_format.h" | 57 #include "chrome/common/time_format.h" |
56 #include "chrome/common/url_constants.h" | 58 #include "chrome/common/url_constants.h" |
57 #include "content/public/browser/notification_details.h" | 59 #include "content/public/browser/notification_details.h" |
58 #include "content/public/browser/notification_source.h" | 60 #include "content/public/browser/notification_source.h" |
59 #include "grit/generated_resources.h" | 61 #include "grit/generated_resources.h" |
60 #include "net/base/cookie_monster.h" | 62 #include "net/base/cookie_monster.h" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 bool ProfileSyncService::AreCredentialsAvailable() { | 152 bool ProfileSyncService::AreCredentialsAvailable() { |
151 return AreCredentialsAvailable(false); | 153 return AreCredentialsAvailable(false); |
152 } | 154 } |
153 | 155 |
154 bool ProfileSyncService::AreCredentialsAvailable( | 156 bool ProfileSyncService::AreCredentialsAvailable( |
155 bool check_oauth_login_token) { | 157 bool check_oauth_login_token) { |
156 if (IsManaged()) { | 158 if (IsManaged()) { |
157 return false; | 159 return false; |
158 } | 160 } |
159 | 161 |
162 // If we have start suppressed, then basically just act like we have no | |
163 // credentials (login is required to fix this, since we need the user's | |
164 // passphrase to encrypt/decrypt anyway). | |
165 // TODO(sync): Revisit this when we move to a server-based keystore. | |
166 if (sync_prefs_.IsStartSuppressed()) | |
167 return false; | |
168 | |
160 // CrOS user is always logged in. Chrome uses signin_ to check logged in. | 169 // CrOS user is always logged in. Chrome uses signin_ to check logged in. |
161 if (signin_->GetAuthenticatedUsername().empty()) | 170 if (signin_->GetAuthenticatedUsername().empty()) |
162 return false; | 171 return false; |
163 | 172 |
164 TokenService* token_service = profile()->GetTokenService(); | 173 TokenService* token_service = profile()->GetTokenService(); |
165 if (!token_service) | 174 if (!token_service) |
166 return false; | 175 return false; |
167 | 176 |
168 // TODO(chron): Verify CrOS unit test behavior. | 177 // TODO(chron): Verify CrOS unit test behavior. |
169 if (!token_service->HasTokenForService(browser_sync::SyncServiceName())) | 178 if (!token_service->HasTokenForService(browser_sync::SyncServiceName())) |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
711 if (!to_register.Empty() && HasSyncSetupCompleted() && migrator_.get()) { | 720 if (!to_register.Empty() && HasSyncSetupCompleted() && migrator_.get()) { |
712 DVLOG(1) << "Dynamically enabling new datatypes: " | 721 DVLOG(1) << "Dynamically enabling new datatypes: " |
713 << syncable::ModelTypeSetToString(to_register); | 722 << syncable::ModelTypeSetToString(to_register); |
714 OnMigrationNeededForTypes(to_register); | 723 OnMigrationNeededForTypes(to_register); |
715 } | 724 } |
716 } | 725 } |
717 } | 726 } |
718 | 727 |
719 void ProfileSyncService::UpdateAuthErrorState( | 728 void ProfileSyncService::UpdateAuthErrorState( |
720 const GoogleServiceAuthError& error) { | 729 const GoogleServiceAuthError& error) { |
730 is_auth_in_progress_ = false; | |
721 last_auth_error_ = error; | 731 last_auth_error_ = error; |
722 // Protect against the in-your-face dialogs that pop out of nowhere. | |
723 // Require the user to click somewhere to run the setup wizard in the case | |
724 // of a steady-state auth failure. | |
725 if (WizardIsVisible()) { | |
726 wizard_.Step(last_auth_error_.state() == AuthError::NONE ? | |
727 SyncSetupWizard::GAIA_SUCCESS : SyncSetupWizard::GetLoginState()); | |
728 } else { | |
729 auth_error_time_ = base::TimeTicks::Now(); | |
730 } | |
731 | 732 |
732 if (!auth_start_time_.is_null()) { | 733 if (WizardIsVisible() && last_auth_error_.state() != AuthError::NONE) { |
733 UMA_HISTOGRAM_TIMES("Sync.AuthorizationTimeInNetwork", | 734 // Got some kind of auth error while the wizard is visible. Exit out of |
tim (not reviewing)
2012/02/14 02:11:21
err... why is this fatal? what happens to any com
Andrew T Wilson (Slow)
2012/02/14 05:23:52
Remember that this is dealing with a GAIA error *a
| |
734 base::TimeTicks::Now() - auth_start_time_); | 735 // the config flow (UI handler can notify the user or bring up the signin |
735 auth_start_time_ = base::TimeTicks(); | 736 // flow as appropriate). |
737 wizard_.Step(SyncSetupWizard::FATAL_ERROR); | |
736 } | 738 } |
737 | 739 |
738 // Fan the notification out to interested UI-thread components. | 740 // Fan the notification out to interested UI-thread components. |
739 NotifyObservers(); | 741 NotifyObservers(); |
740 } | 742 } |
741 | 743 |
742 void ProfileSyncService::OnAuthError() { | 744 void ProfileSyncService::OnAuthError() { |
743 UpdateAuthErrorState(backend_->GetAuthError()); | 745 UpdateAuthErrorState(backend_->GetAuthError()); |
744 } | 746 } |
745 | 747 |
746 void ProfileSyncService::OnStopSyncingPermanently() { | 748 void ProfileSyncService::OnStopSyncingPermanently() { |
749 UpdateAuthErrorState( | |
750 GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE)); | |
751 | |
747 if (SetupInProgress()) { | 752 if (SetupInProgress()) { |
Andrew T Wilson (Slow)
2012/02/14 05:23:52
BTW, I'm changing this to abort whenever the wizar
| |
748 wizard_.Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR); | 753 wizard_.Step(SyncSetupWizard::ABORT); |
749 expect_sync_configuration_aborted_ = true; | 754 expect_sync_configuration_aborted_ = true; |
750 } | 755 } |
751 sync_prefs_.SetStartSuppressed(true); | 756 sync_prefs_.SetStartSuppressed(true); |
752 DisableForUser(); | 757 DisableForUser(); |
753 } | 758 } |
754 | 759 |
755 void ProfileSyncService::OnClearServerDataTimeout() { | 760 void ProfileSyncService::OnClearServerDataTimeout() { |
756 if (clear_server_data_state_ != CLEAR_SUCCEEDED && | 761 if (clear_server_data_state_ != CLEAR_SUCCEEDED && |
757 clear_server_data_state_ != CLEAR_FAILED) { | 762 clear_server_data_state_ != CLEAR_FAILED) { |
758 clear_server_data_state_ = CLEAR_FAILED; | 763 clear_server_data_state_ = CLEAR_FAILED; |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
938 case browser_sync::DISABLE_SYNC_ON_CLIENT: | 943 case browser_sync::DISABLE_SYNC_ON_CLIENT: |
939 OnStopSyncingPermanently(); | 944 OnStopSyncingPermanently(); |
940 break; | 945 break; |
941 default: | 946 default: |
942 NOTREACHED(); | 947 NOTREACHED(); |
943 } | 948 } |
944 NotifyObservers(); | 949 NotifyObservers(); |
945 } | 950 } |
946 | 951 |
947 void ProfileSyncService::ShowLoginDialog() { | 952 void ProfileSyncService::ShowLoginDialog() { |
948 if (WizardIsVisible()) { | 953 // TODO(atwilson): Remove this API and have the callers directly call |
949 wizard_.Focus(); | 954 // LoginUIService. |
950 // Force the wizard to step to the login screen (which will only actually | 955 LoginUIServiceFactory::GetForProfile(profile_)->ShowLoginUI(); |
951 // happen if the transition is valid). | |
952 wizard_.Step(SyncSetupWizard::GetLoginState()); | |
953 return; | |
954 } | |
955 | |
956 if (!auth_error_time_.is_null()) { | |
957 UMA_HISTOGRAM_LONG_TIMES("Sync.ReauthorizationTime", | |
958 base::TimeTicks::Now() - auth_error_time_); | |
959 auth_error_time_ = base::TimeTicks(); // Reset auth_error_time_ to null. | |
960 } | |
961 | |
962 ShowSyncSetupWithWizard(SyncSetupWizard::GetLoginState()); | |
963 | |
964 NotifyObservers(); | |
965 } | 956 } |
966 | 957 |
967 void ProfileSyncService::ShowErrorUI() { | 958 void ProfileSyncService::ShowErrorUI() { |
968 if (WizardIsVisible()) { | 959 if (WizardIsVisible()) { |
969 wizard_.Focus(); | 960 wizard_.Focus(); |
970 return; | 961 return; |
971 } | 962 } |
972 | 963 |
973 if (last_auth_error_.state() != AuthError::NONE) | 964 // Figure out what kind of error we've encountered. There are only 3 kinds: |
965 // 1) auth error. | |
966 // 2) server-initiated error | |
967 // 3) passphrase error | |
968 // Any other errors (such as unrecoverable error) should be handled by the UI | |
969 // itself and should not result in a call to ShowErrorUI. | |
tim (not reviewing)
2012/02/14 02:11:21
hm. so what about a failure to initialize / load t
Andrew T Wilson (Slow)
2012/02/14 05:23:52
This change just makes explicit what was previousl
| |
970 if (last_auth_error_.state() != AuthError::NONE) { | |
974 ShowLoginDialog(); | 971 ShowLoginDialog(); |
975 else if (ShouldShowActionOnUI(last_actionable_error_)) | 972 } else if (ShouldShowActionOnUI(last_actionable_error_)) { |
976 ShowSyncSetup(chrome::kPersonalOptionsSubPage); | 973 ShowSyncSetup(chrome::kPersonalOptionsSubPage); |
977 else | 974 } else { |
978 ShowSyncSetupWithWizard(SyncSetupWizard::NONFATAL_ERROR); | 975 // We should only get here for passphrase error. |
976 DCHECK(IsPassphraseRequired()); | |
977 ShowSyncSetupWithWizard(SyncSetupWizard::ENTER_PASSPHRASE); | |
978 } | |
979 } | 979 } |
980 | 980 |
981 void ProfileSyncService::ShowConfigure(bool sync_everything) { | 981 void ProfileSyncService::ShowConfigure(bool sync_everything) { |
982 if (!sync_initialized()) { | 982 if (!sync_initialized()) { |
983 LOG(ERROR) << "Attempted to show sync configure before backend ready."; | 983 LOG(ERROR) << "Attempted to show sync configure before backend ready."; |
984 return; | 984 return; |
985 } | 985 } |
986 if (WizardIsVisible()) { | 986 if (WizardIsVisible()) { |
987 wizard_.Focus(); | 987 wizard_.Focus(); |
988 return; | 988 return; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1054 | 1054 |
1055 bool ProfileSyncService::sync_initialized() const { | 1055 bool ProfileSyncService::sync_initialized() const { |
1056 return backend_initialized_; | 1056 return backend_initialized_; |
1057 } | 1057 } |
1058 | 1058 |
1059 bool ProfileSyncService::unrecoverable_error_detected() const { | 1059 bool ProfileSyncService::unrecoverable_error_detected() const { |
1060 return unrecoverable_error_detected_; | 1060 return unrecoverable_error_detected_; |
1061 } | 1061 } |
1062 | 1062 |
1063 bool ProfileSyncService::UIShouldDepictAuthInProgress() const { | 1063 bool ProfileSyncService::UIShouldDepictAuthInProgress() const { |
1064 return is_auth_in_progress_; | 1064 return signin()->AuthInProgress(); |
1065 } | |
1066 | |
1067 void ProfileSyncService::SetUIShouldDepictAuthInProgress( | |
1068 bool auth_in_progress) { | |
1069 is_auth_in_progress_ = auth_in_progress; | |
1070 // TODO(atwilson): Figure out if we still need to track this or if we should | |
1071 // move this up to the UI (or break it out into two stats that track GAIA | |
1072 // auth and sync auth separately). | |
1073 if (is_auth_in_progress_) | |
1074 auth_start_time_ = base::TimeTicks::Now(); | |
1075 NotifyObservers(); | |
1076 } | 1065 } |
1077 | 1066 |
1078 bool ProfileSyncService::IsPassphraseRequired() const { | 1067 bool ProfileSyncService::IsPassphraseRequired() const { |
1079 return passphrase_required_reason_ != | 1068 return passphrase_required_reason_ != |
1080 sync_api::REASON_PASSPHRASE_NOT_REQUIRED; | 1069 sync_api::REASON_PASSPHRASE_NOT_REQUIRED; |
1081 } | 1070 } |
1082 | 1071 |
1083 // TODO(zea): Rename this IsPassphraseNeededFromUI and ensure it's used | 1072 // TODO(zea): Rename this IsPassphraseNeededFromUI and ensure it's used |
1084 // appropriately (see http://crbug.com/91379). | 1073 // appropriately (see http://crbug.com/91379). |
1085 bool ProfileSyncService::IsPassphraseRequiredForDecryption() const { | 1074 bool ProfileSyncService::IsPassphraseRequiredForDecryption() const { |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1442 *(content::Details<const GoogleServiceAuthError>(details).ptr()); | 1431 *(content::Details<const GoogleServiceAuthError>(details).ptr()); |
1443 UpdateAuthErrorState(error); | 1432 UpdateAuthErrorState(error); |
1444 break; | 1433 break; |
1445 } | 1434 } |
1446 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { | 1435 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { |
1447 const GoogleServiceSigninSuccessDetails* successful = | 1436 const GoogleServiceSigninSuccessDetails* successful = |
1448 content::Details<const GoogleServiceSigninSuccessDetails>( | 1437 content::Details<const GoogleServiceSigninSuccessDetails>( |
1449 details).ptr(); | 1438 details).ptr(); |
1450 // The user has submitted credentials, which indicates they don't | 1439 // The user has submitted credentials, which indicates they don't |
1451 // want to suppress start up anymore. | 1440 // want to suppress start up anymore. |
1441 // TODO(sync): Remove this when sync is no longer tied to browser signin. | |
tim (not reviewing)
2012/02/14 02:11:21
should tie this to a bug (and mention in the bug t
Andrew T Wilson (Slow)
2012/02/14 05:23:52
Done.
| |
1452 sync_prefs_.SetStartSuppressed(false); | 1442 sync_prefs_.SetStartSuppressed(false); |
1453 | 1443 |
1454 // Because we specify IMPLICIT to SetPassphrase, we know it won't override | 1444 // Because we specify IMPLICIT to SetPassphrase, we know it won't override |
1455 // an explicit one. Thus, we either update the implicit passphrase | 1445 // an explicit one. Thus, we either update the implicit passphrase |
1456 // (idempotent if the passphrase didn't actually change), or the user has | 1446 // (idempotent if the passphrase didn't actually change), or the user has |
1457 // an explicit passphrase set so this becomes a no-op. | 1447 // an explicit passphrase set so this becomes a no-op. |
1458 if (!successful->password.empty()) | 1448 if (!successful->password.empty()) |
1459 SetPassphrase(successful->password, IMPLICIT, INTERNAL); | 1449 SetPassphrase(successful->password, IMPLICIT, INTERNAL); |
1450 | |
1451 if (!sync_initialized() || | |
tim (not reviewing)
2012/02/14 02:11:21
Hm, so there's no way we can call UpdateAuthErrorS
Andrew T Wilson (Slow)
2012/02/14 05:23:52
We aren't actually changing the state - all we're
| |
1452 GetAuthError().state() != GoogleServiceAuthError::NONE) { | |
1453 // Track the fact that we're still waiting for auth to complete. | |
1454 is_auth_in_progress_ = true; | |
1455 } | |
1460 break; | 1456 break; |
1461 } | 1457 } |
1462 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { | 1458 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { |
1463 const TokenService::TokenRequestFailedDetails& token_details = | 1459 const TokenService::TokenRequestFailedDetails& token_details = |
1464 *(content::Details<const TokenService::TokenRequestFailedDetails>( | 1460 *(content::Details<const TokenService::TokenRequestFailedDetails>( |
1465 details).ptr()); | 1461 details).ptr()); |
1466 if (IsTokenServiceRelevant(token_details.service())) { | 1462 if (IsTokenServiceRelevant(token_details.service())) { |
1467 GoogleServiceAuthError error( | 1463 GoogleServiceAuthError error( |
1468 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | 1464 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); |
1469 UpdateAuthErrorState(error); | 1465 UpdateAuthErrorState(error); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1611 << "Unrecoverable error."; | 1607 << "Unrecoverable error."; |
1612 } else { | 1608 } else { |
1613 DVLOG(0) << "ConfigureDataTypeManager not invoked because backend is not " | 1609 DVLOG(0) << "ConfigureDataTypeManager not invoked because backend is not " |
1614 << "initialized"; | 1610 << "initialized"; |
1615 } | 1611 } |
1616 } | 1612 } |
1617 | 1613 |
1618 const FailedDatatypesHandler& ProfileSyncService::failed_datatypes_handler() { | 1614 const FailedDatatypesHandler& ProfileSyncService::failed_datatypes_handler() { |
1619 return failed_datatypes_handler_; | 1615 return failed_datatypes_handler_; |
1620 } | 1616 } |
OLD | NEW |