| Index: chrome/browser/sync/sync_setup_flow.cc
|
| diff --git a/chrome/browser/sync/sync_setup_flow.cc b/chrome/browser/sync/sync_setup_flow.cc
|
| index 92e345eb5a04a4ce43b32740ddb575930c577dfa..9afda358ca124b4ed2ce8b153e9426534466855e 100644
|
| --- a/chrome/browser/sync/sync_setup_flow.cc
|
| +++ b/chrome/browser/sync/sync_setup_flow.cc
|
| @@ -32,6 +32,8 @@
|
|
|
| // XPath expression for finding specific iframes.
|
| static const wchar_t* kLoginIFrameXPath = L"//iframe[@id='login']";
|
| +static const wchar_t* kChooseDataTypesIFrameXPath =
|
| + L"//iframe[@id='choose_data_types']";
|
| static const wchar_t* kDoneIframeXPath = L"//iframe[@id='done']";
|
|
|
| void FlowHandler::RegisterMessages() {
|
| @@ -47,6 +49,8 @@ void FlowHandler::RegisterMessages() {
|
| #endif
|
| dom_ui_->RegisterMessageCallback("SubmitAuth",
|
| NewCallback(this, &FlowHandler::HandleSubmitAuth));
|
| + dom_ui_->RegisterMessageCallback("ChooseDataTypes",
|
| + NewCallback(this, &FlowHandler::HandleChooseDataTypes));
|
| }
|
|
|
| static bool GetAuthData(const std::string& json,
|
| @@ -64,6 +68,63 @@ static bool GetAuthData(const std::string& json,
|
| return true;
|
| }
|
|
|
| +static bool GetDataTypeChoiceData(const std::string& json,
|
| + bool* sync_everything, syncable::ModelTypeSet* data_types) {
|
| + scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false));
|
| + if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY))
|
| + return false;
|
| +
|
| + DictionaryValue* result = static_cast<DictionaryValue*>(parsed_value.get());
|
| + if (!result->GetBoolean(L"keepEverythingSynced", sync_everything))
|
| + return false;
|
| +
|
| + // These values need to be kept in sync with where they are written in
|
| + // choose_datatypes.html.
|
| + bool sync_bookmarks;
|
| + if (!result->GetBoolean(L"syncBookmarks", &sync_bookmarks))
|
| + return false;
|
| + if (sync_bookmarks)
|
| + data_types->insert(syncable::BOOKMARKS);
|
| +
|
| + bool sync_preferences;
|
| + if (!result->GetBoolean(L"syncPreferences", &sync_preferences))
|
| + return false;
|
| + if (sync_preferences)
|
| + data_types->insert(syncable::PREFERENCES);
|
| +
|
| + bool sync_themes;
|
| + if (!result->GetBoolean(L"syncThemes", &sync_themes))
|
| + return false;
|
| + if (sync_themes)
|
| + data_types->insert(syncable::THEMES);
|
| +
|
| + bool sync_passwords;
|
| + if (!result->GetBoolean(L"syncPasswords", &sync_passwords))
|
| + return false;
|
| + if (sync_passwords)
|
| + data_types->insert(syncable::PASSWORDS);
|
| +
|
| + bool sync_autofill;
|
| + if (!result->GetBoolean(L"syncAutofill", &sync_autofill))
|
| + return false;
|
| + if (sync_autofill)
|
| + data_types->insert(syncable::AUTOFILL);
|
| +
|
| + bool sync_extensions;
|
| + if (!result->GetBoolean(L"syncExtensions", &sync_extensions))
|
| + return false;
|
| + if (sync_extensions)
|
| + data_types->insert(syncable::EXTENSIONS);
|
| +
|
| + bool sync_typed_urls;
|
| + if (!result->GetBoolean(L"syncTypedUrls", &sync_typed_urls))
|
| + return false;
|
| + if (sync_typed_urls)
|
| + data_types->insert(syncable::TYPED_URLS);
|
| +
|
| + return true;
|
| +}
|
| +
|
| void FlowHandler::HandleUserClickedCustomize(const Value* value) {
|
| if (flow_)
|
| flow_->OnUserClickedCustomize();
|
| @@ -111,8 +172,39 @@ void FlowHandler::HandleSubmitAuth(const Value* value) {
|
| flow_->OnUserSubmittedAuth(username, password, captcha);
|
| }
|
|
|
| +
|
| +void FlowHandler::HandleChooseDataTypes(const Value* value) {
|
| + std::string json(dom_ui_util::GetJsonResponseFromFirstArgumentInList(value));
|
| + bool sync_everything;
|
| + syncable::ModelTypeSet chosen_types;
|
| + if (json.empty())
|
| + return;
|
| +
|
| + if (!GetDataTypeChoiceData(json, &sync_everything, &chosen_types)) {
|
| + // The page sent us something that we didn't understand.
|
| + // This probably indicates a programming error.
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + DCHECK(flow_);
|
| + flow_->OnUserChoseDataTypes(sync_everything, chosen_types);
|
| +
|
| + return;
|
| +}
|
| +
|
| // Called by SyncSetupFlow::Advance.
|
| void FlowHandler::ShowGaiaLogin(const DictionaryValue& args) {
|
| + // Whenever you start a wizard, you pass in an arg so it starts on the right
|
| + // iframe (see setup_flow.html's showTheRightIframe() method). But when you
|
| + // transition from one flow to another, you have to explicitly call the JS
|
| + // function to show the next iframe.
|
| + // So if you ever made a wizard that involved a gaia login as not the first
|
| + // frame, this call would be necessary to ensure that this method actually
|
| + // shows the gaia login.
|
| + if (dom_ui_)
|
| + dom_ui_->CallJavascriptFunction(L"showGaiaLoginIframe");
|
| +
|
| std::string json;
|
| base::JSONWriter::Write(&args, false, &json);
|
| std::wstring javascript = std::wstring(L"showGaiaLogin") +
|
| @@ -129,6 +221,22 @@ void FlowHandler::ShowGaiaSuccessAndSettingUp() {
|
| L"showGaiaSuccessAndSettingUp();");
|
| }
|
|
|
| +// Called by SyncSetupFlow::Advance.
|
| +void FlowHandler::ShowChooseDataTypes(const DictionaryValue& args) {
|
| +
|
| + // If you're starting the wizard at the Choose Data Types screen (i.e. from
|
| + // "Customize Sync"), this will be redundant. However, if you're coming from
|
| + // another wizard state, this will make sure Choose Data Types is on top.
|
| + if (dom_ui_)
|
| + dom_ui_->CallJavascriptFunction(L"showChooseDataTypes");
|
| +
|
| + std::string json;
|
| + base::JSONWriter::Write(&args, false, &json);
|
| + std::wstring javascript = std::wstring(L"setChooseDataTypesCheckboxes") +
|
| + L"(" + UTF8ToWide(json) + L");";
|
| + ExecuteJavascriptInIFrame(kChooseDataTypesIFrameXPath, javascript);
|
| +}
|
| +
|
| void FlowHandler::ShowSetupDone(const std::wstring& user) {
|
| StringValue synced_to_string(WideToUTF8(l10n_util::GetStringF(
|
| IDS_SYNC_NTP_SYNCED_TO, user)));
|
| @@ -229,8 +337,13 @@ void SyncSetupFlow::OnDialogClosed(const std::string& json_retval) {
|
| ProfileSyncService::SyncEvent(
|
| ProfileSyncService::CANCEL_DURING_SIGNON);
|
| break;
|
| + case SyncSetupWizard::CHOOSE_DATA_TYPES:
|
| + ProfileSyncService::SyncEvent(
|
| + ProfileSyncService::CANCEL_FROM_CHOOSE_DATA_TYPES);
|
| case SyncSetupWizard::DONE_FIRST_TIME:
|
| case SyncSetupWizard::DONE:
|
| + // TODO(sync): rename this histogram; it's tracking authorization AND
|
| + // initial sync download time.
|
| UMA_HISTOGRAM_MEDIUM_TIMES("Sync.UserPerceivedAuthorizationTime",
|
| base::TimeTicks::Now() - login_start_time_);
|
| break;
|
| @@ -245,6 +358,7 @@ void SyncSetupFlow::OnDialogClosed(const std::string& json_retval) {
|
| // static
|
| void SyncSetupFlow::GetArgsForGaiaLogin(const ProfileSyncService* service,
|
| DictionaryValue* args) {
|
| + args->SetString(L"iframeToShow", "login");
|
| const GoogleServiceAuthError& error = service->GetAuthError();
|
| if (!service->last_attempted_user_email().empty()) {
|
| args->SetString(L"user", service->last_attempted_user_email());
|
| @@ -260,6 +374,42 @@ void SyncSetupFlow::GetArgsForGaiaLogin(const ProfileSyncService* service,
|
| args->SetBoolean(L"showCustomize", true);
|
| }
|
|
|
| +// static
|
| +void SyncSetupFlow::GetArgsForChooseDataTypes(ProfileSyncService* service,
|
| + DictionaryValue* args) {
|
| + args->SetString(L"iframeToShow", "choose_data_types");
|
| + args->SetBoolean(L"keepEverythingSynced",
|
| + service->profile()->GetPrefs()->GetBoolean(prefs::kKeepEverythingSynced));
|
| +
|
| + // Bookmarks, Preferences, and Themes are launched for good, there's no
|
| + // going back now. Check if the other data types are registered though.
|
| + syncable::ModelTypeSet registered_types;
|
| + service->GetRegisteredDataTypes(®istered_types);
|
| + args->SetBoolean(L"passwordsRegistered",
|
| + registered_types.count(syncable::PASSWORDS) > 0);
|
| + args->SetBoolean(L"autofillRegistered",
|
| + registered_types.count(syncable::AUTOFILL) > 0);
|
| + args->SetBoolean(L"extensionsRegistered",
|
| + registered_types.count(syncable::EXTENSIONS) > 0);
|
| + args->SetBoolean(L"typedUrlsRegistered",
|
| + registered_types.count(syncable::TYPED_URLS) > 0);
|
| +
|
| + args->SetBoolean(L"syncBookmarks",
|
| + service->profile()->GetPrefs()->GetBoolean(prefs::kSyncBookmarks));
|
| + args->SetBoolean(L"syncPreferences",
|
| + service->profile()->GetPrefs()->GetBoolean(prefs::kSyncPreferences));
|
| + args->SetBoolean(L"syncThemes",
|
| + service->profile()->GetPrefs()->GetBoolean(prefs::kSyncThemes));
|
| + args->SetBoolean(L"syncPasswords",
|
| + service->profile()->GetPrefs()->GetBoolean(prefs::kSyncPasswords));
|
| + args->SetBoolean(L"syncAutofill",
|
| + service->profile()->GetPrefs()->GetBoolean(prefs::kSyncAutofill));
|
| + args->SetBoolean(L"syncExtensions",
|
| + service->profile()->GetPrefs()->GetBoolean(prefs::kSyncExtensions));
|
| + args->SetBoolean(L"syncTypedUrls",
|
| + service->profile()->GetPrefs()->GetBoolean(prefs::kSyncTypedUrls));
|
| +}
|
| +
|
| void SyncSetupFlow::GetDOMMessageHandlers(
|
| std::vector<DOMMessageHandler*>* handlers) const {
|
| handlers->push_back(flow_handler_);
|
| @@ -271,14 +421,17 @@ void SyncSetupFlow::GetDOMMessageHandlers(
|
| bool SyncSetupFlow::ShouldAdvance(SyncSetupWizard::State state) {
|
| switch (state) {
|
| case SyncSetupWizard::GAIA_LOGIN:
|
| - return current_state_ == SyncSetupWizard::GAIA_LOGIN;
|
| + return current_state_ == SyncSetupWizard::FATAL_ERROR ||
|
| + current_state_ == SyncSetupWizard::GAIA_LOGIN;
|
| case SyncSetupWizard::GAIA_SUCCESS:
|
| return current_state_ == SyncSetupWizard::GAIA_LOGIN;
|
| + case SyncSetupWizard::CHOOSE_DATA_TYPES:
|
| + return current_state_ == SyncSetupWizard::GAIA_SUCCESS;
|
| case SyncSetupWizard::FATAL_ERROR:
|
| return true; // You can always hit the panic button.
|
| case SyncSetupWizard::DONE_FIRST_TIME:
|
| case SyncSetupWizard::DONE:
|
| - return current_state_ == SyncSetupWizard::GAIA_SUCCESS;
|
| + return current_state_ == SyncSetupWizard::CHOOSE_DATA_TYPES;
|
| default:
|
| NOTREACHED() << "Unhandled State: " << state;
|
| return false;
|
| @@ -288,6 +441,7 @@ bool SyncSetupFlow::ShouldAdvance(SyncSetupWizard::State state) {
|
| void SyncSetupFlow::Advance(SyncSetupWizard::State advance_state) {
|
| if (!ShouldAdvance(advance_state))
|
| return;
|
| +
|
| switch (advance_state) {
|
| case SyncSetupWizard::GAIA_LOGIN: {
|
| DictionaryValue args;
|
| @@ -296,11 +450,18 @@ void SyncSetupFlow::Advance(SyncSetupWizard::State advance_state) {
|
| break;
|
| }
|
| case SyncSetupWizard::GAIA_SUCCESS:
|
| - if (end_state_ == SyncSetupWizard::GAIA_SUCCESS)
|
| + if (end_state_ == SyncSetupWizard::GAIA_SUCCESS) {
|
| flow_handler_->ShowGaiaSuccessAndClose();
|
| - else
|
| - flow_handler_->ShowGaiaSuccessAndSettingUp();
|
| + break;
|
| + }
|
| + advance_state = SyncSetupWizard::CHOOSE_DATA_TYPES;
|
| + // Fall through.
|
| + case SyncSetupWizard::CHOOSE_DATA_TYPES: {
|
| + DictionaryValue args;
|
| + SyncSetupFlow::GetArgsForChooseDataTypes(service_, &args);
|
| + flow_handler_->ShowChooseDataTypes(args);
|
| break;
|
| + }
|
| case SyncSetupWizard::FATAL_ERROR: {
|
| // This shows the user the "Could not connect to server" error.
|
| // TODO(sync): Update this error messaging.
|
| @@ -345,6 +506,8 @@ SyncSetupFlow* SyncSetupFlow::Run(ProfileSyncService* service,
|
| DictionaryValue args;
|
| if (start == SyncSetupWizard::GAIA_LOGIN)
|
| SyncSetupFlow::GetArgsForGaiaLogin(service, &args);
|
| + else if (start == SyncSetupWizard::CHOOSE_DATA_TYPES)
|
| + SyncSetupFlow::GetArgsForChooseDataTypes(service, &args);
|
| std::string json_args;
|
| base::JSONWriter::Write(&args, false, &json_args);
|
|
|
|
|