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 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 if (!to_register.Empty() && HasSyncSetupCompleted() && migrator_.get()) { | 715 if (!to_register.Empty() && HasSyncSetupCompleted() && migrator_.get()) { |
707 DVLOG(1) << "Dynamically enabling new datatypes: " | 716 DVLOG(1) << "Dynamically enabling new datatypes: " |
708 << syncable::ModelTypeSetToString(to_register); | 717 << syncable::ModelTypeSetToString(to_register); |
709 OnMigrationNeededForTypes(to_register); | 718 OnMigrationNeededForTypes(to_register); |
710 } | 719 } |
711 } | 720 } |
712 } | 721 } |
713 | 722 |
714 void ProfileSyncService::UpdateAuthErrorState( | 723 void ProfileSyncService::UpdateAuthErrorState( |
715 const GoogleServiceAuthError& error) { | 724 const GoogleServiceAuthError& error) { |
| 725 is_auth_in_progress_ = false; |
716 last_auth_error_ = error; | 726 last_auth_error_ = error; |
717 // Protect against the in-your-face dialogs that pop out of nowhere. | |
718 // Require the user to click somewhere to run the setup wizard in the case | |
719 // of a steady-state auth failure. | |
720 if (WizardIsVisible()) { | |
721 wizard_.Step(last_auth_error_.state() == AuthError::NONE ? | |
722 SyncSetupWizard::GAIA_SUCCESS : SyncSetupWizard::GetLoginState()); | |
723 } else { | |
724 auth_error_time_ = base::TimeTicks::Now(); | |
725 } | |
726 | |
727 if (!auth_start_time_.is_null()) { | |
728 UMA_HISTOGRAM_TIMES("Sync.AuthorizationTimeInNetwork", | |
729 base::TimeTicks::Now() - auth_start_time_); | |
730 auth_start_time_ = base::TimeTicks(); | |
731 } | |
732 | 727 |
733 // Fan the notification out to interested UI-thread components. | 728 // Fan the notification out to interested UI-thread components. |
734 NotifyObservers(); | 729 NotifyObservers(); |
735 } | 730 } |
736 | 731 |
737 void ProfileSyncService::OnAuthError() { | 732 void ProfileSyncService::OnAuthError() { |
738 UpdateAuthErrorState(backend_->GetAuthError()); | 733 UpdateAuthErrorState(backend_->GetAuthError()); |
739 } | 734 } |
740 | 735 |
741 void ProfileSyncService::OnStopSyncingPermanently() { | 736 void ProfileSyncService::OnStopSyncingPermanently() { |
742 if (SetupInProgress()) { | 737 UpdateAuthErrorState( |
743 wizard_.Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR); | 738 GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE)); |
| 739 |
| 740 // If the wizard is visible, close it. |
| 741 if (WizardIsVisible()) { |
| 742 wizard_.Step(SyncSetupWizard::ABORT); |
744 expect_sync_configuration_aborted_ = true; | 743 expect_sync_configuration_aborted_ = true; |
745 } | 744 } |
746 sync_prefs_.SetStartSuppressed(true); | 745 sync_prefs_.SetStartSuppressed(true); |
747 DisableForUser(); | 746 DisableForUser(); |
748 } | 747 } |
749 | 748 |
750 void ProfileSyncService::OnClearServerDataTimeout() { | 749 void ProfileSyncService::OnClearServerDataTimeout() { |
751 if (clear_server_data_state_ != CLEAR_SUCCEEDED && | 750 if (clear_server_data_state_ != CLEAR_SUCCEEDED && |
752 clear_server_data_state_ != CLEAR_FAILED) { | 751 clear_server_data_state_ != CLEAR_FAILED) { |
753 clear_server_data_state_ = CLEAR_FAILED; | 752 clear_server_data_state_ = CLEAR_FAILED; |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 case browser_sync::DISABLE_SYNC_ON_CLIENT: | 932 case browser_sync::DISABLE_SYNC_ON_CLIENT: |
934 OnStopSyncingPermanently(); | 933 OnStopSyncingPermanently(); |
935 break; | 934 break; |
936 default: | 935 default: |
937 NOTREACHED(); | 936 NOTREACHED(); |
938 } | 937 } |
939 NotifyObservers(); | 938 NotifyObservers(); |
940 } | 939 } |
941 | 940 |
942 void ProfileSyncService::ShowLoginDialog() { | 941 void ProfileSyncService::ShowLoginDialog() { |
943 if (WizardIsVisible()) { | 942 // TODO(atwilson): Remove this API and have the callers directly call |
944 wizard_.Focus(); | 943 // LoginUIService. |
945 // Force the wizard to step to the login screen (which will only actually | 944 LoginUIServiceFactory::GetForProfile(profile_)->ShowLoginUI(); |
946 // happen if the transition is valid). | |
947 wizard_.Step(SyncSetupWizard::GetLoginState()); | |
948 return; | |
949 } | |
950 | |
951 if (!auth_error_time_.is_null()) { | |
952 UMA_HISTOGRAM_LONG_TIMES("Sync.ReauthorizationTime", | |
953 base::TimeTicks::Now() - auth_error_time_); | |
954 auth_error_time_ = base::TimeTicks(); // Reset auth_error_time_ to null. | |
955 } | |
956 | |
957 ShowSyncSetupWithWizard(SyncSetupWizard::GetLoginState()); | |
958 | |
959 NotifyObservers(); | |
960 } | 945 } |
961 | 946 |
962 void ProfileSyncService::ShowErrorUI() { | 947 void ProfileSyncService::ShowErrorUI() { |
963 if (WizardIsVisible()) { | 948 if (WizardIsVisible()) { |
964 wizard_.Focus(); | 949 wizard_.Focus(); |
965 return; | 950 return; |
966 } | 951 } |
967 | 952 |
968 if (last_auth_error_.state() != AuthError::NONE) | 953 // Figure out what kind of error we've encountered. There are only 3 kinds: |
| 954 // 1) auth error. |
| 955 // 2) server-initiated error |
| 956 // 3) passphrase error |
| 957 // Any other errors (such as unrecoverable error) should be handled by the UI |
| 958 // itself and should not result in a call to ShowErrorUI. |
| 959 if (last_auth_error_.state() != AuthError::NONE) { |
969 ShowLoginDialog(); | 960 ShowLoginDialog(); |
970 else if (ShouldShowActionOnUI(last_actionable_error_)) | 961 } else if (ShouldShowActionOnUI(last_actionable_error_)) { |
971 ShowSyncSetup(chrome::kPersonalOptionsSubPage); | 962 ShowSyncSetup(chrome::kPersonalOptionsSubPage); |
972 else | 963 } else { |
973 ShowSyncSetupWithWizard(SyncSetupWizard::NONFATAL_ERROR); | 964 // We should only get here for passphrase error. |
| 965 DCHECK(IsPassphraseRequired()); |
| 966 ShowSyncSetupWithWizard(SyncSetupWizard::ENTER_PASSPHRASE); |
| 967 } |
974 } | 968 } |
975 | 969 |
976 void ProfileSyncService::ShowConfigure(bool sync_everything) { | 970 void ProfileSyncService::ShowConfigure(bool sync_everything) { |
977 if (!sync_initialized()) { | 971 if (!sync_initialized()) { |
978 LOG(ERROR) << "Attempted to show sync configure before backend ready."; | 972 LOG(ERROR) << "Attempted to show sync configure before backend ready."; |
979 return; | 973 return; |
980 } | 974 } |
981 if (WizardIsVisible()) { | 975 if (WizardIsVisible()) { |
982 wizard_.Focus(); | 976 wizard_.Focus(); |
983 return; | 977 return; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1049 | 1043 |
1050 bool ProfileSyncService::sync_initialized() const { | 1044 bool ProfileSyncService::sync_initialized() const { |
1051 return backend_initialized_; | 1045 return backend_initialized_; |
1052 } | 1046 } |
1053 | 1047 |
1054 bool ProfileSyncService::unrecoverable_error_detected() const { | 1048 bool ProfileSyncService::unrecoverable_error_detected() const { |
1055 return unrecoverable_error_detected_; | 1049 return unrecoverable_error_detected_; |
1056 } | 1050 } |
1057 | 1051 |
1058 bool ProfileSyncService::UIShouldDepictAuthInProgress() const { | 1052 bool ProfileSyncService::UIShouldDepictAuthInProgress() const { |
1059 return is_auth_in_progress_; | 1053 return signin()->AuthInProgress(); |
1060 } | |
1061 | |
1062 void ProfileSyncService::SetUIShouldDepictAuthInProgress( | |
1063 bool auth_in_progress) { | |
1064 is_auth_in_progress_ = auth_in_progress; | |
1065 // TODO(atwilson): Figure out if we still need to track this or if we should | |
1066 // move this up to the UI (or break it out into two stats that track GAIA | |
1067 // auth and sync auth separately). | |
1068 if (is_auth_in_progress_) | |
1069 auth_start_time_ = base::TimeTicks::Now(); | |
1070 NotifyObservers(); | |
1071 } | 1054 } |
1072 | 1055 |
1073 bool ProfileSyncService::IsPassphraseRequired() const { | 1056 bool ProfileSyncService::IsPassphraseRequired() const { |
1074 return passphrase_required_reason_ != | 1057 return passphrase_required_reason_ != |
1075 sync_api::REASON_PASSPHRASE_NOT_REQUIRED; | 1058 sync_api::REASON_PASSPHRASE_NOT_REQUIRED; |
1076 } | 1059 } |
1077 | 1060 |
1078 // TODO(zea): Rename this IsPassphraseNeededFromUI and ensure it's used | 1061 // TODO(zea): Rename this IsPassphraseNeededFromUI and ensure it's used |
1079 // appropriately (see http://crbug.com/91379). | 1062 // appropriately (see http://crbug.com/91379). |
1080 bool ProfileSyncService::IsPassphraseRequiredForDecryption() const { | 1063 bool ProfileSyncService::IsPassphraseRequiredForDecryption() const { |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1437 *(content::Details<const GoogleServiceAuthError>(details).ptr()); | 1420 *(content::Details<const GoogleServiceAuthError>(details).ptr()); |
1438 UpdateAuthErrorState(error); | 1421 UpdateAuthErrorState(error); |
1439 break; | 1422 break; |
1440 } | 1423 } |
1441 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { | 1424 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { |
1442 const GoogleServiceSigninSuccessDetails* successful = | 1425 const GoogleServiceSigninSuccessDetails* successful = |
1443 content::Details<const GoogleServiceSigninSuccessDetails>( | 1426 content::Details<const GoogleServiceSigninSuccessDetails>( |
1444 details).ptr(); | 1427 details).ptr(); |
1445 // The user has submitted credentials, which indicates they don't | 1428 // The user has submitted credentials, which indicates they don't |
1446 // want to suppress start up anymore. | 1429 // want to suppress start up anymore. |
| 1430 // TODO(sync): Remove this when sync is no longer tied to browser signin. |
| 1431 // http://crbug/com/95269. |
1447 sync_prefs_.SetStartSuppressed(false); | 1432 sync_prefs_.SetStartSuppressed(false); |
1448 | 1433 |
1449 // Because we specify IMPLICIT to SetPassphrase, we know it won't override | 1434 // Because we specify IMPLICIT to SetPassphrase, we know it won't override |
1450 // an explicit one. Thus, we either update the implicit passphrase | 1435 // an explicit one. Thus, we either update the implicit passphrase |
1451 // (idempotent if the passphrase didn't actually change), or the user has | 1436 // (idempotent if the passphrase didn't actually change), or the user has |
1452 // an explicit passphrase set so this becomes a no-op. | 1437 // an explicit passphrase set so this becomes a no-op. |
1453 if (!successful->password.empty()) | 1438 if (!successful->password.empty()) |
1454 SetPassphrase(successful->password, IMPLICIT, INTERNAL); | 1439 SetPassphrase(successful->password, IMPLICIT, INTERNAL); |
| 1440 |
| 1441 if (!sync_initialized() || |
| 1442 GetAuthError().state() != GoogleServiceAuthError::NONE) { |
| 1443 // Track the fact that we're still waiting for auth to complete. |
| 1444 is_auth_in_progress_ = true; |
| 1445 } |
1455 break; | 1446 break; |
1456 } | 1447 } |
1457 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { | 1448 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { |
1458 const TokenService::TokenRequestFailedDetails& token_details = | 1449 const TokenService::TokenRequestFailedDetails& token_details = |
1459 *(content::Details<const TokenService::TokenRequestFailedDetails>( | 1450 *(content::Details<const TokenService::TokenRequestFailedDetails>( |
1460 details).ptr()); | 1451 details).ptr()); |
1461 if (IsTokenServiceRelevant(token_details.service())) { | 1452 if (IsTokenServiceRelevant(token_details.service())) { |
1462 GoogleServiceAuthError error( | 1453 GoogleServiceAuthError error( |
1463 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | 1454 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); |
1464 UpdateAuthErrorState(error); | 1455 UpdateAuthErrorState(error); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1606 << "Unrecoverable error."; | 1597 << "Unrecoverable error."; |
1607 } else { | 1598 } else { |
1608 DVLOG(0) << "ConfigureDataTypeManager not invoked because backend is not " | 1599 DVLOG(0) << "ConfigureDataTypeManager not invoked because backend is not " |
1609 << "initialized"; | 1600 << "initialized"; |
1610 } | 1601 } |
1611 } | 1602 } |
1612 | 1603 |
1613 const FailedDatatypesHandler& ProfileSyncService::failed_datatypes_handler() { | 1604 const FailedDatatypesHandler& ProfileSyncService::failed_datatypes_handler() { |
1614 return failed_datatypes_handler_; | 1605 return failed_datatypes_handler_; |
1615 } | 1606 } |
OLD | NEW |