| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/webui/options/sync_setup_handler.h" | |
| 6 | |
| 7 #include "base/basictypes.h" | |
| 8 #include "base/bind.h" | |
| 9 #include "base/bind_helpers.h" | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/compiler_specific.h" | |
| 12 #include "base/i18n/time_formatting.h" | |
| 13 #include "base/json/json_reader.h" | |
| 14 #include "base/json/json_writer.h" | |
| 15 #include "base/metrics/histogram.h" | |
| 16 #include "base/prefs/pref_service.h" | |
| 17 #include "base/strings/utf_string_conversions.h" | |
| 18 #include "base/values.h" | |
| 19 #include "chrome/app/chrome_command_ids.h" | |
| 20 #include "chrome/browser/browser_process.h" | |
| 21 #include "chrome/browser/lifetime/application_lifetime.h" | |
| 22 #include "chrome/browser/profiles/profile.h" | |
| 23 #include "chrome/browser/profiles/profile_info_cache.h" | |
| 24 #include "chrome/browser/profiles/profile_metrics.h" | |
| 25 #include "chrome/browser/signin/chrome_signin_helper.h" | |
| 26 #include "chrome/browser/signin/signin_error_controller_factory.h" | |
| 27 #include "chrome/browser/signin/signin_manager_factory.h" | |
| 28 #include "chrome/browser/signin/signin_promo.h" | |
| 29 #include "chrome/browser/sync/profile_sync_service.h" | |
| 30 #include "chrome/browser/sync/profile_sync_service_factory.h" | |
| 31 #include "chrome/browser/ui/browser_finder.h" | |
| 32 #include "chrome/browser/ui/browser_window.h" | |
| 33 #include "chrome/browser/ui/singleton_tabs.h" | |
| 34 #include "chrome/browser/ui/webui/options/options_handlers_helper.h" | |
| 35 #include "chrome/browser/ui/webui/signin/login_ui_service.h" | |
| 36 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" | |
| 37 #include "chrome/common/chrome_switches.h" | |
| 38 #include "chrome/common/url_constants.h" | |
| 39 #include "chrome/grit/chromium_strings.h" | |
| 40 #include "chrome/grit/generated_resources.h" | |
| 41 #include "chrome/grit/locale_settings.h" | |
| 42 #include "components/google/core/browser/google_util.h" | |
| 43 #include "components/signin/core/browser/signin_error_controller.h" | |
| 44 #include "components/signin/core/browser/signin_header_helper.h" | |
| 45 #include "components/signin/core/browser/signin_metrics.h" | |
| 46 #include "components/signin/core/common/profile_management_switches.h" | |
| 47 #include "components/sync_driver/sync_prefs.h" | |
| 48 #include "content/public/browser/render_view_host.h" | |
| 49 #include "content/public/browser/web_contents.h" | |
| 50 #include "content/public/browser/web_contents_delegate.h" | |
| 51 #include "google_apis/gaia/gaia_auth_util.h" | |
| 52 #include "google_apis/gaia/gaia_constants.h" | |
| 53 #include "grit/components_strings.h" | |
| 54 #include "net/base/url_util.h" | |
| 55 #include "ui/base/l10n/l10n_util.h" | |
| 56 | |
| 57 #if defined(OS_CHROMEOS) | |
| 58 #include "components/signin/core/browser/signin_manager_base.h" | |
| 59 #else | |
| 60 #include "components/signin/core/browser/signin_manager.h" | |
| 61 #endif | |
| 62 | |
| 63 using content::WebContents; | |
| 64 using l10n_util::GetStringFUTF16; | |
| 65 using l10n_util::GetStringUTF16; | |
| 66 | |
| 67 namespace { | |
| 68 | |
| 69 // A structure which contains all the configuration information for sync. | |
| 70 struct SyncConfigInfo { | |
| 71 SyncConfigInfo(); | |
| 72 ~SyncConfigInfo(); | |
| 73 | |
| 74 bool encrypt_all; | |
| 75 bool sync_everything; | |
| 76 bool sync_nothing; | |
| 77 syncer::ModelTypeSet data_types; | |
| 78 std::string passphrase; | |
| 79 bool passphrase_is_gaia; | |
| 80 }; | |
| 81 | |
| 82 SyncConfigInfo::SyncConfigInfo() | |
| 83 : encrypt_all(false), | |
| 84 sync_everything(false), | |
| 85 sync_nothing(false), | |
| 86 passphrase_is_gaia(false) { | |
| 87 } | |
| 88 | |
| 89 SyncConfigInfo::~SyncConfigInfo() {} | |
| 90 | |
| 91 bool GetConfiguration(const std::string& json, SyncConfigInfo* config) { | |
| 92 scoped_ptr<base::Value> parsed_value = base::JSONReader::Read(json); | |
| 93 base::DictionaryValue* result; | |
| 94 if (!parsed_value || !parsed_value->GetAsDictionary(&result)) { | |
| 95 DLOG(ERROR) << "GetConfiguration() not passed a Dictionary"; | |
| 96 return false; | |
| 97 } | |
| 98 | |
| 99 if (!result->GetBoolean("syncAllDataTypes", &config->sync_everything)) { | |
| 100 DLOG(ERROR) << "GetConfiguration() not passed a syncAllDataTypes value"; | |
| 101 return false; | |
| 102 } | |
| 103 | |
| 104 if (!result->GetBoolean("syncNothing", &config->sync_nothing)) { | |
| 105 DLOG(ERROR) << "GetConfiguration() not passed a syncNothing value"; | |
| 106 return false; | |
| 107 } | |
| 108 | |
| 109 DCHECK(!(config->sync_everything && config->sync_nothing)) | |
| 110 << "syncAllDataTypes and syncNothing cannot both be true"; | |
| 111 | |
| 112 syncer::ModelTypeNameMap type_names = syncer::GetUserSelectableTypeNameMap(); | |
| 113 | |
| 114 for (syncer::ModelTypeNameMap::const_iterator it = type_names.begin(); | |
| 115 it != type_names.end(); ++it) { | |
| 116 std::string key_name = it->second + std::string("Synced"); | |
| 117 bool sync_value; | |
| 118 if (!result->GetBoolean(key_name, &sync_value)) { | |
| 119 DLOG(ERROR) << "GetConfiguration() not passed a value for " << key_name; | |
| 120 return false; | |
| 121 } | |
| 122 if (sync_value) | |
| 123 config->data_types.Put(it->first); | |
| 124 } | |
| 125 | |
| 126 // Encryption settings. | |
| 127 if (!result->GetBoolean("encryptAllData", &config->encrypt_all)) { | |
| 128 DLOG(ERROR) << "GetConfiguration() not passed a value for encryptAllData"; | |
| 129 return false; | |
| 130 } | |
| 131 | |
| 132 // Passphrase settings. | |
| 133 bool have_passphrase; | |
| 134 if (!result->GetBoolean("usePassphrase", &have_passphrase)) { | |
| 135 DLOG(ERROR) << "GetConfiguration() not passed a usePassphrase value"; | |
| 136 return false; | |
| 137 } | |
| 138 | |
| 139 if (have_passphrase) { | |
| 140 if (!result->GetBoolean("isGooglePassphrase", | |
| 141 &config->passphrase_is_gaia)) { | |
| 142 DLOG(ERROR) << "GetConfiguration() not passed isGooglePassphrase value"; | |
| 143 return false; | |
| 144 } | |
| 145 if (!result->GetString("passphrase", &config->passphrase)) { | |
| 146 DLOG(ERROR) << "GetConfiguration() not passed a passphrase value"; | |
| 147 return false; | |
| 148 } | |
| 149 } | |
| 150 return true; | |
| 151 } | |
| 152 | |
| 153 } // namespace | |
| 154 | |
| 155 SyncSetupHandler::SyncSetupHandler() | |
| 156 : configuring_sync_(false) { | |
| 157 } | |
| 158 | |
| 159 SyncSetupHandler::~SyncSetupHandler() { | |
| 160 // Just exit if running unit tests (no actual WebUI is attached). | |
| 161 if (!web_ui()) | |
| 162 return; | |
| 163 | |
| 164 // This case is hit when the user performs a back navigation. | |
| 165 CloseSyncSetup(); | |
| 166 } | |
| 167 | |
| 168 void SyncSetupHandler::GetLocalizedValues( | |
| 169 base::DictionaryValue* localized_strings) { | |
| 170 GetStaticLocalizedValues(localized_strings, web_ui()); | |
| 171 } | |
| 172 | |
| 173 void SyncSetupHandler::GetStaticLocalizedValues( | |
| 174 base::DictionaryValue* localized_strings, | |
| 175 content::WebUI* web_ui) { | |
| 176 DCHECK(localized_strings); | |
| 177 | |
| 178 base::string16 product_name(GetStringUTF16(IDS_PRODUCT_NAME)); | |
| 179 localized_strings->SetString( | |
| 180 "chooseDataTypesInstructions", | |
| 181 GetStringFUTF16(IDS_SYNC_CHOOSE_DATATYPES_INSTRUCTIONS, product_name)); | |
| 182 localized_strings->SetString( | |
| 183 "encryptionInstructions", | |
| 184 GetStringFUTF16(IDS_SYNC_ENCRYPTION_INSTRUCTIONS, product_name)); | |
| 185 localized_strings->SetString( | |
| 186 "encryptionHelpURL", chrome::kSyncEncryptionHelpURL); | |
| 187 localized_strings->SetString( | |
| 188 "encryptionSectionMessage", | |
| 189 GetStringFUTF16(IDS_SYNC_ENCRYPTION_SECTION_MESSAGE, product_name)); | |
| 190 localized_strings->SetString( | |
| 191 "passphraseRecover", | |
| 192 GetStringFUTF16( | |
| 193 IDS_SYNC_PASSPHRASE_RECOVER, | |
| 194 base::ASCIIToUTF16( | |
| 195 google_util::AppendGoogleLocaleParam( | |
| 196 GURL(chrome::kSyncGoogleDashboardURL), | |
| 197 g_browser_process->GetApplicationLocale()).spec()))); | |
| 198 localized_strings->SetString( | |
| 199 "stopSyncingExplanation", | |
| 200 l10n_util::GetStringFUTF16( | |
| 201 IDS_SYNC_STOP_SYNCING_EXPLANATION_LABEL, | |
| 202 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), | |
| 203 base::ASCIIToUTF16( | |
| 204 google_util::AppendGoogleLocaleParam( | |
| 205 GURL(chrome::kSyncGoogleDashboardURL), | |
| 206 g_browser_process->GetApplicationLocale()).spec()))); | |
| 207 localized_strings->SetString("deleteProfileLabel", | |
| 208 l10n_util::GetStringUTF16(IDS_SYNC_STOP_DELETE_PROFILE_LABEL)); | |
| 209 localized_strings->SetString("stopSyncingTitle", | |
| 210 l10n_util::GetStringUTF16(IDS_SYNC_STOP_SYNCING_DIALOG_TITLE)); | |
| 211 localized_strings->SetString("stopSyncingConfirm", | |
| 212 l10n_util::GetStringUTF16(IDS_SYNC_STOP_SYNCING_CONFIRM_BUTTON_LABEL)); | |
| 213 | |
| 214 localized_strings->SetString( | |
| 215 "syncEverythingHelpURL", chrome::kSyncEverythingLearnMoreURL); | |
| 216 localized_strings->SetString( | |
| 217 "syncErrorHelpURL", chrome::kSyncErrorsHelpURL); | |
| 218 | |
| 219 static OptionsStringResource resources[] = { | |
| 220 { "syncSetupConfigureTitle", IDS_SYNC_SETUP_CONFIGURE_TITLE }, | |
| 221 { "syncSetupSpinnerTitle", IDS_SYNC_SETUP_SPINNER_TITLE }, | |
| 222 { "syncSetupTimeoutTitle", IDS_SYNC_SETUP_TIME_OUT_TITLE }, | |
| 223 { "syncSetupTimeoutContent", IDS_SYNC_SETUP_TIME_OUT_CONTENT }, | |
| 224 { "errorLearnMore", IDS_LEARN_MORE }, | |
| 225 { "cancel", IDS_CANCEL }, | |
| 226 { "loginSuccess", IDS_SYNC_SUCCESS }, | |
| 227 { "settingUp", IDS_SYNC_LOGIN_SETTING_UP }, | |
| 228 { "syncAllDataTypes", IDS_SYNC_EVERYTHING }, | |
| 229 { "chooseDataTypes", IDS_SYNC_CHOOSE_DATATYPES }, | |
| 230 { "syncNothing", IDS_SYNC_NOTHING }, | |
| 231 { "bookmarks", IDS_SYNC_DATATYPE_BOOKMARKS }, | |
| 232 { "preferences", IDS_SYNC_DATATYPE_PREFERENCES }, | |
| 233 { "autofill", IDS_SYNC_DATATYPE_AUTOFILL }, | |
| 234 { "themes", IDS_SYNC_DATATYPE_THEMES }, | |
| 235 { "passwords", IDS_SYNC_DATATYPE_PASSWORDS }, | |
| 236 { "extensions", IDS_SYNC_DATATYPE_EXTENSIONS }, | |
| 237 { "typedURLs", IDS_SYNC_DATATYPE_TYPED_URLS }, | |
| 238 { "apps", IDS_SYNC_DATATYPE_APPS }, | |
| 239 { "wifiCredentials", IDS_SYNC_DATATYPE_WIFI_CREDENTIALS }, | |
| 240 { "openTabs", IDS_SYNC_DATATYPE_TABS }, | |
| 241 { "serviceUnavailableError", IDS_SYNC_SETUP_ABORTED_BY_PENDING_CLEAR }, | |
| 242 { "confirmLabel", IDS_SYNC_CONFIRM_PASSPHRASE_LABEL }, | |
| 243 { "emptyErrorMessage", IDS_SYNC_EMPTY_PASSPHRASE_ERROR }, | |
| 244 { "mismatchErrorMessage", IDS_SYNC_PASSPHRASE_MISMATCH_ERROR }, | |
| 245 { "customizeLinkLabel", IDS_SYNC_CUSTOMIZE_LINK_LABEL }, | |
| 246 { "confirmSyncPreferences", IDS_SYNC_CONFIRM_SYNC_PREFERENCES }, | |
| 247 { "syncEverything", IDS_SYNC_SYNC_EVERYTHING }, | |
| 248 { "useDefaultSettings", IDS_SYNC_USE_DEFAULT_SETTINGS }, | |
| 249 { "enterPassphraseBody", IDS_SYNC_ENTER_PASSPHRASE_BODY }, | |
| 250 { "enterGooglePassphraseBody", IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY }, | |
| 251 { "passphraseLabel", IDS_SYNC_PASSPHRASE_LABEL }, | |
| 252 { "incorrectPassphrase", IDS_SYNC_INCORRECT_PASSPHRASE }, | |
| 253 { "passphraseWarning", IDS_SYNC_PASSPHRASE_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 // TODO(rogerta): browser/resource/sync_promo/sync_promo.html and related | |
| 260 // file may not be needed any more. If not, then the following promo | |
| 261 // strings can also be removed. | |
| 262 { "promoPageTitle", IDS_SYNC_PROMO_TAB_TITLE }, | |
| 263 { "promoSkipButton", IDS_SYNC_PROMO_SKIP_BUTTON }, | |
| 264 { "promoAdvanced", IDS_SYNC_PROMO_ADVANCED }, | |
| 265 { "promoLearnMore", IDS_LEARN_MORE }, | |
| 266 { "promoTitleShort", IDS_SYNC_PROMO_MESSAGE_TITLE_SHORT }, | |
| 267 { "encryptionSectionTitle", IDS_SYNC_ENCRYPTION_SECTION_TITLE }, | |
| 268 { "basicEncryptionOption", IDS_SYNC_BASIC_ENCRYPTION_DATA }, | |
| 269 { "fullEncryptionOption", IDS_SYNC_FULL_ENCRYPTION_DATA }, | |
| 270 }; | |
| 271 | |
| 272 RegisterStrings(localized_strings, resources, arraysize(resources)); | |
| 273 RegisterTitle(localized_strings, "syncSetupOverlay", IDS_SYNC_SETUP_TITLE); | |
| 274 } | |
| 275 | |
| 276 void SyncSetupHandler::ConfigureSyncDone() { | |
| 277 base::StringValue page("done"); | |
| 278 web_ui()->CallJavascriptFunction( | |
| 279 "SyncSetupOverlay.showSyncSetupPage", page); | |
| 280 | |
| 281 // Suppress the sign in promo once the user starts sync. This way the user | |
| 282 // doesn't see the sign in promo even if they sign out later on. | |
| 283 signin::SetUserSkippedPromo(GetProfile()); | |
| 284 | |
| 285 ProfileSyncService* service = GetSyncService(); | |
| 286 DCHECK(service); | |
| 287 if (!service->HasSyncSetupCompleted()) { | |
| 288 // This is the first time configuring sync, so log it. | |
| 289 base::FilePath profile_file_path = GetProfile()->GetPath(); | |
| 290 ProfileMetrics::LogProfileSyncSignIn(profile_file_path); | |
| 291 | |
| 292 // We're done configuring, so notify ProfileSyncService that it is OK to | |
| 293 // start syncing. | |
| 294 service->SetSetupInProgress(false); | |
| 295 service->SetSyncSetupCompleted(); | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 bool SyncSetupHandler::IsActiveLogin() const { | |
| 300 // LoginUIService can be NULL if page is brought up in incognito mode | |
| 301 // (i.e. if the user is running in guest mode in cros and brings up settings). | |
| 302 LoginUIService* service = GetLoginUIService(); | |
| 303 return service && (service->current_login_ui() == this); | |
| 304 } | |
| 305 | |
| 306 void SyncSetupHandler::RegisterMessages() { | |
| 307 web_ui()->RegisterMessageCallback( | |
| 308 "SyncSetupDidClosePage", | |
| 309 base::Bind(&SyncSetupHandler::OnDidClosePage, | |
| 310 base::Unretained(this))); | |
| 311 web_ui()->RegisterMessageCallback( | |
| 312 "SyncSetupConfigure", | |
| 313 base::Bind(&SyncSetupHandler::HandleConfigure, | |
| 314 base::Unretained(this))); | |
| 315 web_ui()->RegisterMessageCallback( | |
| 316 "SyncSetupShowSetupUI", | |
| 317 base::Bind(&SyncSetupHandler::HandleShowSetupUI, | |
| 318 base::Unretained(this))); | |
| 319 web_ui()->RegisterMessageCallback("CloseTimeout", | |
| 320 base::Bind(&SyncSetupHandler::HandleCloseTimeout, | |
| 321 base::Unretained(this))); | |
| 322 #if defined(OS_CHROMEOS) | |
| 323 web_ui()->RegisterMessageCallback( | |
| 324 "SyncSetupDoSignOutOnAuthError", | |
| 325 base::Bind(&SyncSetupHandler::HandleDoSignOutOnAuthError, | |
| 326 base::Unretained(this))); | |
| 327 #else | |
| 328 web_ui()->RegisterMessageCallback("SyncSetupStopSyncing", | |
| 329 base::Bind(&SyncSetupHandler::HandleStopSyncing, | |
| 330 base::Unretained(this))); | |
| 331 web_ui()->RegisterMessageCallback("SyncSetupStartSignIn", | |
| 332 base::Bind(&SyncSetupHandler::HandleStartSignin, | |
| 333 base::Unretained(this))); | |
| 334 #endif | |
| 335 } | |
| 336 | |
| 337 #if !defined(OS_CHROMEOS) | |
| 338 void SyncSetupHandler::DisplayGaiaLogin() { | |
| 339 DCHECK(!sync_startup_tracker_); | |
| 340 // Advanced options are no longer being configured if the login screen is | |
| 341 // visible. If the user exits the signin wizard after this without | |
| 342 // configuring sync, CloseSyncSetup() will ensure they are logged out. | |
| 343 configuring_sync_ = false; | |
| 344 DisplayGaiaLoginInNewTabOrWindow(); | |
| 345 } | |
| 346 | |
| 347 void SyncSetupHandler::DisplayGaiaLoginInNewTabOrWindow() { | |
| 348 Browser* browser = chrome::FindBrowserWithWebContents( | |
| 349 web_ui()->GetWebContents()); | |
| 350 bool force_new_tab = false; | |
| 351 if (!browser) { | |
| 352 // Settings is not displayed in a browser window. Open a new window. | |
| 353 browser = new Browser(Browser::CreateParams( | |
| 354 Browser::TYPE_TABBED, GetProfile(), chrome::GetActiveDesktop())); | |
| 355 force_new_tab = true; | |
| 356 } | |
| 357 | |
| 358 // If the signin manager already has an authenticated username, this is a | |
| 359 // re-auth scenario, and we need to ensure that the user signs in with the | |
| 360 // same email address. | |
| 361 GURL url; | |
| 362 if (SigninManagerFactory::GetForProfile( | |
| 363 browser->profile())->IsAuthenticated()) { | |
| 364 UMA_HISTOGRAM_ENUMERATION("Signin.Reauth", | |
| 365 signin_metrics::HISTOGRAM_REAUTH_SHOWN, | |
| 366 signin_metrics::HISTOGRAM_REAUTH_MAX); | |
| 367 | |
| 368 SigninErrorController* error_controller = | |
| 369 SigninErrorControllerFactory::GetForProfile(browser->profile()); | |
| 370 DCHECK(error_controller->HasError()); | |
| 371 if (!force_new_tab) { | |
| 372 browser->window()->ShowAvatarBubbleFromAvatarButton( | |
| 373 BrowserWindow::AVATAR_BUBBLE_MODE_REAUTH, | |
| 374 signin::ManageAccountsParams()); | |
| 375 } else { | |
| 376 url = signin::GetReauthURL(browser->profile(), | |
| 377 error_controller->error_account_id()); | |
| 378 } | |
| 379 } else { | |
| 380 signin_metrics::LogSigninSource(signin_metrics::SOURCE_SETTINGS); | |
| 381 if (!force_new_tab) { | |
| 382 browser->window()->ShowAvatarBubbleFromAvatarButton( | |
| 383 BrowserWindow::AVATAR_BUBBLE_MODE_SIGNIN, | |
| 384 signin::ManageAccountsParams()); | |
| 385 } else { | |
| 386 url = signin::GetPromoURL(signin_metrics::SOURCE_SETTINGS, true); | |
| 387 } | |
| 388 } | |
| 389 | |
| 390 if (url.is_valid()) | |
| 391 chrome::ShowSingletonTab(browser, url); | |
| 392 } | |
| 393 #endif | |
| 394 | |
| 395 bool SyncSetupHandler::PrepareSyncSetup() { | |
| 396 // If the wizard is already visible, just focus that one. | |
| 397 if (FocusExistingWizardIfPresent()) { | |
| 398 if (!IsActiveLogin()) | |
| 399 CloseSyncSetup(); | |
| 400 return false; | |
| 401 } | |
| 402 | |
| 403 // Notify services that login UI is now active. | |
| 404 GetLoginUIService()->SetLoginUI(this); | |
| 405 | |
| 406 ProfileSyncService* service = GetSyncService(); | |
| 407 if (service) | |
| 408 service->SetSetupInProgress(true); | |
| 409 | |
| 410 return true; | |
| 411 } | |
| 412 | |
| 413 void SyncSetupHandler::DisplaySpinner() { | |
| 414 configuring_sync_ = true; | |
| 415 base::StringValue page("spinner"); | |
| 416 base::DictionaryValue args; | |
| 417 | |
| 418 const int kTimeoutSec = 30; | |
| 419 DCHECK(!backend_start_timer_); | |
| 420 backend_start_timer_.reset(new base::OneShotTimer()); | |
| 421 backend_start_timer_->Start(FROM_HERE, | |
| 422 base::TimeDelta::FromSeconds(kTimeoutSec), | |
| 423 this, &SyncSetupHandler::DisplayTimeout); | |
| 424 | |
| 425 web_ui()->CallJavascriptFunction( | |
| 426 "SyncSetupOverlay.showSyncSetupPage", page, args); | |
| 427 } | |
| 428 | |
| 429 // TODO(kochi): Handle error conditions other than timeout. | |
| 430 // http://crbug.com/128692 | |
| 431 void SyncSetupHandler::DisplayTimeout() { | |
| 432 // Stop a timer to handle timeout in waiting for checking network connection. | |
| 433 backend_start_timer_.reset(); | |
| 434 | |
| 435 // Do not listen to sync startup events. | |
| 436 sync_startup_tracker_.reset(); | |
| 437 | |
| 438 base::StringValue page("timeout"); | |
| 439 base::DictionaryValue args; | |
| 440 web_ui()->CallJavascriptFunction( | |
| 441 "SyncSetupOverlay.showSyncSetupPage", page, args); | |
| 442 } | |
| 443 | |
| 444 void SyncSetupHandler::OnDidClosePage(const base::ListValue* args) { | |
| 445 CloseSyncSetup(); | |
| 446 } | |
| 447 | |
| 448 void SyncSetupHandler::SyncStartupFailed() { | |
| 449 // Stop a timer to handle timeout in waiting for checking network connection. | |
| 450 backend_start_timer_.reset(); | |
| 451 | |
| 452 // Just close the sync overlay (the idea is that the base settings page will | |
| 453 // display the current error.) | |
| 454 CloseUI(); | |
| 455 } | |
| 456 | |
| 457 void SyncSetupHandler::SyncStartupCompleted() { | |
| 458 ProfileSyncService* service = GetSyncService(); | |
| 459 DCHECK(service->IsBackendInitialized()); | |
| 460 | |
| 461 // Stop a timer to handle timeout in waiting for checking network connection. | |
| 462 backend_start_timer_.reset(); | |
| 463 | |
| 464 DisplayConfigureSync(false); | |
| 465 } | |
| 466 | |
| 467 Profile* SyncSetupHandler::GetProfile() const { | |
| 468 return Profile::FromWebUI(web_ui()); | |
| 469 } | |
| 470 | |
| 471 ProfileSyncService* SyncSetupHandler::GetSyncService() const { | |
| 472 Profile* profile = GetProfile(); | |
| 473 return profile->IsSyncAllowed() ? | |
| 474 ProfileSyncServiceFactory::GetForProfile(GetProfile()) : NULL; | |
| 475 } | |
| 476 | |
| 477 void SyncSetupHandler::HandleConfigure(const base::ListValue* args) { | |
| 478 DCHECK(!sync_startup_tracker_); | |
| 479 std::string json; | |
| 480 if (!args->GetString(0, &json)) { | |
| 481 NOTREACHED() << "Could not read JSON argument"; | |
| 482 return; | |
| 483 } | |
| 484 if (json.empty()) { | |
| 485 NOTREACHED(); | |
| 486 return; | |
| 487 } | |
| 488 | |
| 489 SyncConfigInfo configuration; | |
| 490 if (!GetConfiguration(json, &configuration)) { | |
| 491 // The page sent us something that we didn't understand. | |
| 492 // This probably indicates a programming error. | |
| 493 NOTREACHED(); | |
| 494 return; | |
| 495 } | |
| 496 | |
| 497 // Start configuring the ProfileSyncService using the configuration passed | |
| 498 // to us from the JS layer. | |
| 499 ProfileSyncService* service = GetSyncService(); | |
| 500 | |
| 501 // If the sync engine has shutdown for some reason, just close the sync | |
| 502 // dialog. | |
| 503 if (!service || !service->IsBackendInitialized()) { | |
| 504 CloseUI(); | |
| 505 return; | |
| 506 } | |
| 507 | |
| 508 // Disable sync, but remain signed in if the user selected "Sync nothing" in | |
| 509 // the advanced settings dialog. Note: In order to disable sync across | |
| 510 // restarts on Chrome OS, we must call RequestStop(CLEAR_DATA), which | |
| 511 // suppresses sync startup in addition to disabling it. | |
| 512 if (configuration.sync_nothing) { | |
| 513 ProfileSyncService::SyncEvent( | |
| 514 ProfileSyncService::STOP_FROM_ADVANCED_DIALOG); | |
| 515 CloseUI(); | |
| 516 service->RequestStop(ProfileSyncService::CLEAR_DATA); | |
| 517 service->SetSetupInProgress(false); | |
| 518 return; | |
| 519 } | |
| 520 | |
| 521 // Don't allow "encrypt all" if the ProfileSyncService doesn't allow it. | |
| 522 // The UI is hidden, but the user may have enabled it e.g. by fiddling with | |
| 523 // the web inspector. | |
| 524 if (!service->IsEncryptEverythingAllowed()) | |
| 525 configuration.encrypt_all = false; | |
| 526 | |
| 527 // Note: Data encryption will not occur until configuration is complete | |
| 528 // (when the PSS receives its CONFIGURE_DONE notification from the sync | |
| 529 // backend), so the user still has a chance to cancel out of the operation | |
| 530 // if (for example) some kind of passphrase error is encountered. | |
| 531 if (configuration.encrypt_all) | |
| 532 service->EnableEncryptEverything(); | |
| 533 | |
| 534 bool passphrase_failed = false; | |
| 535 if (!configuration.passphrase.empty()) { | |
| 536 // We call IsPassphraseRequired() here (instead of | |
| 537 // IsPassphraseRequiredForDecryption()) because the user may try to enter | |
| 538 // a passphrase even though no encrypted data types are enabled. | |
| 539 if (service->IsPassphraseRequired()) { | |
| 540 // If we have pending keys, try to decrypt them with the provided | |
| 541 // passphrase. We track if this succeeds or fails because a failed | |
| 542 // decryption should result in an error even if there aren't any encrypted | |
| 543 // data types. | |
| 544 passphrase_failed = | |
| 545 !service->SetDecryptionPassphrase(configuration.passphrase); | |
| 546 } else { | |
| 547 // OK, the user sent us a passphrase, but we don't have pending keys. So | |
| 548 // it either means that the pending keys were resolved somehow since the | |
| 549 // time the UI was displayed (re-encryption, pending passphrase change, | |
| 550 // etc) or the user wants to re-encrypt. | |
| 551 if (!configuration.passphrase_is_gaia && | |
| 552 !service->IsUsingSecondaryPassphrase()) { | |
| 553 // User passed us a secondary passphrase, and the data is encrypted | |
| 554 // with a GAIA passphrase so they must want to encrypt. | |
| 555 service->SetEncryptionPassphrase(configuration.passphrase, | |
| 556 ProfileSyncService::EXPLICIT); | |
| 557 } | |
| 558 } | |
| 559 } | |
| 560 | |
| 561 bool user_was_prompted_for_passphrase = | |
| 562 service->IsPassphraseRequiredForDecryption(); | |
| 563 service->OnUserChoseDatatypes(configuration.sync_everything, | |
| 564 configuration.data_types); | |
| 565 | |
| 566 // Need to call IsPassphraseRequiredForDecryption() *after* calling | |
| 567 // OnUserChoseDatatypes() because the user may have just disabled the | |
| 568 // encrypted datatypes (in which case we just want to exit, not prompt the | |
| 569 // user for a passphrase). | |
| 570 if (passphrase_failed || service->IsPassphraseRequiredForDecryption()) { | |
| 571 // We need a passphrase, or the user's attempt to set a passphrase failed - | |
| 572 // prompt them again. This covers a few subtle cases: | |
| 573 // 1) The user enters an incorrect passphrase *and* disabled the encrypted | |
| 574 // data types. In that case we want to notify the user that the | |
| 575 // passphrase was incorrect even though there are no longer any encrypted | |
| 576 // types enabled (IsPassphraseRequiredForDecryption() == false). | |
| 577 // 2) The user doesn't enter any passphrase. In this case, we won't call | |
| 578 // SetDecryptionPassphrase() (passphrase_failed == false), but we still | |
| 579 // want to display an error message to let the user know that their | |
| 580 // blank passphrase entry is not acceptable. | |
| 581 // 3) The user just enabled an encrypted data type - in this case we don't | |
| 582 // want to display an "invalid passphrase" error, since it's the first | |
| 583 // time the user is seeing the prompt. | |
| 584 DisplayConfigureSync(passphrase_failed || user_was_prompted_for_passphrase); | |
| 585 } else { | |
| 586 // No passphrase is required from the user so mark the configuration as | |
| 587 // complete and close the sync setup overlay. | |
| 588 ConfigureSyncDone(); | |
| 589 } | |
| 590 | |
| 591 ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_CUSTOMIZE); | |
| 592 if (configuration.encrypt_all) | |
| 593 ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_ENCRYPT); | |
| 594 if (configuration.passphrase_is_gaia && !configuration.passphrase.empty()) | |
| 595 ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_PASSPHRASE); | |
| 596 if (!configuration.sync_everything) | |
| 597 ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_CHOOSE); | |
| 598 } | |
| 599 | |
| 600 void SyncSetupHandler::HandleShowSetupUI(const base::ListValue* args) { | |
| 601 if (!GetSyncService()) { | |
| 602 DLOG(WARNING) << "Cannot display sync UI when sync is disabled"; | |
| 603 CloseUI(); | |
| 604 return; | |
| 605 } | |
| 606 | |
| 607 SigninManagerBase* signin = | |
| 608 SigninManagerFactory::GetForProfile(GetProfile()); | |
| 609 if (!signin->IsAuthenticated()) { | |
| 610 // For web-based signin, the signin page is not displayed in an overlay | |
| 611 // on the settings page. So if we get here, it must be due to the user | |
| 612 // cancelling signin (by reloading the sync settings page during initial | |
| 613 // signin) or by directly navigating to settings/syncSetup | |
| 614 // (http://crbug.com/229836). So just exit and go back to the settings page. | |
| 615 DLOG(WARNING) << "Cannot display sync setup UI when not signed in"; | |
| 616 CloseUI(); | |
| 617 return; | |
| 618 } | |
| 619 | |
| 620 // If a setup wizard is already present, but not on this page, close the | |
| 621 // blank setup overlay on this page by showing the "done" page. This can | |
| 622 // happen if the user navigates to chrome://settings/syncSetup in more than | |
| 623 // one tab. See crbug.com/261566. | |
| 624 // Note: The following block will transfer focus to the existing wizard. | |
| 625 if (IsExistingWizardPresent() && !IsActiveLogin()) | |
| 626 CloseUI(); | |
| 627 | |
| 628 // If a setup wizard is present on this page or another, bring it to focus. | |
| 629 // Otherwise, display a new one on this page. | |
| 630 if (!FocusExistingWizardIfPresent()) | |
| 631 OpenSyncSetup(); | |
| 632 } | |
| 633 | |
| 634 #if defined(OS_CHROMEOS) | |
| 635 // On ChromeOS, we need to sign out the user session to fix an auth error, so | |
| 636 // the user goes through the real signin flow to generate a new auth token. | |
| 637 void SyncSetupHandler::HandleDoSignOutOnAuthError(const base::ListValue* args) { | |
| 638 DVLOG(1) << "Signing out the user to fix a sync error."; | |
| 639 chrome::AttemptUserExit(); | |
| 640 } | |
| 641 #endif | |
| 642 | |
| 643 #if !defined(OS_CHROMEOS) | |
| 644 void SyncSetupHandler::HandleStartSignin(const base::ListValue* args) { | |
| 645 // Should only be called if the user is not already signed in. | |
| 646 DCHECK(!SigninManagerFactory::GetForProfile(GetProfile())-> | |
| 647 IsAuthenticated()); | |
| 648 OpenSyncSetup(); | |
| 649 } | |
| 650 | |
| 651 void SyncSetupHandler::HandleStopSyncing(const base::ListValue* args) { | |
| 652 if (GetSyncService()) | |
| 653 ProfileSyncService::SyncEvent(ProfileSyncService::STOP_FROM_OPTIONS); | |
| 654 SigninManagerFactory::GetForProfile(GetProfile())->SignOut( | |
| 655 signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS); | |
| 656 | |
| 657 bool delete_profile = false; | |
| 658 if (args->GetBoolean(0, &delete_profile) && delete_profile) { | |
| 659 // Do as BrowserOptionsHandler::DeleteProfile(). | |
| 660 options::helper::DeleteProfileAtPath(GetProfile()->GetPath(), web_ui()); | |
| 661 } | |
| 662 } | |
| 663 #endif | |
| 664 | |
| 665 void SyncSetupHandler::HandleCloseTimeout(const base::ListValue* args) { | |
| 666 CloseSyncSetup(); | |
| 667 } | |
| 668 | |
| 669 void SyncSetupHandler::CloseSyncSetup() { | |
| 670 // Stop a timer to handle timeout in waiting for checking network connection. | |
| 671 backend_start_timer_.reset(); | |
| 672 | |
| 673 // Clear the sync startup tracker, since the setup wizard is being closed. | |
| 674 sync_startup_tracker_.reset(); | |
| 675 | |
| 676 ProfileSyncService* sync_service = GetSyncService(); | |
| 677 if (IsActiveLogin()) { | |
| 678 // Don't log a cancel event if the sync setup dialog is being | |
| 679 // automatically closed due to an auth error. | |
| 680 if (!sync_service || (!sync_service->HasSyncSetupCompleted() && | |
| 681 sync_service->GetAuthError().state() == GoogleServiceAuthError::NONE)) { | |
| 682 if (configuring_sync_) { | |
| 683 ProfileSyncService::SyncEvent( | |
| 684 ProfileSyncService::CANCEL_DURING_CONFIGURE); | |
| 685 | |
| 686 // If the user clicked "Cancel" while setting up sync, disable sync | |
| 687 // because we don't want the sync backend to remain in the | |
| 688 // first-setup-incomplete state. | |
| 689 // Note: In order to disable sync across restarts on Chrome OS, | |
| 690 // we must call RequestStop(CLEAR_DATA), which suppresses sync startup | |
| 691 // in addition to disabling it. | |
| 692 if (sync_service) { | |
| 693 DVLOG(1) << "Sync setup aborted by user action"; | |
| 694 sync_service->RequestStop(ProfileSyncService::CLEAR_DATA); | |
| 695 #if !defined(OS_CHROMEOS) | |
| 696 // Sign out the user on desktop Chrome if they click cancel during | |
| 697 // initial setup. | |
| 698 // TODO(rsimha): Revisit this for M30. See http://crbug.com/252049. | |
| 699 if (sync_service->IsFirstSetupInProgress()) { | |
| 700 SigninManagerFactory::GetForProfile(GetProfile())->SignOut( | |
| 701 signin_metrics::ABORT_SIGNIN); | |
| 702 } | |
| 703 #endif | |
| 704 } | |
| 705 } | |
| 706 } | |
| 707 | |
| 708 GetLoginUIService()->LoginUIClosed(this); | |
| 709 } | |
| 710 | |
| 711 // Alert the sync service anytime the sync setup dialog is closed. This can | |
| 712 // happen due to the user clicking the OK or Cancel button, or due to the | |
| 713 // dialog being closed by virtue of sync being disabled in the background. | |
| 714 if (sync_service) | |
| 715 sync_service->SetSetupInProgress(false); | |
| 716 | |
| 717 configuring_sync_ = false; | |
| 718 } | |
| 719 | |
| 720 void SyncSetupHandler::OpenSyncSetup() { | |
| 721 if (!PrepareSyncSetup()) | |
| 722 return; | |
| 723 | |
| 724 // There are several different UI flows that can bring the user here: | |
| 725 // 1) Signin promo. | |
| 726 // 2) Normal signin through settings page (IsAuthenticated() is false). | |
| 727 // 3) Previously working credentials have expired. | |
| 728 // 4) User is signed in, but has stopped sync via the google dashboard, and | |
| 729 // signout is prohibited by policy so we need to force a re-auth. | |
| 730 // 5) User clicks [Advanced Settings] button on options page while already | |
| 731 // logged in. | |
| 732 // 6) One-click signin (credentials are already available, so should display | |
| 733 // sync configure UI, not login UI). | |
| 734 // 7) User re-enables sync after disabling it via advanced settings. | |
| 735 #if !defined(OS_CHROMEOS) | |
| 736 SigninManagerBase* signin = | |
| 737 SigninManagerFactory::GetForProfile(GetProfile()); | |
| 738 | |
| 739 if (!signin->IsAuthenticated() || | |
| 740 SigninErrorControllerFactory::GetForProfile(GetProfile())->HasError()) { | |
| 741 // User is not logged in (cases 1-2), or login has been specially requested | |
| 742 // because previously working credentials have expired (case 3). Close sync | |
| 743 // setup including any visible overlays, and display the gaia auth page. | |
| 744 // Control will be returned to the sync settings page once auth is complete. | |
| 745 CloseUI(); | |
| 746 DisplayGaiaLogin(); | |
| 747 return; | |
| 748 } | |
| 749 #endif | |
| 750 if (!GetSyncService()) { | |
| 751 // This can happen if the user directly navigates to /settings/syncSetup. | |
| 752 DLOG(WARNING) << "Cannot display sync UI when sync is disabled"; | |
| 753 CloseUI(); | |
| 754 return; | |
| 755 } | |
| 756 | |
| 757 // User is already logged in. They must have brought up the config wizard | |
| 758 // via the "Advanced..." button or through One-Click signin (cases 4-6), or | |
| 759 // they are re-enabling sync after having disabled it (case 7). | |
| 760 DisplayConfigureSync(false); | |
| 761 } | |
| 762 | |
| 763 void SyncSetupHandler::OpenConfigureSync() { | |
| 764 if (!PrepareSyncSetup()) | |
| 765 return; | |
| 766 | |
| 767 DisplayConfigureSync(false); | |
| 768 } | |
| 769 | |
| 770 void SyncSetupHandler::FocusUI() { | |
| 771 DCHECK(IsActiveLogin()); | |
| 772 WebContents* web_contents = web_ui()->GetWebContents(); | |
| 773 web_contents->GetDelegate()->ActivateContents(web_contents); | |
| 774 } | |
| 775 | |
| 776 void SyncSetupHandler::CloseUI() { | |
| 777 CloseSyncSetup(); | |
| 778 base::StringValue page("done"); | |
| 779 web_ui()->CallJavascriptFunction( | |
| 780 "SyncSetupOverlay.showSyncSetupPage", page); | |
| 781 } | |
| 782 | |
| 783 bool SyncSetupHandler::IsExistingWizardPresent() { | |
| 784 LoginUIService* service = GetLoginUIService(); | |
| 785 DCHECK(service); | |
| 786 return service->current_login_ui() != NULL; | |
| 787 } | |
| 788 | |
| 789 bool SyncSetupHandler::FocusExistingWizardIfPresent() { | |
| 790 if (!IsExistingWizardPresent()) | |
| 791 return false; | |
| 792 | |
| 793 LoginUIService* service = GetLoginUIService(); | |
| 794 DCHECK(service); | |
| 795 service->current_login_ui()->FocusUI(); | |
| 796 return true; | |
| 797 } | |
| 798 | |
| 799 void SyncSetupHandler::DisplayConfigureSync(bool passphrase_failed) { | |
| 800 // Should never call this when we are not signed in. | |
| 801 DCHECK(SigninManagerFactory::GetForProfile( | |
| 802 GetProfile())->IsAuthenticated()); | |
| 803 ProfileSyncService* service = GetSyncService(); | |
| 804 DCHECK(service); | |
| 805 if (!service->IsBackendInitialized()) { | |
| 806 service->RequestStart(); | |
| 807 | |
| 808 // See if it's even possible to bring up the sync backend - if not | |
| 809 // (unrecoverable error?), don't bother displaying a spinner that will be | |
| 810 // immediately closed because this leads to some ugly infinite UI loop (see | |
| 811 // http://crbug.com/244769). | |
| 812 if (SyncStartupTracker::GetSyncServiceState(GetProfile()) != | |
| 813 SyncStartupTracker::SYNC_STARTUP_ERROR) { | |
| 814 DisplaySpinner(); | |
| 815 } | |
| 816 | |
| 817 // Start SyncSetupTracker to wait for sync to initialize. | |
| 818 sync_startup_tracker_.reset( | |
| 819 new SyncStartupTracker(GetProfile(), this)); | |
| 820 return; | |
| 821 } | |
| 822 | |
| 823 // Should only get here if user is signed in and sync is initialized, so no | |
| 824 // longer need a SyncStartupTracker. | |
| 825 sync_startup_tracker_.reset(); | |
| 826 configuring_sync_ = true; | |
| 827 DCHECK(service->IsBackendInitialized()) | |
| 828 << "Cannot configure sync until the sync backend is initialized"; | |
| 829 | |
| 830 // Setup args for the sync configure screen: | |
| 831 // syncAllDataTypes: true if the user wants to sync everything | |
| 832 // syncNothing: true if the user wants to sync nothing | |
| 833 // <data_type>Registered: true if the associated data type is supported | |
| 834 // <data_type>Synced: true if the user wants to sync that specific data type | |
| 835 // encryptionEnabled: true if sync supports encryption | |
| 836 // encryptAllData: true if user wants to encrypt all data (not just | |
| 837 // passwords) | |
| 838 // usePassphrase: true if the data is encrypted with a secondary passphrase | |
| 839 // show_passphrase: true if a passphrase is needed to decrypt the sync data | |
| 840 base::DictionaryValue args; | |
| 841 | |
| 842 // Tell the UI layer which data types are registered/enabled by the user. | |
| 843 const syncer::ModelTypeSet registered_types = | |
| 844 service->GetRegisteredDataTypes(); | |
| 845 const syncer::ModelTypeSet preferred_types = service->GetPreferredDataTypes(); | |
| 846 const syncer::ModelTypeSet enforced_types = service->GetForcedDataTypes(); | |
| 847 syncer::ModelTypeNameMap type_names = syncer::GetUserSelectableTypeNameMap(); | |
| 848 for (syncer::ModelTypeNameMap::const_iterator it = type_names.begin(); | |
| 849 it != type_names.end(); ++it) { | |
| 850 syncer::ModelType sync_type = it->first; | |
| 851 const std::string key_name = it->second; | |
| 852 args.SetBoolean(key_name + "Registered", registered_types.Has(sync_type)); | |
| 853 args.SetBoolean(key_name + "Synced", preferred_types.Has(sync_type)); | |
| 854 args.SetBoolean(key_name + "Enforced", enforced_types.Has(sync_type)); | |
| 855 // TODO(treib): How do we want to handle pref groups, i.e. when only some of | |
| 856 // the sync types behind a checkbox are force-enabled? crbug.com/403326 | |
| 857 } | |
| 858 sync_driver::SyncPrefs sync_prefs(GetProfile()->GetPrefs()); | |
| 859 args.SetBoolean("passphraseFailed", passphrase_failed); | |
| 860 args.SetBoolean("syncAllDataTypes", sync_prefs.HasKeepEverythingSynced()); | |
| 861 args.SetBoolean("syncNothing", false); // Always false during initial setup. | |
| 862 args.SetBoolean("encryptAllData", service->IsEncryptEverythingEnabled()); | |
| 863 args.SetBoolean("encryptAllDataAllowed", | |
| 864 service->IsEncryptEverythingAllowed()); | |
| 865 | |
| 866 // We call IsPassphraseRequired() here, instead of calling | |
| 867 // IsPassphraseRequiredForDecryption(), because we want to show the passphrase | |
| 868 // UI even if no encrypted data types are enabled. | |
| 869 args.SetBoolean("showPassphrase", service->IsPassphraseRequired()); | |
| 870 | |
| 871 // To distinguish between FROZEN_IMPLICIT_PASSPHRASE and CUSTOM_PASSPHRASE | |
| 872 // we only set usePassphrase for CUSTOM_PASSPHRASE. | |
| 873 args.SetBoolean("usePassphrase", | |
| 874 service->GetPassphraseType() == syncer::CUSTOM_PASSPHRASE); | |
| 875 base::Time passphrase_time = service->GetExplicitPassphraseTime(); | |
| 876 syncer::PassphraseType passphrase_type = service->GetPassphraseType(); | |
| 877 if (!passphrase_time.is_null()) { | |
| 878 base::string16 passphrase_time_str = | |
| 879 base::TimeFormatShortDate(passphrase_time); | |
| 880 args.SetString( | |
| 881 "enterPassphraseBody", | |
| 882 GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE, | |
| 883 passphrase_time_str)); | |
| 884 args.SetString( | |
| 885 "enterGooglePassphraseBody", | |
| 886 GetStringFUTF16(IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE, | |
| 887 passphrase_time_str)); | |
| 888 switch (passphrase_type) { | |
| 889 case syncer::FROZEN_IMPLICIT_PASSPHRASE: | |
| 890 args.SetString( | |
| 891 "fullEncryptionBody", | |
| 892 GetStringFUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_GOOGLE_WITH_DATE, | |
| 893 passphrase_time_str)); | |
| 894 break; | |
| 895 case syncer::CUSTOM_PASSPHRASE: | |
| 896 args.SetString( | |
| 897 "fullEncryptionBody", | |
| 898 GetStringFUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM_WITH_DATE, | |
| 899 passphrase_time_str)); | |
| 900 break; | |
| 901 default: | |
| 902 args.SetString( | |
| 903 "fullEncryptionBody", | |
| 904 GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM)); | |
| 905 break; | |
| 906 } | |
| 907 } else if (passphrase_type == syncer::CUSTOM_PASSPHRASE) { | |
| 908 args.SetString( | |
| 909 "fullEncryptionBody", | |
| 910 GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM)); | |
| 911 } else { | |
| 912 args.SetString( | |
| 913 "fullEncryptionBody", | |
| 914 GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_DATA)); | |
| 915 } | |
| 916 | |
| 917 base::StringValue page("configure"); | |
| 918 web_ui()->CallJavascriptFunction( | |
| 919 "SyncSetupOverlay.showSyncSetupPage", page, args); | |
| 920 | |
| 921 // Make sure the tab used for the Gaia sign in does not cover the settings | |
| 922 // tab. | |
| 923 FocusUI(); | |
| 924 } | |
| 925 | |
| 926 LoginUIService* SyncSetupHandler::GetLoginUIService() const { | |
| 927 return LoginUIServiceFactory::GetForProfile(GetProfile()); | |
| 928 } | |
| OLD | NEW |