[email protected] | 0865c134 | 2011-01-28 20:29:37 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | d80033e | 2009-10-16 10:32:04 | [diff] [blame] | 5 | #include "chrome/browser/sync/sync_setup_flow.h" |
[email protected] | 8ac2dc11 | 2009-10-01 23:19:13 | [diff] [blame] | 6 | |
[email protected] | 2041cf34 | 2010-02-19 03:15:59 | [diff] [blame] | 7 | #include "base/callback.h" |
[email protected] | 23ec180 | 2011-05-24 17:40:31 | [diff] [blame] | 8 | #include "base/command_line.h" |
[email protected] | 93d49d7 | 2009-10-23 20:00:20 | [diff] [blame] | 9 | #include "base/json/json_reader.h" |
| 10 | #include "base/json/json_writer.h" |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 11 | #include "base/metrics/histogram.h" |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 12 | #include "base/string_util.h" |
[email protected] | d80033e | 2009-10-16 10:32:04 | [diff] [blame] | 13 | #include "base/utf_string_conversions.h" |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 14 | #include "base/values.h" |
[email protected] | 37858e5 | 2010-08-26 00:22:02 | [diff] [blame] | 15 | #include "chrome/browser/prefs/pref_service.h" |
[email protected] | 8ecad5e | 2010-12-02 21:18:33 | [diff] [blame] | 16 | #include "chrome/browser/profiles/profile.h" |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 17 | #include "chrome/browser/sync/profile_sync_service.h" |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 18 | #include "chrome/browser/sync/sync_setup_flow_handler.h" |
[email protected] | 80772ed | 2011-08-09 21:11:38 | [diff] [blame] | 19 | #include "chrome/browser/sync/syncable/model_type.h" |
[email protected] | 934a3079 | 2011-09-12 19:15:44 | [diff] [blame] | 20 | #include "chrome/browser/sync/util/oauth.h" |
[email protected] | 2ad4a90 | 2010-11-17 06:05:13 | [diff] [blame] | 21 | #include "chrome/browser/ui/browser_list.h" |
[email protected] | 23ec180 | 2011-05-24 17:40:31 | [diff] [blame] | 22 | #include "chrome/common/chrome_switches.h" |
[email protected] | 99074c5 | 2010-08-19 18:44:19 | [diff] [blame] | 23 | #include "chrome/common/net/gaia/google_service_auth_error.h" |
[email protected] | 24f8371 | 2009-10-08 22:52:45 | [diff] [blame] | 24 | #include "chrome/common/pref_names.h" |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 25 | #include "chrome/common/url_constants.h" |
[email protected] | d2912a2 | 2011-03-15 15:20:50 | [diff] [blame] | 26 | #include "grit/generated_resources.h" |
[email protected] | 9dd7e3d7 | 2011-01-20 18:27:06 | [diff] [blame] | 27 | |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 28 | namespace { |
| 29 | |
| 30 | // Helper function to disable password sync. |
| 31 | void DisablePasswordSync(ProfileSyncService* service) { |
| 32 | syncable::ModelTypeSet types; |
| 33 | service->GetPreferredDataTypes(&types); |
| 34 | types.erase(syncable::PASSWORDS); |
| 35 | service->OnUserChoseDatatypes(false, types); |
| 36 | } |
| 37 | |
[email protected] | 87d5eb4 | 2011-06-14 01:21:25 | [diff] [blame] | 38 | // Returns the next step for the non-fatal error case. |
| 39 | SyncSetupWizard::State GetStepForNonFatalError(ProfileSyncService* service) { |
[email protected] | b862fc8b | 2011-08-17 17:59:24 | [diff] [blame] | 40 | // TODO(sync): Update this error handling to allow different platforms to |
| 41 | // display the error appropriately (http://crbug.com/92722) instead of |
| 42 | // navigating to a LOGIN state that is not supported on every platform. |
[email protected] | bc44b8d8 | 2011-07-22 08:39:11 | [diff] [blame] | 43 | if (service->IsPassphraseRequired()) { |
| 44 | if (service->IsUsingSecondaryPassphrase()) |
[email protected] | 87d5eb4 | 2011-06-14 01:21:25 | [diff] [blame] | 45 | return SyncSetupWizard::ENTER_PASSPHRASE; |
[email protected] | 6f5fa9f | 2011-07-28 03:39:57 | [diff] [blame] | 46 | return SyncSetupWizard::GetLoginState(); |
[email protected] | bc44b8d8 | 2011-07-22 08:39:11 | [diff] [blame] | 47 | } |
[email protected] | 87d5eb4 | 2011-06-14 01:21:25 | [diff] [blame] | 48 | |
| 49 | const GoogleServiceAuthError& error = service->GetAuthError(); |
| 50 | if (error.state() == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS || |
| 51 | error.state() == GoogleServiceAuthError::CAPTCHA_REQUIRED || |
| 52 | error.state() == GoogleServiceAuthError::ACCOUNT_DELETED || |
| 53 | error.state() == GoogleServiceAuthError::ACCOUNT_DISABLED || |
| 54 | error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE) |
[email protected] | 6f5fa9f | 2011-07-28 03:39:57 | [diff] [blame] | 55 | return SyncSetupWizard::GetLoginState(); |
[email protected] | 87d5eb4 | 2011-06-14 01:21:25 | [diff] [blame] | 56 | |
| 57 | NOTREACHED(); |
| 58 | return SyncSetupWizard::FATAL_ERROR; |
| 59 | } |
| 60 | |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 61 | } // namespace |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 62 | |
[email protected] | 0865c134 | 2011-01-28 20:29:37 | [diff] [blame] | 63 | SyncConfiguration::SyncConfiguration() |
[email protected] | d45f751 | 2011-06-21 21:18:27 | [diff] [blame] | 64 | : encrypt_all(false), |
| 65 | sync_everything(false), |
[email protected] | 202b564 | 2011-09-10 02:04:07 | [diff] [blame] | 66 | set_secondary_passphrase(false), |
| 67 | set_gaia_passphrase(false) { |
[email protected] | 0865c134 | 2011-01-28 20:29:37 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | SyncConfiguration::~SyncConfiguration() {} |
| 71 | |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 72 | SyncSetupFlow::~SyncSetupFlow() { |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 73 | flow_handler_->SetFlow(NULL); |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 74 | } |
| 75 | |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 76 | // static |
| 77 | SyncSetupFlow* SyncSetupFlow::Run(ProfileSyncService* service, |
| 78 | SyncSetupFlowContainer* container, |
| 79 | SyncSetupWizard::State start, |
| 80 | SyncSetupWizard::State end) { |
[email protected] | 87d5eb4 | 2011-06-14 01:21:25 | [diff] [blame] | 81 | if (start == SyncSetupWizard::NONFATAL_ERROR) |
| 82 | start = GetStepForNonFatalError(service); |
[email protected] | 7518591 | 2011-09-08 03:03:08 | [diff] [blame] | 83 | if ((start == SyncSetupWizard::CONFIGURE || |
| 84 | start == SyncSetupWizard::SYNC_EVERYTHING || |
| 85 | start == SyncSetupWizard::ENTER_PASSPHRASE) && |
| 86 | !service->sync_initialized()) { |
| 87 | // We are trying to open configuration window, but the backend isn't ready. |
| 88 | // We just return NULL. This has the effect of the flow getting reset, and |
| 89 | // the user's action has no effect. |
| 90 | LOG(ERROR) << "Attempted to show sync configure before backend ready."; |
| 91 | return NULL; |
| 92 | } |
[email protected] | d693024 | 2011-09-03 01:52:19 | [diff] [blame] | 93 | return new SyncSetupFlow(start, end, container, service); |
[email protected] | e4be2dd | 2010-12-14 00:44:39 | [diff] [blame] | 94 | } |
| 95 | |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 96 | // static |
| 97 | void SyncSetupFlow::GetArgsForGaiaLogin(const ProfileSyncService* service, |
| 98 | DictionaryValue* args) { |
[email protected] | 712257e | 2009-11-11 22:57:46 | [diff] [blame] | 99 | const GoogleServiceAuthError& error = service->GetAuthError(); |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 100 | if (!service->last_attempted_user_email().empty()) { |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 101 | args->SetString("user", service->last_attempted_user_email()); |
| 102 | args->SetInteger("error", error.state()); |
| 103 | args->SetBoolean("editable_user", true); |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 104 | } else { |
[email protected] | bb868b4 | 2010-11-18 22:33:00 | [diff] [blame] | 105 | string16 user; |
| 106 | if (!service->cros_user().empty()) |
| 107 | user = UTF8ToUTF16(service->cros_user()); |
| 108 | else |
| 109 | user = service->GetAuthenticatedUsername(); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 110 | args->SetString("user", user); |
| 111 | args->SetInteger("error", 0); |
| 112 | args->SetBoolean("editable_user", user.empty()); |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 113 | } |
[email protected] | 1fc9b3f | 2009-11-12 21:22:09 | [diff] [blame] | 114 | |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 115 | args->SetString("captchaUrl", error.captcha().image_url.spec()); |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 116 | } |
| 117 | |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 118 | void SyncSetupFlow::GetArgsForConfigure(ProfileSyncService* service, |
| 119 | DictionaryValue* args) { |
[email protected] | 5d0e7c2 | 2011-04-19 23:09:07 | [diff] [blame] | 120 | // The SYNC_EVERYTHING case will set this to true. |
[email protected] | 56e2a440 | 2011-05-05 18:49:49 | [diff] [blame] | 121 | args->SetBoolean("showSyncEverythingPage", false); |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 122 | |
[email protected] | ff34710 | 2011-09-12 17:38:11 | [diff] [blame] | 123 | args->SetBoolean("syncAllDataTypes", |
[email protected] | 0d1b2c9 | 2011-10-07 18:48:54 | [diff] [blame] | 124 | service->profile()->GetPrefs()->GetBoolean( |
| 125 | prefs::kSyncKeepEverythingSynced)); |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 126 | |
| 127 | // Bookmarks, Preferences, and Themes are launched for good, there's no |
| 128 | // going back now. Check if the other data types are registered though. |
| 129 | syncable::ModelTypeSet registered_types; |
| 130 | service->GetRegisteredDataTypes(®istered_types); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 131 | args->SetBoolean("passwordsRegistered", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 132 | registered_types.count(syncable::PASSWORDS) > 0); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 133 | args->SetBoolean("autofillRegistered", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 134 | registered_types.count(syncable::AUTOFILL) > 0); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 135 | args->SetBoolean("extensionsRegistered", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 136 | registered_types.count(syncable::EXTENSIONS) > 0); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 137 | args->SetBoolean("typedUrlsRegistered", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 138 | registered_types.count(syncable::TYPED_URLS) > 0); |
[email protected] | 75b362b | 2010-08-17 04:18:13 | [diff] [blame] | 139 | args->SetBoolean("appsRegistered", |
[email protected] | 06e3320 | 2010-08-16 23:45:15 | [diff] [blame] | 140 | registered_types.count(syncable::APPS) > 0); |
[email protected] | d9e3309 | 2011-09-01 03:34:05 | [diff] [blame] | 141 | args->SetBoolean("searchEnginesRegistered", |
| 142 | registered_types.count(syncable::SEARCH_ENGINES) > 0); |
[email protected] | 5edb922 | 2010-08-18 00:23:29 | [diff] [blame] | 143 | args->SetBoolean("sessionsRegistered", |
| 144 | registered_types.count(syncable::SESSIONS) > 0); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 145 | args->SetBoolean("syncBookmarks", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 146 | service->profile()->GetPrefs()->GetBoolean(prefs::kSyncBookmarks)); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 147 | args->SetBoolean("syncPreferences", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 148 | service->profile()->GetPrefs()->GetBoolean(prefs::kSyncPreferences)); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 149 | args->SetBoolean("syncThemes", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 150 | service->profile()->GetPrefs()->GetBoolean(prefs::kSyncThemes)); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 151 | args->SetBoolean("syncPasswords", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 152 | service->profile()->GetPrefs()->GetBoolean(prefs::kSyncPasswords)); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 153 | args->SetBoolean("syncAutofill", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 154 | service->profile()->GetPrefs()->GetBoolean(prefs::kSyncAutofill)); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 155 | args->SetBoolean("syncExtensions", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 156 | service->profile()->GetPrefs()->GetBoolean(prefs::kSyncExtensions)); |
[email protected] | d9e3309 | 2011-09-01 03:34:05 | [diff] [blame] | 157 | args->SetBoolean("syncSearchEngines", |
| 158 | service->profile()->GetPrefs()->GetBoolean(prefs::kSyncSearchEngines)); |
[email protected] | 5edb922 | 2010-08-18 00:23:29 | [diff] [blame] | 159 | args->SetBoolean("syncSessions", |
| 160 | service->profile()->GetPrefs()->GetBoolean(prefs::kSyncSessions)); |
[email protected] | dc9a676 | 2010-08-16 07:13:53 | [diff] [blame] | 161 | args->SetBoolean("syncTypedUrls", |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 162 | service->profile()->GetPrefs()->GetBoolean(prefs::kSyncTypedUrls)); |
[email protected] | 75b362b | 2010-08-17 04:18:13 | [diff] [blame] | 163 | args->SetBoolean("syncApps", |
[email protected] | 06e3320 | 2010-08-16 23:45:15 | [diff] [blame] | 164 | service->profile()->GetPrefs()->GetBoolean(prefs::kSyncApps)); |
[email protected] | 23ec180 | 2011-05-24 17:40:31 | [diff] [blame] | 165 | args->SetBoolean("encryptionEnabled", |
[email protected] | a57c07c | 2011-07-20 00:59:13 | [diff] [blame] | 166 | !CommandLine::ForCurrentProcess()->HasSwitch( |
| 167 | switches::kDisableSyncEncryption)); |
[email protected] | 23ec180 | 2011-05-24 17:40:31 | [diff] [blame] | 168 | |
[email protected] | 794742d | 2011-09-09 21:44:31 | [diff] [blame] | 169 | bool encrypt_all = service->EncryptEverythingEnabled(); |
| 170 | if (service->encryption_pending()) |
[email protected] | cc10e7c | 2011-08-06 00:17:50 | [diff] [blame] | 171 | encrypt_all = true; |
[email protected] | 23ec180 | 2011-05-24 17:40:31 | [diff] [blame] | 172 | args->SetBoolean("encryptAllData", encrypt_all); |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 173 | |
| 174 | // Load the parameters for the encryption tab. |
| 175 | args->SetBoolean("usePassphrase", service->IsUsingSecondaryPassphrase()); |
[email protected] | d693024 | 2011-09-03 01:52:19 | [diff] [blame] | 176 | |
| 177 | // Determine if we need a passphrase or not, and if so, prompt the user. |
| 178 | if (service->IsPassphraseRequiredForDecryption() && |
| 179 | (service->IsUsingSecondaryPassphrase() || cached_passphrase_.empty())) { |
| 180 | // We need a passphrase, and either it's an explicit passphrase, or we |
| 181 | // don't have a cached gaia passphrase, so we have to prompt the user. |
| 182 | args->SetBoolean("show_passphrase", true); |
[email protected] | 202b564 | 2011-09-10 02:04:07 | [diff] [blame] | 183 | // Tell the UI layer what kind of passphrase we need. |
| 184 | args->SetBoolean("need_google_passphrase", |
| 185 | !service->IsUsingSecondaryPassphrase()); |
| 186 | args->SetBoolean("passphrase_creation_rejected", |
[email protected] | c63fa11 | 2011-10-06 20:17:15 | [diff] [blame] | 187 | user_tried_creating_explicit_passphrase_); |
[email protected] | 202b564 | 2011-09-10 02:04:07 | [diff] [blame] | 188 | args->SetBoolean("passphrase_setting_rejected", |
[email protected] | c63fa11 | 2011-10-06 20:17:15 | [diff] [blame] | 189 | user_tried_setting_passphrase_); |
[email protected] | d693024 | 2011-09-03 01:52:19 | [diff] [blame] | 190 | } |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 191 | } |
| 192 | |
[email protected] | 7c72ecaf | 2011-06-15 20:42:47 | [diff] [blame] | 193 | bool SyncSetupFlow::AttachSyncSetupHandler(SyncSetupFlowHandler* handler) { |
| 194 | if (flow_handler_) |
| 195 | return false; |
| 196 | |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 197 | flow_handler_ = handler; |
[email protected] | 87d5eb4 | 2011-06-14 01:21:25 | [diff] [blame] | 198 | handler->SetFlow(this); |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 199 | ActivateState(current_state_); |
[email protected] | 7c72ecaf | 2011-06-15 20:42:47 | [diff] [blame] | 200 | return true; |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 201 | } |
| 202 | |
[email protected] | 3c9e109 | 2011-08-04 18:41:15 | [diff] [blame] | 203 | bool SyncSetupFlow::IsAttached() const { |
| 204 | return flow_handler_ != NULL; |
| 205 | } |
| 206 | |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 207 | void SyncSetupFlow::Advance(SyncSetupWizard::State advance_state) { |
| 208 | if (!ShouldAdvance(advance_state)) { |
| 209 | LOG(WARNING) << "Invalid state change from " |
| 210 | << current_state_ << " to " << advance_state; |
| 211 | return; |
| 212 | } |
| 213 | |
[email protected] | 3c9e109 | 2011-08-04 18:41:15 | [diff] [blame] | 214 | if (flow_handler_) |
| 215 | ActivateState(advance_state); |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 216 | } |
| 217 | |
| 218 | void SyncSetupFlow::Focus() { |
[email protected] | 6783bdd | 2011-06-28 23:51:47 | [diff] [blame] | 219 | // This gets called from SyncSetupWizard::Focus(), and might get called |
| 220 | // before flow_handler_ is set in AttachSyncSetupHandler() (which gets |
| 221 | // called asynchronously after the UI initializes). |
| 222 | if (flow_handler_) |
| 223 | flow_handler_->Focus(); |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 224 | } |
| 225 | |
| 226 | // A callback to notify the delegate that the dialog closed. |
[email protected] | 6f5fa9f | 2011-07-28 03:39:57 | [diff] [blame] | 227 | // TODO(rickcam): Bug 90713: Handle OAUTH_LOGIN case here |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 228 | void SyncSetupFlow::OnDialogClosed(const std::string& json_retval) { |
| 229 | DCHECK(json_retval.empty()); |
| 230 | container_->set_flow(NULL); // Sever ties from the wizard. |
[email protected] | 7ad97cf | 2011-07-29 21:42:16 | [diff] [blame] | 231 | // If we've reached the end, mark it. This could be a discrete run, in which |
| 232 | // case it's already set, but it simplifes the logic to do it this way. |
| 233 | if (current_state_ == end_state_) |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 234 | service_->SetSyncSetupCompleted(); |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 235 | |
| 236 | // Record the state at which the user cancelled the signon dialog. |
| 237 | switch (current_state_) { |
| 238 | case SyncSetupWizard::GAIA_LOGIN: |
| 239 | ProfileSyncService::SyncEvent( |
| 240 | ProfileSyncService::CANCEL_FROM_SIGNON_WITHOUT_AUTH); |
| 241 | break; |
| 242 | case SyncSetupWizard::GAIA_SUCCESS: |
| 243 | ProfileSyncService::SyncEvent( |
| 244 | ProfileSyncService::CANCEL_DURING_SIGNON); |
| 245 | break; |
| 246 | case SyncSetupWizard::CONFIGURE: |
| 247 | case SyncSetupWizard::ENTER_PASSPHRASE: |
| 248 | case SyncSetupWizard::SETTING_UP: |
| 249 | // TODO(atwilson): Treat a close during ENTER_PASSPHRASE like a |
| 250 | // Cancel + Skip (i.e. call OnPassphraseCancel()). http://crbug.com/74645 |
| 251 | ProfileSyncService::SyncEvent( |
| 252 | ProfileSyncService::CANCEL_DURING_CONFIGURE); |
| 253 | break; |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 254 | case SyncSetupWizard::DONE: |
| 255 | // TODO(sync): rename this histogram; it's tracking authorization AND |
| 256 | // initial sync download time. |
| 257 | UMA_HISTOGRAM_MEDIUM_TIMES("Sync.UserPerceivedAuthorizationTime", |
| 258 | base::TimeTicks::Now() - login_start_time_); |
| 259 | break; |
| 260 | default: |
| 261 | break; |
| 262 | } |
| 263 | |
| 264 | service_->OnUserCancelledDialog(); |
| 265 | delete this; |
| 266 | } |
| 267 | |
| 268 | void SyncSetupFlow::OnUserSubmittedAuth(const std::string& username, |
| 269 | const std::string& password, |
| 270 | const std::string& captcha, |
| 271 | const std::string& access_code) { |
[email protected] | a313caa3 | 2011-09-09 04:31:05 | [diff] [blame] | 272 | // It's possible to receive an empty password (e.g. for ASP's), in which case |
| 273 | // we don't want to overwrite any previously cached password. |
| 274 | if (!password.empty()) |
| 275 | cached_passphrase_ = password; |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 276 | service_->OnUserSubmittedAuth(username, password, captcha, access_code); |
| 277 | } |
| 278 | |
[email protected] | 934a3079 | 2011-09-12 19:15:44 | [diff] [blame] | 279 | void SyncSetupFlow::OnUserSubmittedOAuth( |
| 280 | const std::string& oauth1_request_token) { |
| 281 | service_->OnUserSubmittedOAuth(oauth1_request_token); |
| 282 | } |
| 283 | |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 284 | void SyncSetupFlow::OnUserConfigured(const SyncConfiguration& configuration) { |
| 285 | // Go to the "loading..." screen. |
| 286 | Advance(SyncSetupWizard::SETTING_UP); |
| 287 | |
[email protected] | cc10e7c | 2011-08-06 00:17:50 | [diff] [blame] | 288 | // Note: encryption will not occur until OnUserChoseDatatypes is called. |
[email protected] | 794742d | 2011-09-09 21:44:31 | [diff] [blame] | 289 | service_->SetEncryptEverything(configuration.encrypt_all); |
[email protected] | c63fa11 | 2011-10-06 20:17:15 | [diff] [blame] | 290 | bool set_new_decryption_passphrase = false; |
[email protected] | 202b564 | 2011-09-10 02:04:07 | [diff] [blame] | 291 | if (configuration.set_gaia_passphrase) { |
[email protected] | 1a315b4 | 2011-08-04 17:44:18 | [diff] [blame] | 292 | // Caller passed a gaia passphrase. This is illegal if we are currently |
| 293 | // using a secondary passphrase. |
| 294 | DCHECK(!service_->IsUsingSecondaryPassphrase()); |
[email protected] | d693024 | 2011-09-03 01:52:19 | [diff] [blame] | 295 | service_->SetPassphrase(configuration.gaia_passphrase, false); |
[email protected] | 202b564 | 2011-09-10 02:04:07 | [diff] [blame] | 296 | // Since the user entered the passphrase manually, set this flag so we can |
| 297 | // report an error if the passphrase setting failed. |
[email protected] | c63fa11 | 2011-10-06 20:17:15 | [diff] [blame] | 298 | user_tried_setting_passphrase_ = true; |
| 299 | set_new_decryption_passphrase = true; |
[email protected] | d693024 | 2011-09-03 01:52:19 | [diff] [blame] | 300 | } else if (!service_->IsUsingSecondaryPassphrase() && |
| 301 | !cached_passphrase_.empty()) { |
| 302 | // Service needs a GAIA passphrase and we have one cached, so try it. |
| 303 | service_->SetPassphrase(cached_passphrase_, false); |
| 304 | cached_passphrase_.clear(); |
[email protected] | c63fa11 | 2011-10-06 20:17:15 | [diff] [blame] | 305 | set_new_decryption_passphrase = true; |
[email protected] | d693024 | 2011-09-03 01:52:19 | [diff] [blame] | 306 | } else { |
[email protected] | 202b564 | 2011-09-10 02:04:07 | [diff] [blame] | 307 | // We can get here if the user changes their GAIA passphrase but still has |
| 308 | // data encrypted with the old passphrase. The UI prompts the user for their |
| 309 | // passphrase, but they might just leave it blank/disable the encrypted |
| 310 | // types. |
[email protected] | d693024 | 2011-09-03 01:52:19 | [diff] [blame] | 311 | // No gaia passphrase cached or set, so make sure the ProfileSyncService |
| 312 | // wasn't expecting one. |
[email protected] | 202b564 | 2011-09-10 02:04:07 | [diff] [blame] | 313 | DLOG_IF(WARNING, !service_->IsUsingSecondaryPassphrase() && |
| 314 | service_->IsPassphraseRequiredForDecryption()) << |
| 315 | "Google passphrase required but not provided by UI"; |
[email protected] | 1a315b4 | 2011-08-04 17:44:18 | [diff] [blame] | 316 | } |
| 317 | |
[email protected] | 202b564 | 2011-09-10 02:04:07 | [diff] [blame] | 318 | // Set the secondary passphrase, either as a decryption passphrase, or |
| 319 | // as an attempt to encrypt the user's data using this new passphrase. |
| 320 | if (configuration.set_secondary_passphrase) { |
[email protected] | d693024 | 2011-09-03 01:52:19 | [diff] [blame] | 321 | service_->SetPassphrase(configuration.secondary_passphrase, true); |
[email protected] | c63fa11 | 2011-10-06 20:17:15 | [diff] [blame] | 322 | if (service_->IsUsingSecondaryPassphrase()) { |
| 323 | user_tried_setting_passphrase_ = true; |
| 324 | set_new_decryption_passphrase = true; |
| 325 | } else { |
| 326 | user_tried_creating_explicit_passphrase_ = true; |
| 327 | } |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 328 | } |
| 329 | |
| 330 | service_->OnUserChoseDatatypes(configuration.sync_everything, |
| 331 | configuration.data_types); |
[email protected] | c63fa11 | 2011-10-06 20:17:15 | [diff] [blame] | 332 | |
| 333 | // See if we are done configuring (if we don't need a passphrase, and don't |
| 334 | // need to hang around waiting for encryption to happen, just exit). This call |
| 335 | // to IsPassphraseRequiredForDecryption() takes into account the data types |
| 336 | // we just enabled/disabled. |
[email protected] | 31af458bd | 2011-10-15 02:37:44 | [diff] [blame] | 337 | if (!service_->IsPassphraseRequiredForDecryption() && |
| 338 | !service_->encryption_pending()) { |
[email protected] | c63fa11 | 2011-10-06 20:17:15 | [diff] [blame] | 339 | Advance(SyncSetupWizard::DONE); |
| 340 | } else if (!set_new_decryption_passphrase) { |
| 341 | // We need a passphrase, but the user did not provide one, so transition |
| 342 | // directly to ENTER_PASSPHRASE (otherwise we'll have to wait until |
| 343 | // the sync engine generates another OnPassphraseRequired() at the end of |
| 344 | // the sync cycle which can take a long time). |
| 345 | Advance(SyncSetupWizard::ENTER_PASSPHRASE); |
| 346 | } |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 347 | } |
| 348 | |
| 349 | void SyncSetupFlow::OnPassphraseEntry(const std::string& passphrase) { |
| 350 | Advance(SyncSetupWizard::SETTING_UP); |
[email protected] | d693024 | 2011-09-03 01:52:19 | [diff] [blame] | 351 | service_->SetPassphrase(passphrase, true); |
[email protected] | c63fa11 | 2011-10-06 20:17:15 | [diff] [blame] | 352 | user_tried_setting_passphrase_ = true; |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 353 | } |
| 354 | |
| 355 | void SyncSetupFlow::OnPassphraseCancel() { |
| 356 | // If the user cancels when being asked for the passphrase, |
| 357 | // just disable encrypted sync and continue setting up. |
| 358 | if (current_state_ == SyncSetupWizard::ENTER_PASSPHRASE) |
| 359 | DisablePasswordSync(service_); |
| 360 | |
| 361 | Advance(SyncSetupWizard::SETTING_UP); |
| 362 | } |
| 363 | |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 364 | // Use static Run method to get an instance. |
| 365 | SyncSetupFlow::SyncSetupFlow(SyncSetupWizard::State start_state, |
| 366 | SyncSetupWizard::State end_state, |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 367 | SyncSetupFlowContainer* container, |
| 368 | ProfileSyncService* service) |
| 369 | : container_(container), |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 370 | current_state_(start_state), |
| 371 | end_state_(end_state), |
| 372 | login_start_time_(base::TimeTicks::Now()), |
| 373 | flow_handler_(NULL), |
| 374 | service_(service), |
[email protected] | c63fa11 | 2011-10-06 20:17:15 | [diff] [blame] | 375 | user_tried_creating_explicit_passphrase_(false), |
| 376 | user_tried_setting_passphrase_(false) { |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 377 | } |
| 378 | |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 379 | // Returns true if the flow should advance to |state| based on |current_state_|. |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 380 | bool SyncSetupFlow::ShouldAdvance(SyncSetupWizard::State state) { |
| 381 | switch (state) { |
[email protected] | 6f5fa9f | 2011-07-28 03:39:57 | [diff] [blame] | 382 | case SyncSetupWizard::OAUTH_LOGIN: |
| 383 | return current_state_ == SyncSetupWizard::FATAL_ERROR || |
| 384 | current_state_ == SyncSetupWizard::OAUTH_LOGIN || |
| 385 | current_state_ == SyncSetupWizard::SETTING_UP; |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 386 | case SyncSetupWizard::GAIA_LOGIN: |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 387 | return current_state_ == SyncSetupWizard::FATAL_ERROR || |
[email protected] | 7155564 | 2011-02-23 18:51:04 | [diff] [blame] | 388 | current_state_ == SyncSetupWizard::GAIA_LOGIN || |
| 389 | current_state_ == SyncSetupWizard::SETTING_UP; |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 390 | case SyncSetupWizard::GAIA_SUCCESS: |
[email protected] | 6f5fa9f | 2011-07-28 03:39:57 | [diff] [blame] | 391 | return current_state_ == SyncSetupWizard::GAIA_LOGIN || |
| 392 | current_state_ == SyncSetupWizard::OAUTH_LOGIN; |
| 393 | case SyncSetupWizard::SYNC_EVERYTHING: // Intentionally fall through. |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 394 | case SyncSetupWizard::CONFIGURE: |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 395 | return current_state_ == SyncSetupWizard::GAIA_SUCCESS; |
[email protected] | 66d8100 | 2010-10-18 16:52:09 | [diff] [blame] | 396 | case SyncSetupWizard::ENTER_PASSPHRASE: |
[email protected] | 5d0e7c2 | 2011-04-19 23:09:07 | [diff] [blame] | 397 | return current_state_ == SyncSetupWizard::SYNC_EVERYTHING || |
| 398 | current_state_ == SyncSetupWizard::CONFIGURE || |
[email protected] | 66d8100 | 2010-10-18 16:52:09 | [diff] [blame] | 399 | current_state_ == SyncSetupWizard::SETTING_UP; |
[email protected] | a47eeb5 | 2010-07-15 17:54:25 | [diff] [blame] | 400 | case SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR: |
[email protected] | cb5199b | 2011-09-04 01:55:52 | [diff] [blame] | 401 | return current_state_ != SyncSetupWizard::ABORT; |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 402 | case SyncSetupWizard::SETTING_UP: |
[email protected] | 5d0e7c2 | 2011-04-19 23:09:07 | [diff] [blame] | 403 | return current_state_ == SyncSetupWizard::SYNC_EVERYTHING || |
| 404 | current_state_ == SyncSetupWizard::CONFIGURE || |
[email protected] | 5c0ec92f | 2011-05-09 20:28:52 | [diff] [blame] | 405 | current_state_ == SyncSetupWizard::ENTER_PASSPHRASE; |
[email protected] | 6f5fa9f | 2011-07-28 03:39:57 | [diff] [blame] | 406 | case SyncSetupWizard::NONFATAL_ERROR: // Intentionally fall through. |
[email protected] | fb42c98 | 2009-09-16 22:33:33 | [diff] [blame] | 407 | case SyncSetupWizard::FATAL_ERROR: |
[email protected] | cb5199b | 2011-09-04 01:55:52 | [diff] [blame] | 408 | return current_state_ != SyncSetupWizard::ABORT; |
| 409 | case SyncSetupWizard::ABORT: |
| 410 | return true; |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 411 | case SyncSetupWizard::DONE: |
[email protected] | 66d8100 | 2010-10-18 16:52:09 | [diff] [blame] | 412 | return current_state_ == SyncSetupWizard::SETTING_UP || |
| 413 | current_state_ == SyncSetupWizard::ENTER_PASSPHRASE; |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 414 | default: |
| 415 | NOTREACHED() << "Unhandled State: " << state; |
| 416 | return false; |
| 417 | } |
| 418 | } |
| 419 | |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 420 | void SyncSetupFlow::ActivateState(SyncSetupWizard::State state) { |
[email protected] | 7c72ecaf | 2011-06-15 20:42:47 | [diff] [blame] | 421 | DCHECK(flow_handler_); |
| 422 | |
[email protected] | 87d5eb4 | 2011-06-14 01:21:25 | [diff] [blame] | 423 | if (state == SyncSetupWizard::NONFATAL_ERROR) |
| 424 | state = GetStepForNonFatalError(service_); |
| 425 | |
| 426 | current_state_ = state; |
| 427 | |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 428 | switch (state) { |
[email protected] | 6f5fa9f | 2011-07-28 03:39:57 | [diff] [blame] | 429 | case SyncSetupWizard::OAUTH_LOGIN: { |
| 430 | flow_handler_->ShowOAuthLogin(); |
| 431 | break; |
| 432 | } |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 433 | case SyncSetupWizard::GAIA_LOGIN: { |
| 434 | DictionaryValue args; |
| 435 | SyncSetupFlow::GetArgsForGaiaLogin(service_, &args); |
| 436 | flow_handler_->ShowGaiaLogin(args); |
| 437 | break; |
| 438 | } |
| 439 | case SyncSetupWizard::GAIA_SUCCESS: |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 440 | if (end_state_ == SyncSetupWizard::GAIA_SUCCESS) { |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 441 | flow_handler_->ShowGaiaSuccessAndClose(); |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 442 | break; |
| 443 | } |
[email protected] | d2c04f2 | 2011-06-22 17:39:04 | [diff] [blame] | 444 | flow_handler_->ShowGaiaSuccessAndSettingUp(); |
| 445 | break; |
[email protected] | 5d0e7c2 | 2011-04-19 23:09:07 | [diff] [blame] | 446 | case SyncSetupWizard::SYNC_EVERYTHING: { |
| 447 | DictionaryValue args; |
| 448 | SyncSetupFlow::GetArgsForConfigure(service_, &args); |
[email protected] | 56e2a440 | 2011-05-05 18:49:49 | [diff] [blame] | 449 | args.SetBoolean("showSyncEverythingPage", true); |
[email protected] | 5d0e7c2 | 2011-04-19 23:09:07 | [diff] [blame] | 450 | flow_handler_->ShowConfigure(args); |
| 451 | break; |
| 452 | } |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 453 | case SyncSetupWizard::CONFIGURE: { |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 454 | DictionaryValue args; |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 455 | SyncSetupFlow::GetArgsForConfigure(service_, &args); |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 456 | flow_handler_->ShowConfigure(args); |
| 457 | break; |
| 458 | } |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 459 | case SyncSetupWizard::ENTER_PASSPHRASE: { |
| 460 | DictionaryValue args; |
[email protected] | 503ff125 | 2011-06-01 20:36:24 | [diff] [blame] | 461 | SyncSetupFlow::GetArgsForConfigure(service_, &args); |
[email protected] | d693024 | 2011-09-03 01:52:19 | [diff] [blame] | 462 | GetArgsForConfigure(service_, &args); |
| 463 | // TODO(atwilson): Remove ShowPassphraseEntry in favor of using |
| 464 | // ShowConfigure() - http://crbug.com/90786. |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 465 | flow_handler_->ShowPassphraseEntry(args); |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 466 | break; |
[email protected] | 8c94d63 | 2010-06-25 22:38:00 | [diff] [blame] | 467 | } |
[email protected] | a47eeb5 | 2010-07-15 17:54:25 | [diff] [blame] | 468 | case SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR: { |
[email protected] | 41bd81eb9 | 2011-10-10 20:17:53 | [diff] [blame] | 469 | // TODO(sync): We should expose a real "display an error" API on |
| 470 | // SyncSetupFlowHandler (crbug.com/92722) but for now just transition |
| 471 | // to the login state with a special error code. |
[email protected] | a47eeb5 | 2010-07-15 17:54:25 | [diff] [blame] | 472 | DictionaryValue args; |
[email protected] | d898dc97 | 2011-09-15 21:54:01 | [diff] [blame] | 473 | SyncSetupFlow::GetArgsForGaiaLogin(service_, &args); |
| 474 | args.SetInteger("error", GoogleServiceAuthError::SERVICE_UNAVAILABLE); |
[email protected] | 41bd81eb9 | 2011-10-10 20:17:53 | [diff] [blame] | 475 | current_state_ = SyncSetupWizard::GAIA_LOGIN; |
[email protected] | d898dc97 | 2011-09-15 21:54:01 | [diff] [blame] | 476 | flow_handler_->ShowGaiaLogin(args); |
[email protected] | c976938f | 2010-10-12 04:55:44 | [diff] [blame] | 477 | break; |
| 478 | } |
| 479 | case SyncSetupWizard::SETTING_UP: { |
| 480 | flow_handler_->ShowSettingUp(); |
[email protected] | a47eeb5 | 2010-07-15 17:54:25 | [diff] [blame] | 481 | break; |
| 482 | } |
[email protected] | 2be7bf2 | 2010-04-23 21:02:37 | [diff] [blame] | 483 | case SyncSetupWizard::FATAL_ERROR: { |
| 484 | // This shows the user the "Could not connect to server" error. |
[email protected] | b862fc8b | 2011-08-17 17:59:24 | [diff] [blame] | 485 | // TODO(sync): Update this error handling to allow different platforms to |
| 486 | // display the error appropriately (http://crbug.com/92722). |
[email protected] | 2be7bf2 | 2010-04-23 21:02:37 | [diff] [blame] | 487 | DictionaryValue args; |
| 488 | SyncSetupFlow::GetArgsForGaiaLogin(service_, &args); |
[email protected] | 349f9bc | 2011-10-06 18:52:02 | [diff] [blame] | 489 | args.SetBoolean("fatalError", true); |
[email protected] | 41bd81eb9 | 2011-10-10 20:17:53 | [diff] [blame] | 490 | current_state_ = SyncSetupWizard::GAIA_LOGIN; |
[email protected] | 2be7bf2 | 2010-04-23 21:02:37 | [diff] [blame] | 491 | flow_handler_->ShowGaiaLogin(args); |
[email protected] | fb42c98 | 2009-09-16 22:33:33 | [diff] [blame] | 492 | break; |
[email protected] | 2be7bf2 | 2010-04-23 21:02:37 | [diff] [blame] | 493 | } |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 494 | case SyncSetupWizard::DONE: |
[email protected] | cb5199b | 2011-09-04 01:55:52 | [diff] [blame] | 495 | case SyncSetupWizard::ABORT: |
[email protected] | d80033e | 2009-10-16 10:32:04 | [diff] [blame] | 496 | flow_handler_->ShowSetupDone( |
| 497 | UTF16ToWide(service_->GetAuthenticatedUsername())); |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 498 | break; |
| 499 | default: |
[email protected] | a159596 | 2011-04-22 21:56:24 | [diff] [blame] | 500 | NOTREACHED() << "Invalid advance state: " << state; |
[email protected] | 132c8565 | 2009-08-05 01:18:27 | [diff] [blame] | 501 | } |
[email protected] | 22d3eff | 2011-01-08 01:45:18 | [diff] [blame] | 502 | } |