OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/ui/webui/options/sync_setup_handler.h" | |
6 | |
7 #include "base/json/json_reader.h" | |
8 #include "base/json/json_writer.h" | |
9 #include "base/values.h" | |
10 #include "chrome/browser/google/google_util.h" | |
11 #include "chrome/browser/profiles/profile.h" | |
12 #include "chrome/browser/sync/profile_sync_service.h" | |
13 #include "chrome/browser/sync/sync_setup_flow.h" | |
14 #include "chrome/common/url_constants.h" | |
15 #include "content/browser/tab_contents/tab_contents.h" | |
16 #include "grit/chromium_strings.h" | |
17 #include "grit/generated_resources.h" | |
18 #include "grit/locale_settings.h" | |
19 #include "ui/base/l10n/l10n_util.h" | |
20 | |
21 using l10n_util::GetStringFUTF16; | |
22 using l10n_util::GetStringUTF16; | |
23 | |
24 namespace { | |
25 | |
26 // TODO(jhawkins): Move these to url_constants.h. | |
27 const char* kInvalidPasswordHelpUrl = | |
28 "http://www.google.com/support/accounts/bin/answer.py?ctx=ch&answer=27444"; | |
29 const char* kCanNotAccessAccountUrl = | |
30 "http://www.google.com/support/accounts/bin/answer.py?answer=48598"; | |
31 #if defined(OS_CHROMEOS) | |
32 const char* kEncryptionHelpUrl = | |
33 "http://www.google.com/support/chromeos/bin/answer.py?answer=1181035"; | |
34 #else | |
35 const char* kEncryptionHelpUrl = | |
36 "http://www.google.com/support/chrome/bin/answer.py?answer=1181035"; | |
37 #endif | |
38 const char* kCreateNewAccountUrl = | |
39 "https://www.google.com/accounts/NewAccount?service=chromiumsync"; | |
40 | |
41 bool GetAuthData(const std::string& json, | |
42 std::string* username, | |
43 std::string* password, | |
44 std::string* captcha, | |
45 std::string* access_code) { | |
46 scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false)); | |
47 if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY)) | |
48 return false; | |
49 | |
50 DictionaryValue* result = static_cast<DictionaryValue*>(parsed_value.get()); | |
51 if (!result->GetString("user", username) || | |
52 !result->GetString("pass", password) || | |
53 !result->GetString("captcha", captcha) || | |
54 !result->GetString("access_code", access_code)) { | |
55 return false; | |
56 } | |
57 return true; | |
58 } | |
59 | |
60 bool GetConfiguration(const std::string& json, SyncConfiguration* config) { | |
61 scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false)); | |
62 if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY)) | |
63 return false; | |
64 | |
65 DictionaryValue* result = static_cast<DictionaryValue*>(parsed_value.get()); | |
66 if (!result->GetBoolean("keepEverythingSynced", &config->sync_everything)) | |
67 return false; | |
68 | |
69 // These values need to be kept in sync with where they are written in | |
70 // choose_datatypes.html. | |
71 bool sync_bookmarks; | |
72 if (!result->GetBoolean("syncBookmarks", &sync_bookmarks)) | |
73 return false; | |
74 if (sync_bookmarks) | |
75 config->data_types.insert(syncable::BOOKMARKS); | |
76 | |
77 bool sync_preferences; | |
78 if (!result->GetBoolean("syncPreferences", &sync_preferences)) | |
79 return false; | |
80 if (sync_preferences) | |
81 config->data_types.insert(syncable::PREFERENCES); | |
82 | |
83 bool sync_themes; | |
84 if (!result->GetBoolean("syncThemes", &sync_themes)) | |
85 return false; | |
86 if (sync_themes) | |
87 config->data_types.insert(syncable::THEMES); | |
88 | |
89 bool sync_passwords; | |
90 if (!result->GetBoolean("syncPasswords", &sync_passwords)) | |
91 return false; | |
92 if (sync_passwords) | |
93 config->data_types.insert(syncable::PASSWORDS); | |
94 | |
95 bool sync_autofill; | |
96 if (!result->GetBoolean("syncAutofill", &sync_autofill)) | |
97 return false; | |
98 if (sync_autofill) | |
99 config->data_types.insert(syncable::AUTOFILL); | |
100 | |
101 bool sync_extensions; | |
102 if (!result->GetBoolean("syncExtensions", &sync_extensions)) | |
103 return false; | |
104 if (sync_extensions) | |
105 config->data_types.insert(syncable::EXTENSIONS); | |
106 | |
107 bool sync_typed_urls; | |
108 if (!result->GetBoolean("syncTypedUrls", &sync_typed_urls)) | |
109 return false; | |
110 if (sync_typed_urls) | |
111 config->data_types.insert(syncable::TYPED_URLS); | |
112 | |
113 bool sync_sessions; | |
114 if (!result->GetBoolean("syncSessions", &sync_sessions)) | |
115 return false; | |
116 if (sync_sessions) | |
117 config->data_types.insert(syncable::SESSIONS); | |
118 | |
119 bool sync_apps; | |
120 if (!result->GetBoolean("syncApps", &sync_apps)) | |
121 return false; | |
122 if (sync_apps) | |
123 config->data_types.insert(syncable::APPS); | |
124 | |
125 // Encryption settings. | |
126 if (!result->GetBoolean("encryptAllData", &config->encrypt_all)) | |
127 return false; | |
128 | |
129 // Passphrase settings. | |
130 if (!result->GetBoolean("usePassphrase", &config->use_secondary_passphrase)) | |
131 return false; | |
132 if (config->use_secondary_passphrase && | |
133 !result->GetString("passphrase", &config->secondary_passphrase)) | |
134 return false; | |
135 | |
136 return true; | |
137 } | |
138 | |
139 bool GetPassphrase(const std::string& json, std::string* passphrase) { | |
140 scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false)); | |
141 if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY)) | |
142 return false; | |
143 | |
144 DictionaryValue* result = static_cast<DictionaryValue*>(parsed_value.get()); | |
145 return result->GetString("passphrase", passphrase); | |
146 } | |
147 | |
148 } // namespace | |
149 | |
150 SyncSetupHandler::SyncSetupHandler() : flow_(NULL) { | |
151 } | |
152 | |
153 SyncSetupHandler::~SyncSetupHandler() { | |
154 // This case is hit when the user performs a back navigation. | |
155 if (flow_) | |
156 flow_->OnDialogClosed(""); | |
157 } | |
158 | |
159 void SyncSetupHandler::GetLocalizedValues(DictionaryValue* localized_strings) { | |
160 DCHECK(localized_strings); | |
161 | |
162 localized_strings->SetString( | |
163 "invalidPasswordHelpURL", | |
164 google_util::StringAppendGoogleLocaleParam(kInvalidPasswordHelpUrl)); | |
165 localized_strings->SetString( | |
166 "cannotAccessAccountURL", | |
167 google_util::StringAppendGoogleLocaleParam(kCanNotAccessAccountUrl)); | |
168 localized_strings->SetString( | |
169 "createNewAccountURL", | |
170 google_util::StringAppendGoogleLocaleParam(kCreateNewAccountUrl)); | |
171 localized_strings->SetString( | |
172 "introduction", | |
173 GetStringFUTF16(IDS_SYNC_LOGIN_INTRODUCTION, | |
174 GetStringUTF16(IDS_PRODUCT_NAME))); | |
175 localized_strings->SetString( | |
176 "chooseDataTypesInstructions", | |
177 GetStringFUTF16(IDS_SYNC_CHOOSE_DATATYPES_INSTRUCTIONS, | |
178 GetStringUTF16(IDS_PRODUCT_NAME))); | |
179 localized_strings->SetString( | |
180 "encryptionInstructions", | |
181 GetStringFUTF16(IDS_SYNC_ENCRYPTION_INSTRUCTIONS, | |
182 GetStringUTF16(IDS_PRODUCT_NAME))); | |
183 localized_strings->SetString( | |
184 "encryptionHelpURL", | |
185 google_util::StringAppendGoogleLocaleParam(kEncryptionHelpUrl)); | |
186 localized_strings->SetString( | |
187 "passphraseEncryptionMessage", | |
188 GetStringFUTF16(IDS_SYNC_PASSPHRASE_ENCRYPTION_MESSAGE, | |
189 GetStringUTF16(IDS_PRODUCT_NAME))); | |
190 localized_strings->SetString( | |
191 "passphraseRecover", | |
192 GetStringFUTF16(IDS_SYNC_PASSPHRASE_RECOVER, | |
193 ASCIIToUTF16(google_util::StringAppendGoogleLocaleParam( | |
194 chrome::kSyncGoogleDashboardURL)))); | |
195 | |
196 static OptionsStringResource resources[] = { | |
197 { "syncSetupOverlayTitle", IDS_SYNC_SETUP_TITLE }, | |
198 { "syncSetupConfigureTitle", IDS_SYNC_SETUP_CONFIGURE_TITLE }, | |
199 { "signinPrefix", IDS_SYNC_LOGIN_SIGNIN_PREFIX }, | |
200 { "signinSuffix", IDS_SYNC_LOGIN_SIGNIN_SUFFIX }, | |
201 { "cannotBeBlank", IDS_SYNC_CANNOT_BE_BLANK }, | |
202 { "emailLabel", IDS_SYNC_LOGIN_EMAIL }, | |
203 { "passwordLabel", IDS_SYNC_LOGIN_PASSWORD }, | |
204 { "invalidCredentials", IDS_SYNC_INVALID_USER_CREDENTIALS }, | |
205 { "signin", IDS_SYNC_SIGNIN }, | |
206 { "couldNotConnect", IDS_SYNC_LOGIN_COULD_NOT_CONNECT }, | |
207 { "cannotAccessAccount", IDS_SYNC_CANNOT_ACCESS_ACCOUNT }, | |
208 { "createAccount", IDS_SYNC_CREATE_ACCOUNT }, | |
209 { "cancel", IDS_CANCEL }, | |
210 { "settingUp", IDS_SYNC_LOGIN_SETTING_UP }, | |
211 { "errorSigningIn", IDS_SYNC_ERROR_SIGNING_IN }, | |
212 { "captchaInstructions", IDS_SYNC_GAIA_CAPTCHA_INSTRUCTIONS }, | |
213 { "invalidAccessCode", IDS_SYNC_INVALID_ACCESS_CODE_LABEL }, | |
214 { "enterAccessCode", IDS_SYNC_ENTER_ACCESS_CODE_LABEL }, | |
215 { "getAccessCodeHelp", IDS_SYNC_ACCESS_CODE_HELP_LABEL }, | |
216 { "getAccessCodeURL", IDS_SYNC_GET_ACCESS_CODE_URL }, | |
217 { "keepEverythingSynced", IDS_SYNC_EVERYTHING }, | |
218 { "chooseDataTypes", IDS_SYNC_CHOOSE_DATATYPES }, | |
219 { "bookmarks", IDS_SYNC_DATATYPE_BOOKMARKS }, | |
220 { "preferences", IDS_SYNC_DATATYPE_PREFERENCES }, | |
221 { "autofill", IDS_SYNC_DATATYPE_AUTOFILL }, | |
222 { "themes", IDS_SYNC_DATATYPE_THEMES }, | |
223 { "passwords", IDS_SYNC_DATATYPE_PASSWORDS }, | |
224 { "extensions", IDS_SYNC_DATATYPE_EXTENSIONS }, | |
225 { "typedURLs", IDS_SYNC_DATATYPE_TYPED_URLS }, | |
226 { "apps", IDS_SYNC_DATATYPE_APPS }, | |
227 { "foreignSessions", IDS_SYNC_DATATYPE_SESSIONS }, | |
228 { "syncZeroDataTypesError", IDS_SYNC_ZERO_DATA_TYPES_ERROR }, | |
229 { "abortedError", IDS_SYNC_SETUP_ABORTED_BY_PENDING_CLEAR }, | |
230 { "encryptAllLabel", IDS_SYNC_ENCRYPT_ALL_LABEL }, | |
231 { "googleOption", IDS_SYNC_PASSPHRASE_OPT_GOOGLE }, | |
232 { "explicitOption", IDS_SYNC_PASSPHRASE_OPT_EXPLICIT }, | |
233 { "sectionGoogleMessage", IDS_SYNC_PASSPHRASE_MSG_GOOGLE }, | |
234 { "sectionExplicitMessage", IDS_SYNC_PASSPHRASE_MSG_EXPLICIT }, | |
235 { "passphraseLabel", IDS_SYNC_PASSPHRASE_LABEL }, | |
236 { "confirmLabel", IDS_SYNC_CONFIRM_PASSPHRASE_LABEL }, | |
237 { "emptyErrorMessage", IDS_SYNC_EMPTY_PASSPHRASE_ERROR }, | |
238 { "mismatchErrorMessage", IDS_SYNC_PASSPHRASE_MISMATCH_ERROR }, | |
239 { "passphraseWarning", IDS_SYNC_PASSPHRASE_WARNING }, | |
240 { "customizeLinkLabel", IDS_SYNC_CUSTOMIZE_LINK_LABEL }, | |
241 { "confirmSyncPreferences", IDS_SYNC_CONFIRM_SYNC_PREFERENCES }, | |
242 { "syncEverything", IDS_SYNC_SYNC_EVERYTHING }, | |
243 { "useDefaultSettings", IDS_SYNC_USE_DEFAULT_SETTINGS }, | |
244 { "passphraseSectionTitle", IDS_SYNC_PASSPHRASE_SECTION_TITLE }, | |
245 { "privacyDashboardLink", IDS_SYNC_PRIVACY_DASHBOARD_LINK_LABEL }, | |
246 { "enterPassphraseTitle", IDS_SYNC_ENTER_PASSPHRASE_TITLE }, | |
247 { "enterPassphraseBody", IDS_SYNC_ENTER_PASSPHRASE_BODY }, | |
248 { "enterOtherPassphraseBody", IDS_SYNC_ENTER_OTHER_PASSPHRASE_BODY }, | |
249 { "passphraseLabel", IDS_SYNC_PASSPHRASE_LABEL }, | |
250 { "incorrectPassphrase", IDS_SYNC_INCORRECT_PASSPHRASE }, | |
251 { "passphraseWarning", IDS_SYNC_PASSPHRASE_WARNING }, | |
252 { "cancelWarningHeader", IDS_SYNC_PASSPHRASE_CANCEL_WARNING_HEADER }, | |
253 { "cancelWarning", IDS_SYNC_PASSPHRASE_CANCEL_WARNING }, | |
254 { "yes", IDS_SYNC_PASSPHRASE_CANCEL_YES }, | |
255 { "no", IDS_SYNC_PASSPHRASE_CANCEL_NO }, | |
256 { "sectionExplicitMessagePrefix", IDS_SYNC_PASSPHRASE_MSG_EXPLICIT_PREFIX }, | |
257 { "sectionExplicitMessagePostfix", | |
258 IDS_SYNC_PASSPHRASE_MSG_EXPLICIT_POSTFIX }, | |
259 { "encryptedDataTypesTitle", IDS_SYNC_ENCRYPTION_DATA_TYPES_TITLE }, | |
260 { "encryptSensitiveOption", IDS_SYNC_ENCRYPT_SENSITIVE_DATA }, | |
261 { "encryptAllOption", IDS_SYNC_ENCRYPT_ALL_DATA }, | |
262 }; | |
263 | |
264 RegisterStrings(localized_strings, resources, arraysize(resources)); | |
265 } | |
266 | |
267 void SyncSetupHandler::Initialize() { | |
268 } | |
269 | |
270 void SyncSetupHandler::RegisterMessages() { | |
271 web_ui_->RegisterMessageCallback("SyncSetupDidClosePage", | |
272 NewCallback(this, &SyncSetupHandler::OnDidClosePage)); | |
273 web_ui_->RegisterMessageCallback("SyncSetupSubmitAuth", | |
274 NewCallback(this, &SyncSetupHandler::HandleSubmitAuth)); | |
275 web_ui_->RegisterMessageCallback("SyncSetupConfigure", | |
276 NewCallback(this, &SyncSetupHandler::HandleConfigure)); | |
277 web_ui_->RegisterMessageCallback("SyncSetupPassphrase", | |
278 NewCallback(this, &SyncSetupHandler::HandlePassphraseEntry)); | |
279 web_ui_->RegisterMessageCallback("SyncSetupPassphraseCancel", | |
280 NewCallback(this, &SyncSetupHandler::HandlePassphraseCancel)); | |
281 web_ui_->RegisterMessageCallback("SyncSetupAttachHandler", | |
282 NewCallback(this, &SyncSetupHandler::HandleAttachHandler)); | |
283 web_ui_->RegisterMessageCallback("SyncSetupShowErrorUI", | |
284 NewCallback(this, &SyncSetupHandler::HandleShowErrorUI)); | |
285 web_ui_->RegisterMessageCallback("SyncSetupShowSetupUI", | |
286 NewCallback(this, &SyncSetupHandler::HandleShowSetupUI)); | |
287 } | |
288 | |
289 void SyncSetupHandler::ShowGaiaLogin(const DictionaryValue& args) { | |
290 StringValue page("login"); | |
291 web_ui_->CallJavascriptFunction( | |
292 "SyncSetupOverlay.showSyncSetupPage", page, args); | |
293 } | |
294 | |
295 void SyncSetupHandler::ShowGaiaSuccessAndClose() { | |
296 web_ui_->CallJavascriptFunction("SyncSetupOverlay.showSuccessAndClose"); | |
297 } | |
298 | |
299 void SyncSetupHandler::ShowGaiaSuccessAndSettingUp() { | |
300 web_ui_->CallJavascriptFunction("SyncSetupOverlay.showSuccessAndSettingUp"); | |
301 } | |
302 | |
303 void SyncSetupHandler::ShowConfigure(const DictionaryValue& args) { | |
304 StringValue page("configure"); | |
305 web_ui_->CallJavascriptFunction( | |
306 "SyncSetupOverlay.showSyncSetupPage", page, args); | |
307 } | |
308 | |
309 void SyncSetupHandler::ShowPassphraseEntry(const DictionaryValue& args) { | |
310 StringValue page("passphrase"); | |
311 web_ui_->CallJavascriptFunction( | |
312 "SyncSetupOverlay.showSyncSetupPage", page, args); | |
313 } | |
314 | |
315 void SyncSetupHandler::ShowSettingUp() { | |
316 StringValue page("settingUp"); | |
317 web_ui_->CallJavascriptFunction( | |
318 "SyncSetupOverlay.showSyncSetupPage", page); | |
319 } | |
320 | |
321 void SyncSetupHandler::ShowSetupDone(const std::wstring& user) { | |
322 StringValue page("done"); | |
323 web_ui_->CallJavascriptFunction( | |
324 "SyncSetupOverlay.showSyncSetupPage", page); | |
325 } | |
326 | |
327 void SyncSetupHandler::SetFlow(SyncSetupFlow* flow) { | |
328 flow_ = flow; | |
329 } | |
330 | |
331 void SyncSetupHandler::Focus() { | |
332 static_cast<RenderViewHostDelegate*>(web_ui_->tab_contents())->Activate(); | |
333 } | |
334 | |
335 void SyncSetupHandler::OnDidClosePage(const ListValue* args) { | |
336 if (flow_) { | |
337 flow_->OnDialogClosed(std::string()); | |
338 flow_ = NULL; | |
339 } | |
340 } | |
341 | |
342 void SyncSetupHandler::HandleSubmitAuth(const ListValue* args) { | |
343 std::string json; | |
344 if (!args->GetString(0, &json)) { | |
345 NOTREACHED() << "Could not read JSON argument"; | |
346 return; | |
347 } | |
348 | |
349 if (json.empty()) | |
350 return; | |
351 | |
352 std::string username, password, captcha, access_code; | |
353 if (!GetAuthData(json, &username, &password, &captcha, &access_code)) { | |
354 // The page sent us something that we didn't understand. | |
355 // This probably indicates a programming error. | |
356 NOTREACHED(); | |
357 return; | |
358 } | |
359 | |
360 if (flow_) | |
361 flow_->OnUserSubmittedAuth(username, password, captcha, access_code); | |
362 } | |
363 | |
364 void SyncSetupHandler::HandleConfigure(const ListValue* args) { | |
365 std::string json; | |
366 if (!args->GetString(0, &json)) { | |
367 NOTREACHED() << "Could not read JSON argument"; | |
368 return; | |
369 } | |
370 if (json.empty()) { | |
371 NOTREACHED(); | |
372 return; | |
373 } | |
374 | |
375 SyncConfiguration configuration; | |
376 if (!GetConfiguration(json, &configuration)) { | |
377 // The page sent us something that we didn't understand. | |
378 // This probably indicates a programming error. | |
379 NOTREACHED(); | |
380 return; | |
381 } | |
382 | |
383 DCHECK(flow_); | |
384 flow_->OnUserConfigured(configuration); | |
385 } | |
386 | |
387 void SyncSetupHandler::HandlePassphraseEntry(const ListValue* args) { | |
388 std::string json; | |
389 if (!args->GetString(0, &json)) { | |
390 NOTREACHED() << "Could not read JSON argument"; | |
391 return; | |
392 } | |
393 | |
394 if (json.empty()) | |
395 return; | |
396 | |
397 std::string passphrase; | |
398 if (!GetPassphrase(json, &passphrase)) { | |
399 // Couldn't understand what the page sent. Indicates a programming error. | |
400 NOTREACHED(); | |
401 return; | |
402 } | |
403 | |
404 DCHECK(flow_); | |
405 flow_->OnPassphraseEntry(passphrase); | |
406 } | |
407 | |
408 void SyncSetupHandler::HandlePassphraseCancel(const ListValue* args) { | |
409 DCHECK(flow_); | |
410 flow_->OnPassphraseCancel(); | |
411 } | |
412 | |
413 void SyncSetupHandler::HandleAttachHandler(const ListValue* args) { | |
414 DCHECK(web_ui_); | |
415 DCHECK(!flow_); | |
416 | |
417 ProfileSyncService* service = web_ui_->GetProfile()->GetProfileSyncService(); | |
418 if (!service) { | |
419 // If there's no sync service, the user tried to manually invoke a syncSetup | |
420 // URL, but sync features are disabled. We need to close the overlay for | |
421 // this (rare) case. | |
422 web_ui_->CallJavascriptFunction("OptionsPage.closeOverlay"); | |
423 return; | |
424 } | |
425 | |
426 // If the wizard is not visible, step into the appropriate UI state. | |
427 if (!service->get_wizard().IsVisible()) | |
428 HandleShowSetupUI(NULL); | |
429 | |
430 // The SyncSetupFlow will set itself as the |flow_|. | |
431 if (!service->get_wizard().AttachSyncSetupHandler(this)) { | |
432 // If attach fails, a wizard is already activated and attached to a flow | |
433 // handler. | |
434 web_ui_->CallJavascriptFunction("OptionsPage.closeOverlay"); | |
435 service->get_wizard().Focus(); | |
436 } | |
437 } | |
438 | |
439 void SyncSetupHandler::HandleShowErrorUI(const ListValue* args) { | |
440 DCHECK(!flow_); | |
441 | |
442 ProfileSyncService* service = | |
443 web_ui_->GetProfile()->GetProfileSyncService(); | |
444 DCHECK(service); | |
445 | |
446 service->get_wizard().Step(SyncSetupWizard::NONFATAL_ERROR); | |
447 | |
448 // The SyncSetupFlow will set itself as the |flow_|. | |
449 if (!service->get_wizard().AttachSyncSetupHandler(this)) { | |
450 web_ui_->CallJavascriptFunction("OptionsPage.closeOverlay"); | |
451 service->get_wizard().Focus(); | |
452 } | |
453 } | |
454 | |
455 void SyncSetupHandler::HandleShowSetupUI(const ListValue* args) { | |
456 DCHECK(!flow_); | |
457 | |
458 ProfileSyncService* service = | |
459 web_ui_->GetProfile()->GetProfileSyncService(); | |
460 DCHECK(service); | |
461 | |
462 // If the wizard is already visible, focus it. | |
463 if (service->get_wizard().IsVisible()) { | |
464 web_ui_->CallJavascriptFunction("OptionsPage.closeOverlay"); | |
465 service->get_wizard().Focus(); | |
466 return; | |
467 } | |
468 | |
469 // The user is trying to manually load a syncSetup URL. We should bring up | |
470 // either a login or a configure flow based on the state of sync. | |
471 if (service->HasSyncSetupCompleted()) | |
472 service->get_wizard().Step(SyncSetupWizard::CONFIGURE); | |
473 else | |
474 service->get_wizard().Step(SyncSetupWizard::GAIA_LOGIN); | |
475 | |
476 // Show the Sync Setup page. | |
477 scoped_ptr<Value> page(Value::CreateStringValue("syncSetup")); | |
478 web_ui_->CallJavascriptFunction("OptionsPage.navigateToPage", *page); | |
479 } | |
OLD | NEW |