blob: e83183122a0d0984bc06b0abf6acce58beaa5b39 [file] [log] [blame]
[email protected]0865c1342011-01-28 20:29:371// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]132c85652009-08-05 01:18:272// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]d80033e2009-10-16 10:32:045#include "chrome/browser/sync/sync_setup_flow.h"
[email protected]8ac2dc112009-10-01 23:19:136
[email protected]2041cf342010-02-19 03:15:597#include "base/callback.h"
[email protected]23ec1802011-05-24 17:40:318#include "base/command_line.h"
[email protected]93d49d72009-10-23 20:00:209#include "base/json/json_reader.h"
10#include "base/json/json_writer.h"
[email protected]835d7c82010-10-14 04:38:3811#include "base/metrics/histogram.h"
[email protected]132c85652009-08-05 01:18:2712#include "base/string_util.h"
[email protected]d80033e2009-10-16 10:32:0413#include "base/utf_string_conversions.h"
[email protected]132c85652009-08-05 01:18:2714#include "base/values.h"
[email protected]37858e52010-08-26 00:22:0215#include "chrome/browser/prefs/pref_service.h"
[email protected]8ecad5e2010-12-02 21:18:3316#include "chrome/browser/profiles/profile.h"
[email protected]132c85652009-08-05 01:18:2717#include "chrome/browser/sync/profile_sync_service.h"
[email protected]a1595962011-04-22 21:56:2418#include "chrome/browser/sync/sync_setup_flow_handler.h"
[email protected]80772ed2011-08-09 21:11:3819#include "chrome/browser/sync/syncable/model_type.h"
[email protected]934a30792011-09-12 19:15:4420#include "chrome/browser/sync/util/oauth.h"
[email protected]2ad4a902010-11-17 06:05:1321#include "chrome/browser/ui/browser_list.h"
[email protected]23ec1802011-05-24 17:40:3122#include "chrome/common/chrome_switches.h"
[email protected]99074c52010-08-19 18:44:1923#include "chrome/common/net/gaia/google_service_auth_error.h"
[email protected]24f83712009-10-08 22:52:4524#include "chrome/common/pref_names.h"
[email protected]a1595962011-04-22 21:56:2425#include "chrome/common/url_constants.h"
[email protected]d2912a22011-03-15 15:20:5026#include "grit/generated_resources.h"
[email protected]9dd7e3d72011-01-20 18:27:0627
[email protected]a1595962011-04-22 21:56:2428namespace {
29
30// Helper function to disable password sync.
31void 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]87d5eb42011-06-14 01:21:2538// Returns the next step for the non-fatal error case.
39SyncSetupWizard::State GetStepForNonFatalError(ProfileSyncService* service) {
[email protected]b862fc8b2011-08-17 17:59:2440 // 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]bc44b8d82011-07-22 08:39:1143 if (service->IsPassphraseRequired()) {
44 if (service->IsUsingSecondaryPassphrase())
[email protected]87d5eb42011-06-14 01:21:2545 return SyncSetupWizard::ENTER_PASSPHRASE;
[email protected]6f5fa9f2011-07-28 03:39:5746 return SyncSetupWizard::GetLoginState();
[email protected]bc44b8d82011-07-22 08:39:1147 }
[email protected]87d5eb42011-06-14 01:21:2548
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]6f5fa9f2011-07-28 03:39:5755 return SyncSetupWizard::GetLoginState();
[email protected]87d5eb42011-06-14 01:21:2556
57 NOTREACHED();
58 return SyncSetupWizard::FATAL_ERROR;
59}
60
[email protected]a1595962011-04-22 21:56:2461} // namespace
[email protected]132c85652009-08-05 01:18:2762
[email protected]0865c1342011-01-28 20:29:3763SyncConfiguration::SyncConfiguration()
[email protected]d45f7512011-06-21 21:18:2764 : encrypt_all(false),
65 sync_everything(false),
[email protected]202b5642011-09-10 02:04:0766 set_secondary_passphrase(false),
67 set_gaia_passphrase(false) {
[email protected]0865c1342011-01-28 20:29:3768}
69
70SyncConfiguration::~SyncConfiguration() {}
71
[email protected]132c85652009-08-05 01:18:2772SyncSetupFlow::~SyncSetupFlow() {
[email protected]a1595962011-04-22 21:56:2473 flow_handler_->SetFlow(NULL);
[email protected]132c85652009-08-05 01:18:2774}
75
[email protected]a1595962011-04-22 21:56:2476// static
77SyncSetupFlow* SyncSetupFlow::Run(ProfileSyncService* service,
78 SyncSetupFlowContainer* container,
79 SyncSetupWizard::State start,
80 SyncSetupWizard::State end) {
[email protected]87d5eb42011-06-14 01:21:2581 if (start == SyncSetupWizard::NONFATAL_ERROR)
82 start = GetStepForNonFatalError(service);
[email protected]75185912011-09-08 03:03:0883 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]d6930242011-09-03 01:52:1993 return new SyncSetupFlow(start, end, container, service);
[email protected]e4be2dd2010-12-14 00:44:3994}
95
[email protected]132c85652009-08-05 01:18:2796// static
97void SyncSetupFlow::GetArgsForGaiaLogin(const ProfileSyncService* service,
98 DictionaryValue* args) {
[email protected]712257e2009-11-11 22:57:4699 const GoogleServiceAuthError& error = service->GetAuthError();
[email protected]132c85652009-08-05 01:18:27100 if (!service->last_attempted_user_email().empty()) {
[email protected]dc9a6762010-08-16 07:13:53101 args->SetString("user", service->last_attempted_user_email());
102 args->SetInteger("error", error.state());
103 args->SetBoolean("editable_user", true);
[email protected]132c85652009-08-05 01:18:27104 } else {
[email protected]bb868b42010-11-18 22:33:00105 string16 user;
106 if (!service->cros_user().empty())
107 user = UTF8ToUTF16(service->cros_user());
108 else
109 user = service->GetAuthenticatedUsername();
[email protected]dc9a6762010-08-16 07:13:53110 args->SetString("user", user);
111 args->SetInteger("error", 0);
112 args->SetBoolean("editable_user", user.empty());
[email protected]132c85652009-08-05 01:18:27113 }
[email protected]1fc9b3f2009-11-12 21:22:09114
[email protected]dc9a6762010-08-16 07:13:53115 args->SetString("captchaUrl", error.captcha().image_url.spec());
[email protected]132c85652009-08-05 01:18:27116}
117
[email protected]c976938f2010-10-12 04:55:44118void SyncSetupFlow::GetArgsForConfigure(ProfileSyncService* service,
119 DictionaryValue* args) {
[email protected]5d0e7c22011-04-19 23:09:07120 // The SYNC_EVERYTHING case will set this to true.
[email protected]56e2a4402011-05-05 18:49:49121 args->SetBoolean("showSyncEverythingPage", false);
[email protected]c976938f2010-10-12 04:55:44122
[email protected]ff347102011-09-12 17:38:11123 args->SetBoolean("syncAllDataTypes",
[email protected]0d1b2c92011-10-07 18:48:54124 service->profile()->GetPrefs()->GetBoolean(
125 prefs::kSyncKeepEverythingSynced));
[email protected]8c94d632010-06-25 22:38:00126
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(&registered_types);
[email protected]dc9a6762010-08-16 07:13:53131 args->SetBoolean("passwordsRegistered",
[email protected]8c94d632010-06-25 22:38:00132 registered_types.count(syncable::PASSWORDS) > 0);
[email protected]dc9a6762010-08-16 07:13:53133 args->SetBoolean("autofillRegistered",
[email protected]8c94d632010-06-25 22:38:00134 registered_types.count(syncable::AUTOFILL) > 0);
[email protected]dc9a6762010-08-16 07:13:53135 args->SetBoolean("extensionsRegistered",
[email protected]8c94d632010-06-25 22:38:00136 registered_types.count(syncable::EXTENSIONS) > 0);
[email protected]dc9a6762010-08-16 07:13:53137 args->SetBoolean("typedUrlsRegistered",
[email protected]8c94d632010-06-25 22:38:00138 registered_types.count(syncable::TYPED_URLS) > 0);
[email protected]75b362b2010-08-17 04:18:13139 args->SetBoolean("appsRegistered",
[email protected]06e33202010-08-16 23:45:15140 registered_types.count(syncable::APPS) > 0);
[email protected]d9e33092011-09-01 03:34:05141 args->SetBoolean("searchEnginesRegistered",
142 registered_types.count(syncable::SEARCH_ENGINES) > 0);
[email protected]5edb9222010-08-18 00:23:29143 args->SetBoolean("sessionsRegistered",
144 registered_types.count(syncable::SESSIONS) > 0);
[email protected]dc9a6762010-08-16 07:13:53145 args->SetBoolean("syncBookmarks",
[email protected]8c94d632010-06-25 22:38:00146 service->profile()->GetPrefs()->GetBoolean(prefs::kSyncBookmarks));
[email protected]dc9a6762010-08-16 07:13:53147 args->SetBoolean("syncPreferences",
[email protected]8c94d632010-06-25 22:38:00148 service->profile()->GetPrefs()->GetBoolean(prefs::kSyncPreferences));
[email protected]dc9a6762010-08-16 07:13:53149 args->SetBoolean("syncThemes",
[email protected]8c94d632010-06-25 22:38:00150 service->profile()->GetPrefs()->GetBoolean(prefs::kSyncThemes));
[email protected]dc9a6762010-08-16 07:13:53151 args->SetBoolean("syncPasswords",
[email protected]8c94d632010-06-25 22:38:00152 service->profile()->GetPrefs()->GetBoolean(prefs::kSyncPasswords));
[email protected]dc9a6762010-08-16 07:13:53153 args->SetBoolean("syncAutofill",
[email protected]8c94d632010-06-25 22:38:00154 service->profile()->GetPrefs()->GetBoolean(prefs::kSyncAutofill));
[email protected]dc9a6762010-08-16 07:13:53155 args->SetBoolean("syncExtensions",
[email protected]8c94d632010-06-25 22:38:00156 service->profile()->GetPrefs()->GetBoolean(prefs::kSyncExtensions));
[email protected]d9e33092011-09-01 03:34:05157 args->SetBoolean("syncSearchEngines",
158 service->profile()->GetPrefs()->GetBoolean(prefs::kSyncSearchEngines));
[email protected]5edb9222010-08-18 00:23:29159 args->SetBoolean("syncSessions",
160 service->profile()->GetPrefs()->GetBoolean(prefs::kSyncSessions));
[email protected]dc9a6762010-08-16 07:13:53161 args->SetBoolean("syncTypedUrls",
[email protected]8c94d632010-06-25 22:38:00162 service->profile()->GetPrefs()->GetBoolean(prefs::kSyncTypedUrls));
[email protected]75b362b2010-08-17 04:18:13163 args->SetBoolean("syncApps",
[email protected]06e33202010-08-16 23:45:15164 service->profile()->GetPrefs()->GetBoolean(prefs::kSyncApps));
[email protected]23ec1802011-05-24 17:40:31165 args->SetBoolean("encryptionEnabled",
[email protected]a57c07c2011-07-20 00:59:13166 !CommandLine::ForCurrentProcess()->HasSwitch(
167 switches::kDisableSyncEncryption));
[email protected]23ec1802011-05-24 17:40:31168
[email protected]794742d2011-09-09 21:44:31169 bool encrypt_all = service->EncryptEverythingEnabled();
170 if (service->encryption_pending())
[email protected]cc10e7c2011-08-06 00:17:50171 encrypt_all = true;
[email protected]23ec1802011-05-24 17:40:31172 args->SetBoolean("encryptAllData", encrypt_all);
[email protected]c976938f2010-10-12 04:55:44173
174 // Load the parameters for the encryption tab.
175 args->SetBoolean("usePassphrase", service->IsUsingSecondaryPassphrase());
[email protected]d6930242011-09-03 01:52:19176
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]202b5642011-09-10 02:04:07183 // 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]c63fa112011-10-06 20:17:15187 user_tried_creating_explicit_passphrase_);
[email protected]202b5642011-09-10 02:04:07188 args->SetBoolean("passphrase_setting_rejected",
[email protected]c63fa112011-10-06 20:17:15189 user_tried_setting_passphrase_);
[email protected]d6930242011-09-03 01:52:19190 }
[email protected]8c94d632010-06-25 22:38:00191}
192
[email protected]7c72ecaf2011-06-15 20:42:47193bool SyncSetupFlow::AttachSyncSetupHandler(SyncSetupFlowHandler* handler) {
194 if (flow_handler_)
195 return false;
196
[email protected]a1595962011-04-22 21:56:24197 flow_handler_ = handler;
[email protected]87d5eb42011-06-14 01:21:25198 handler->SetFlow(this);
[email protected]a1595962011-04-22 21:56:24199 ActivateState(current_state_);
[email protected]7c72ecaf2011-06-15 20:42:47200 return true;
[email protected]a1595962011-04-22 21:56:24201}
202
[email protected]3c9e1092011-08-04 18:41:15203bool SyncSetupFlow::IsAttached() const {
204 return flow_handler_ != NULL;
205}
206
[email protected]a1595962011-04-22 21:56:24207void 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]3c9e1092011-08-04 18:41:15214 if (flow_handler_)
215 ActivateState(advance_state);
[email protected]a1595962011-04-22 21:56:24216}
217
218void SyncSetupFlow::Focus() {
[email protected]6783bdd2011-06-28 23:51:47219 // 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]a1595962011-04-22 21:56:24224}
225
226// A callback to notify the delegate that the dialog closed.
[email protected]6f5fa9f2011-07-28 03:39:57227// TODO(rickcam): Bug 90713: Handle OAUTH_LOGIN case here
[email protected]a1595962011-04-22 21:56:24228void SyncSetupFlow::OnDialogClosed(const std::string& json_retval) {
229 DCHECK(json_retval.empty());
230 container_->set_flow(NULL); // Sever ties from the wizard.
[email protected]7ad97cf2011-07-29 21:42:16231 // 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]a1595962011-04-22 21:56:24234 service_->SetSyncSetupCompleted();
[email protected]a1595962011-04-22 21:56:24235
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]a1595962011-04-22 21:56:24254 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
268void SyncSetupFlow::OnUserSubmittedAuth(const std::string& username,
269 const std::string& password,
270 const std::string& captcha,
271 const std::string& access_code) {
[email protected]a313caa32011-09-09 04:31:05272 // 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]a1595962011-04-22 21:56:24276 service_->OnUserSubmittedAuth(username, password, captcha, access_code);
277}
278
[email protected]934a30792011-09-12 19:15:44279void SyncSetupFlow::OnUserSubmittedOAuth(
280 const std::string& oauth1_request_token) {
281 service_->OnUserSubmittedOAuth(oauth1_request_token);
282}
283
[email protected]a1595962011-04-22 21:56:24284void SyncSetupFlow::OnUserConfigured(const SyncConfiguration& configuration) {
285 // Go to the "loading..." screen.
286 Advance(SyncSetupWizard::SETTING_UP);
287
[email protected]cc10e7c2011-08-06 00:17:50288 // Note: encryption will not occur until OnUserChoseDatatypes is called.
[email protected]794742d2011-09-09 21:44:31289 service_->SetEncryptEverything(configuration.encrypt_all);
[email protected]c63fa112011-10-06 20:17:15290 bool set_new_decryption_passphrase = false;
[email protected]202b5642011-09-10 02:04:07291 if (configuration.set_gaia_passphrase) {
[email protected]1a315b42011-08-04 17:44:18292 // Caller passed a gaia passphrase. This is illegal if we are currently
293 // using a secondary passphrase.
294 DCHECK(!service_->IsUsingSecondaryPassphrase());
[email protected]d6930242011-09-03 01:52:19295 service_->SetPassphrase(configuration.gaia_passphrase, false);
[email protected]202b5642011-09-10 02:04:07296 // Since the user entered the passphrase manually, set this flag so we can
297 // report an error if the passphrase setting failed.
[email protected]c63fa112011-10-06 20:17:15298 user_tried_setting_passphrase_ = true;
299 set_new_decryption_passphrase = true;
[email protected]d6930242011-09-03 01:52:19300 } 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]c63fa112011-10-06 20:17:15305 set_new_decryption_passphrase = true;
[email protected]d6930242011-09-03 01:52:19306 } else {
[email protected]202b5642011-09-10 02:04:07307 // 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]d6930242011-09-03 01:52:19311 // No gaia passphrase cached or set, so make sure the ProfileSyncService
312 // wasn't expecting one.
[email protected]202b5642011-09-10 02:04:07313 DLOG_IF(WARNING, !service_->IsUsingSecondaryPassphrase() &&
314 service_->IsPassphraseRequiredForDecryption()) <<
315 "Google passphrase required but not provided by UI";
[email protected]1a315b42011-08-04 17:44:18316 }
317
[email protected]202b5642011-09-10 02:04:07318 // 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]d6930242011-09-03 01:52:19321 service_->SetPassphrase(configuration.secondary_passphrase, true);
[email protected]c63fa112011-10-06 20:17:15322 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]a1595962011-04-22 21:56:24328 }
329
330 service_->OnUserChoseDatatypes(configuration.sync_everything,
331 configuration.data_types);
[email protected]c63fa112011-10-06 20:17:15332
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]31af458bd2011-10-15 02:37:44337 if (!service_->IsPassphraseRequiredForDecryption() &&
338 !service_->encryption_pending()) {
[email protected]c63fa112011-10-06 20:17:15339 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]a1595962011-04-22 21:56:24347}
348
349void SyncSetupFlow::OnPassphraseEntry(const std::string& passphrase) {
350 Advance(SyncSetupWizard::SETTING_UP);
[email protected]d6930242011-09-03 01:52:19351 service_->SetPassphrase(passphrase, true);
[email protected]c63fa112011-10-06 20:17:15352 user_tried_setting_passphrase_ = true;
[email protected]a1595962011-04-22 21:56:24353}
354
355void 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]a1595962011-04-22 21:56:24364// Use static Run method to get an instance.
365SyncSetupFlow::SyncSetupFlow(SyncSetupWizard::State start_state,
366 SyncSetupWizard::State end_state,
[email protected]a1595962011-04-22 21:56:24367 SyncSetupFlowContainer* container,
368 ProfileSyncService* service)
369 : container_(container),
[email protected]a1595962011-04-22 21:56:24370 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]c63fa112011-10-06 20:17:15375 user_tried_creating_explicit_passphrase_(false),
376 user_tried_setting_passphrase_(false) {
[email protected]132c85652009-08-05 01:18:27377}
378
[email protected]c976938f2010-10-12 04:55:44379// Returns true if the flow should advance to |state| based on |current_state_|.
[email protected]132c85652009-08-05 01:18:27380bool SyncSetupFlow::ShouldAdvance(SyncSetupWizard::State state) {
381 switch (state) {
[email protected]6f5fa9f2011-07-28 03:39:57382 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]132c85652009-08-05 01:18:27386 case SyncSetupWizard::GAIA_LOGIN:
[email protected]8c94d632010-06-25 22:38:00387 return current_state_ == SyncSetupWizard::FATAL_ERROR ||
[email protected]71555642011-02-23 18:51:04388 current_state_ == SyncSetupWizard::GAIA_LOGIN ||
389 current_state_ == SyncSetupWizard::SETTING_UP;
[email protected]132c85652009-08-05 01:18:27390 case SyncSetupWizard::GAIA_SUCCESS:
[email protected]6f5fa9f2011-07-28 03:39:57391 return current_state_ == SyncSetupWizard::GAIA_LOGIN ||
392 current_state_ == SyncSetupWizard::OAUTH_LOGIN;
393 case SyncSetupWizard::SYNC_EVERYTHING: // Intentionally fall through.
[email protected]c976938f2010-10-12 04:55:44394 case SyncSetupWizard::CONFIGURE:
[email protected]8c94d632010-06-25 22:38:00395 return current_state_ == SyncSetupWizard::GAIA_SUCCESS;
[email protected]66d81002010-10-18 16:52:09396 case SyncSetupWizard::ENTER_PASSPHRASE:
[email protected]5d0e7c22011-04-19 23:09:07397 return current_state_ == SyncSetupWizard::SYNC_EVERYTHING ||
398 current_state_ == SyncSetupWizard::CONFIGURE ||
[email protected]66d81002010-10-18 16:52:09399 current_state_ == SyncSetupWizard::SETTING_UP;
[email protected]a47eeb52010-07-15 17:54:25400 case SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR:
[email protected]cb5199b2011-09-04 01:55:52401 return current_state_ != SyncSetupWizard::ABORT;
[email protected]c976938f2010-10-12 04:55:44402 case SyncSetupWizard::SETTING_UP:
[email protected]5d0e7c22011-04-19 23:09:07403 return current_state_ == SyncSetupWizard::SYNC_EVERYTHING ||
404 current_state_ == SyncSetupWizard::CONFIGURE ||
[email protected]5c0ec92f2011-05-09 20:28:52405 current_state_ == SyncSetupWizard::ENTER_PASSPHRASE;
[email protected]6f5fa9f2011-07-28 03:39:57406 case SyncSetupWizard::NONFATAL_ERROR: // Intentionally fall through.
[email protected]fb42c982009-09-16 22:33:33407 case SyncSetupWizard::FATAL_ERROR:
[email protected]cb5199b2011-09-04 01:55:52408 return current_state_ != SyncSetupWizard::ABORT;
409 case SyncSetupWizard::ABORT:
410 return true;
[email protected]132c85652009-08-05 01:18:27411 case SyncSetupWizard::DONE:
[email protected]66d81002010-10-18 16:52:09412 return current_state_ == SyncSetupWizard::SETTING_UP ||
413 current_state_ == SyncSetupWizard::ENTER_PASSPHRASE;
[email protected]132c85652009-08-05 01:18:27414 default:
415 NOTREACHED() << "Unhandled State: " << state;
416 return false;
417 }
418}
419
[email protected]a1595962011-04-22 21:56:24420void SyncSetupFlow::ActivateState(SyncSetupWizard::State state) {
[email protected]7c72ecaf2011-06-15 20:42:47421 DCHECK(flow_handler_);
422
[email protected]87d5eb42011-06-14 01:21:25423 if (state == SyncSetupWizard::NONFATAL_ERROR)
424 state = GetStepForNonFatalError(service_);
425
426 current_state_ = state;
427
[email protected]a1595962011-04-22 21:56:24428 switch (state) {
[email protected]6f5fa9f2011-07-28 03:39:57429 case SyncSetupWizard::OAUTH_LOGIN: {
430 flow_handler_->ShowOAuthLogin();
431 break;
432 }
[email protected]132c85652009-08-05 01:18:27433 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]8c94d632010-06-25 22:38:00440 if (end_state_ == SyncSetupWizard::GAIA_SUCCESS) {
[email protected]132c85652009-08-05 01:18:27441 flow_handler_->ShowGaiaSuccessAndClose();
[email protected]8c94d632010-06-25 22:38:00442 break;
443 }
[email protected]d2c04f22011-06-22 17:39:04444 flow_handler_->ShowGaiaSuccessAndSettingUp();
445 break;
[email protected]5d0e7c22011-04-19 23:09:07446 case SyncSetupWizard::SYNC_EVERYTHING: {
447 DictionaryValue args;
448 SyncSetupFlow::GetArgsForConfigure(service_, &args);
[email protected]56e2a4402011-05-05 18:49:49449 args.SetBoolean("showSyncEverythingPage", true);
[email protected]5d0e7c22011-04-19 23:09:07450 flow_handler_->ShowConfigure(args);
451 break;
452 }
[email protected]c976938f2010-10-12 04:55:44453 case SyncSetupWizard::CONFIGURE: {
[email protected]8c94d632010-06-25 22:38:00454 DictionaryValue args;
[email protected]c976938f2010-10-12 04:55:44455 SyncSetupFlow::GetArgsForConfigure(service_, &args);
[email protected]c976938f2010-10-12 04:55:44456 flow_handler_->ShowConfigure(args);
457 break;
458 }
[email protected]c976938f2010-10-12 04:55:44459 case SyncSetupWizard::ENTER_PASSPHRASE: {
460 DictionaryValue args;
[email protected]503ff1252011-06-01 20:36:24461 SyncSetupFlow::GetArgsForConfigure(service_, &args);
[email protected]d6930242011-09-03 01:52:19462 GetArgsForConfigure(service_, &args);
463 // TODO(atwilson): Remove ShowPassphraseEntry in favor of using
464 // ShowConfigure() - http://crbug.com/90786.
[email protected]c976938f2010-10-12 04:55:44465 flow_handler_->ShowPassphraseEntry(args);
[email protected]132c85652009-08-05 01:18:27466 break;
[email protected]8c94d632010-06-25 22:38:00467 }
[email protected]a47eeb52010-07-15 17:54:25468 case SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR: {
[email protected]41bd81eb92011-10-10 20:17:53469 // 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]a47eeb52010-07-15 17:54:25472 DictionaryValue args;
[email protected]d898dc972011-09-15 21:54:01473 SyncSetupFlow::GetArgsForGaiaLogin(service_, &args);
474 args.SetInteger("error", GoogleServiceAuthError::SERVICE_UNAVAILABLE);
[email protected]41bd81eb92011-10-10 20:17:53475 current_state_ = SyncSetupWizard::GAIA_LOGIN;
[email protected]d898dc972011-09-15 21:54:01476 flow_handler_->ShowGaiaLogin(args);
[email protected]c976938f2010-10-12 04:55:44477 break;
478 }
479 case SyncSetupWizard::SETTING_UP: {
480 flow_handler_->ShowSettingUp();
[email protected]a47eeb52010-07-15 17:54:25481 break;
482 }
[email protected]2be7bf22010-04-23 21:02:37483 case SyncSetupWizard::FATAL_ERROR: {
484 // This shows the user the "Could not connect to server" error.
[email protected]b862fc8b2011-08-17 17:59:24485 // TODO(sync): Update this error handling to allow different platforms to
486 // display the error appropriately (http://crbug.com/92722).
[email protected]2be7bf22010-04-23 21:02:37487 DictionaryValue args;
488 SyncSetupFlow::GetArgsForGaiaLogin(service_, &args);
[email protected]349f9bc2011-10-06 18:52:02489 args.SetBoolean("fatalError", true);
[email protected]41bd81eb92011-10-10 20:17:53490 current_state_ = SyncSetupWizard::GAIA_LOGIN;
[email protected]2be7bf22010-04-23 21:02:37491 flow_handler_->ShowGaiaLogin(args);
[email protected]fb42c982009-09-16 22:33:33492 break;
[email protected]2be7bf22010-04-23 21:02:37493 }
[email protected]132c85652009-08-05 01:18:27494 case SyncSetupWizard::DONE:
[email protected]cb5199b2011-09-04 01:55:52495 case SyncSetupWizard::ABORT:
[email protected]d80033e2009-10-16 10:32:04496 flow_handler_->ShowSetupDone(
497 UTF16ToWide(service_->GetAuthenticatedUsername()));
[email protected]132c85652009-08-05 01:18:27498 break;
499 default:
[email protected]a1595962011-04-22 21:56:24500 NOTREACHED() << "Invalid advance state: " << state;
[email protected]132c85652009-08-05 01:18:27501 }
[email protected]22d3eff2011-01-08 01:45:18502}