| Index: chrome/browser/sync/sync_setup_flow.cc
|
| ===================================================================
|
| --- chrome/browser/sync/sync_setup_flow.cc (revision 62207)
|
| +++ chrome/browser/sync/sync_setup_flow.cc (working copy)
|
| @@ -23,7 +23,6 @@
|
| #include "chrome/browser/profile.h"
|
| #include "chrome/browser/renderer_host/render_view_host.h"
|
| #include "chrome/browser/sync/profile_sync_service.h"
|
| -#include "chrome/browser/sync/syncable/model_type.h"
|
| #include "chrome/browser/tab_contents/tab_contents.h"
|
| #include "chrome/common/net/gaia/google_service_auth_error.h"
|
| #include "chrome/common/pref_names.h"
|
| @@ -33,14 +32,18 @@
|
| // 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']";
|
| + L"//iframe[@id='configure']";
|
| +static const wchar_t* kPassphraseIFrameXPath =
|
| + L"//iframe[@id='passphrase']";
|
| static const wchar_t* kDoneIframeXPath = L"//iframe[@id='done']";
|
|
|
| void FlowHandler::RegisterMessages() {
|
| dom_ui_->RegisterMessageCallback("SubmitAuth",
|
| NewCallback(this, &FlowHandler::HandleSubmitAuth));
|
| - dom_ui_->RegisterMessageCallback("ChooseDataTypes",
|
| - NewCallback(this, &FlowHandler::HandleChooseDataTypes));
|
| + dom_ui_->RegisterMessageCallback("Configure",
|
| + NewCallback(this, &FlowHandler::HandleConfigure));
|
| + dom_ui_->RegisterMessageCallback("Passphrase",
|
| + NewCallback(this, &FlowHandler::HandlePassphraseEntry));
|
| }
|
|
|
| static bool GetAuthData(const std::string& json,
|
| @@ -62,66 +65,79 @@
|
| return true;
|
| }
|
|
|
| -static bool GetDataTypeChoiceData(const std::string& json,
|
| - bool* sync_everything, syncable::ModelTypeSet* data_types) {
|
| +static bool GetPassphrase(const std::string& json, std::string* passphrase) {
|
| 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("keepEverythingSynced", sync_everything))
|
| + return result->GetString("passphrase", passphrase);
|
| +}
|
| +
|
| +static bool GetConfiguration(const std::string& json,
|
| + SyncConfiguration* config) {
|
| + 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("keepEverythingSynced", &config->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("syncBookmarks", &sync_bookmarks))
|
| return false;
|
| if (sync_bookmarks)
|
| - data_types->insert(syncable::BOOKMARKS);
|
| + config->data_types.insert(syncable::BOOKMARKS);
|
|
|
| bool sync_preferences;
|
| if (!result->GetBoolean("syncPreferences", &sync_preferences))
|
| return false;
|
| if (sync_preferences)
|
| - data_types->insert(syncable::PREFERENCES);
|
| + config->data_types.insert(syncable::PREFERENCES);
|
|
|
| bool sync_themes;
|
| if (!result->GetBoolean("syncThemes", &sync_themes))
|
| return false;
|
| if (sync_themes)
|
| - data_types->insert(syncable::THEMES);
|
| + config->data_types.insert(syncable::THEMES);
|
|
|
| bool sync_passwords;
|
| if (!result->GetBoolean("syncPasswords", &sync_passwords))
|
| return false;
|
| if (sync_passwords)
|
| - data_types->insert(syncable::PASSWORDS);
|
| + config->data_types.insert(syncable::PASSWORDS);
|
|
|
| bool sync_autofill;
|
| if (!result->GetBoolean("syncAutofill", &sync_autofill))
|
| return false;
|
| if (sync_autofill)
|
| - data_types->insert(syncable::AUTOFILL);
|
| + config->data_types.insert(syncable::AUTOFILL);
|
|
|
| bool sync_extensions;
|
| if (!result->GetBoolean("syncExtensions", &sync_extensions))
|
| return false;
|
| if (sync_extensions)
|
| - data_types->insert(syncable::EXTENSIONS);
|
| + config->data_types.insert(syncable::EXTENSIONS);
|
|
|
| bool sync_typed_urls;
|
| if (!result->GetBoolean("syncTypedUrls", &sync_typed_urls))
|
| return false;
|
| if (sync_typed_urls)
|
| - data_types->insert(syncable::TYPED_URLS);
|
| + config->data_types.insert(syncable::TYPED_URLS);
|
|
|
| bool sync_apps;
|
| if (!result->GetBoolean("syncApps", &sync_apps))
|
| return false;
|
| if (sync_apps)
|
| - data_types->insert(syncable::APPS);
|
| + config->data_types.insert(syncable::APPS);
|
|
|
| + // Encyption settings.
|
| + if (!result->GetBoolean("usePassphrase", &config->use_secondary_passphrase))
|
| + return false;
|
| +
|
| return true;
|
| }
|
|
|
| @@ -142,14 +158,14 @@
|
| flow_->OnUserSubmittedAuth(username, password, captcha, access_code);
|
| }
|
|
|
| -void FlowHandler::HandleChooseDataTypes(const ListValue* args) {
|
| +void FlowHandler::HandleConfigure(const ListValue* args) {
|
| std::string json(dom_ui_util::GetJsonResponseFromFirstArgumentInList(args));
|
| - bool sync_everything;
|
| - syncable::ModelTypeSet chosen_types;
|
| + SyncConfiguration configuration;
|
| +
|
| if (json.empty())
|
| return;
|
|
|
| - if (!GetDataTypeChoiceData(json, &sync_everything, &chosen_types)) {
|
| + if (!GetConfiguration(json, &configuration)) {
|
| // The page sent us something that we didn't understand.
|
| // This probably indicates a programming error.
|
| NOTREACHED();
|
| @@ -157,11 +173,28 @@
|
| }
|
|
|
| DCHECK(flow_);
|
| - flow_->OnUserChoseDataTypes(sync_everything, chosen_types);
|
| + flow_->OnUserConfigured(configuration);
|
|
|
| return;
|
| }
|
|
|
| +void FlowHandler::HandlePassphraseEntry(const ListValue* args) {
|
| + std::string json(dom_ui_util::GetJsonResponseFromFirstArgumentInList(args));
|
| +
|
| + if (json.empty())
|
| + return;
|
| +
|
| + std::string passphrase;
|
| + if (!GetPassphrase(json, &passphrase)) {
|
| + // Couldn't understand what the page sent. Indicates a programming error.
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + DCHECK(flow_);
|
| + flow_->OnPassphraseEntry(passphrase);
|
| +}
|
| +
|
| // 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
|
| @@ -191,20 +224,36 @@
|
| }
|
|
|
| // 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
|
| +void FlowHandler::ShowConfigure(const DictionaryValue& args) {
|
| + // If you're starting the wizard at the configure 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");
|
| + dom_ui_->CallJavascriptFunction(L"showConfigure");
|
|
|
| std::string json;
|
| base::JSONWriter::Write(&args, false, &json);
|
| - std::wstring javascript = std::wstring(L"setCheckboxesAndErrors") +
|
| + std::wstring javascript = std::wstring(L"initializeConfigureDialog") +
|
| L"(" + UTF8ToWide(json) + L");";
|
| ExecuteJavascriptInIFrame(kChooseDataTypesIFrameXPath, javascript);
|
| }
|
|
|
| +void FlowHandler::ShowPassphraseEntry(const DictionaryValue& args) {
|
| + if (dom_ui_)
|
| + dom_ui_->CallJavascriptFunction(L"showPassphrase");
|
| +
|
| + std::string json;
|
| + base::JSONWriter::Write(&args, false, &json);
|
| + std::wstring script = std::wstring(L"setupPassphraseDialog") +
|
| + L"(" + UTF8ToWide(json) + L");";
|
| + ExecuteJavascriptInIFrame(kPassphraseIFrameXPath, script);
|
| +}
|
| +
|
| +void FlowHandler::ShowSettingUp() {
|
| + if (dom_ui_)
|
| + dom_ui_->CallJavascriptFunction(L"showSettingUp");
|
| +}
|
| +
|
| void FlowHandler::ShowSetupDone(const std::wstring& user) {
|
| StringValue synced_to_string(l10n_util::GetStringFUTF8(
|
| IDS_SYNC_NTP_SYNCED_TO, WideToUTF16Hack(user)));
|
| @@ -248,6 +297,7 @@
|
| login_start_time_(base::TimeTicks::Now()),
|
| flow_handler_(new FlowHandler()),
|
| owns_flow_handler_(true),
|
| + configuration_pending_(false),
|
| service_(service),
|
| html_dialog_window_(NULL) {
|
| flow_handler_->set_flow(this);
|
| @@ -305,9 +355,11 @@
|
| ProfileSyncService::SyncEvent(
|
| ProfileSyncService::CANCEL_DURING_SIGNON);
|
| break;
|
| - case SyncSetupWizard::CHOOSE_DATA_TYPES:
|
| + case SyncSetupWizard::CONFIGURE:
|
| + case SyncSetupWizard::ENTER_PASSPHRASE:
|
| + case SyncSetupWizard::SETTING_UP:
|
| ProfileSyncService::SyncEvent(
|
| - ProfileSyncService::CANCEL_FROM_CHOOSE_DATA_TYPES);
|
| + ProfileSyncService::CANCEL_DURING_CONFIGURE);
|
| break;
|
| case SyncSetupWizard::DONE_FIRST_TIME:
|
| case SyncSetupWizard::DONE:
|
| @@ -344,9 +396,13 @@
|
| }
|
|
|
| // static
|
| -void SyncSetupFlow::GetArgsForChooseDataTypes(ProfileSyncService* service,
|
| - DictionaryValue* args) {
|
| - args->SetString("iframeToShow", "choose_data_types");
|
| +void SyncSetupFlow::GetArgsForConfigure(ProfileSyncService* service,
|
| + DictionaryValue* args) {
|
| + args->SetString("iframeToShow", "configure");
|
| +
|
| + // By default start on the data types tab.
|
| + args->SetString("initialTab", "data-type");
|
| +
|
| args->SetBoolean("keepEverythingSynced",
|
| service->profile()->GetPrefs()->GetBoolean(prefs::kKeepEverythingSynced));
|
|
|
| @@ -384,6 +440,9 @@
|
| service->profile()->GetPrefs()->GetBoolean(prefs::kSyncTypedUrls));
|
| args->SetBoolean("syncApps",
|
| service->profile()->GetPrefs()->GetBoolean(prefs::kSyncApps));
|
| +
|
| + // Load the parameters for the encryption tab.
|
| + args->SetBoolean("usePassphrase", service->IsUsingSecondaryPassphrase());
|
| }
|
|
|
| void SyncSetupFlow::GetDOMMessageHandlers(
|
| @@ -394,6 +453,7 @@
|
| owns_flow_handler_ = false;
|
| }
|
|
|
| +// Returns true if the flow should advance to |state| based on |current_state_|.
|
| bool SyncSetupFlow::ShouldAdvance(SyncSetupWizard::State state) {
|
| switch (state) {
|
| case SyncSetupWizard::GAIA_LOGIN:
|
| @@ -401,15 +461,20 @@
|
| current_state_ == SyncSetupWizard::GAIA_LOGIN;
|
| case SyncSetupWizard::GAIA_SUCCESS:
|
| return current_state_ == SyncSetupWizard::GAIA_LOGIN;
|
| - case SyncSetupWizard::CHOOSE_DATA_TYPES:
|
| + case SyncSetupWizard::CONFIGURE:
|
| return current_state_ == SyncSetupWizard::GAIA_SUCCESS;
|
| + case SyncSetupWizard::CREATE_PASSPHRASE:
|
| + return current_state_ == SyncSetupWizard::CONFIGURE;
|
| case SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR:
|
| - return current_state_ == SyncSetupWizard::CHOOSE_DATA_TYPES;
|
| + return current_state_ == SyncSetupWizard::CONFIGURE;
|
| + case SyncSetupWizard::SETTING_UP:
|
| + return current_state_ == SyncSetupWizard::CONFIGURE ||
|
| + current_state_ == SyncSetupWizard::CREATE_PASSPHRASE;
|
| 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::CHOOSE_DATA_TYPES;
|
| + return current_state_ == SyncSetupWizard::SETTING_UP;
|
| default:
|
| NOTREACHED() << "Unhandled State: " << state;
|
| return false;
|
| @@ -417,8 +482,11 @@
|
| }
|
|
|
| void SyncSetupFlow::Advance(SyncSetupWizard::State advance_state) {
|
| - if (!ShouldAdvance(advance_state))
|
| + if (!ShouldAdvance(advance_state)) {
|
| + LOG(WARNING) << "Invalid state change from "
|
| + << current_state_ << " to " << advance_state;
|
| return;
|
| + }
|
|
|
| switch (advance_state) {
|
| case SyncSetupWizard::GAIA_LOGIN: {
|
| @@ -432,21 +500,41 @@
|
| flow_handler_->ShowGaiaSuccessAndClose();
|
| break;
|
| }
|
| - advance_state = SyncSetupWizard::CHOOSE_DATA_TYPES;
|
| + advance_state = SyncSetupWizard::CONFIGURE;
|
| // Fall through.
|
| - case SyncSetupWizard::CHOOSE_DATA_TYPES: {
|
| + case SyncSetupWizard::CONFIGURE: {
|
| DictionaryValue args;
|
| - SyncSetupFlow::GetArgsForChooseDataTypes(service_, &args);
|
| - flow_handler_->ShowChooseDataTypes(args);
|
| + SyncSetupFlow::GetArgsForConfigure(service_, &args);
|
| + args.SetString("initialTab", "data-type");
|
| + flow_handler_->ShowConfigure(args);
|
| break;
|
| }
|
| + case SyncSetupWizard::CREATE_PASSPHRASE: {
|
| + DictionaryValue args;
|
| + args.SetString("mode", "new");
|
| + flow_handler_->ShowPassphraseEntry(args);
|
| + break;
|
| + }
|
| + case SyncSetupWizard::ENTER_PASSPHRASE: {
|
| + DictionaryValue args;
|
| + if (service_->IsUsingSecondaryPassphrase())
|
| + args.SetString("mode", "enter");
|
| + else
|
| + args.SetString("mode", "gaia");
|
| + flow_handler_->ShowPassphraseEntry(args);
|
| + break;
|
| + }
|
| case SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR: {
|
| DictionaryValue args;
|
| - SyncSetupFlow::GetArgsForChooseDataTypes(service_, &args);
|
| + SyncSetupFlow::GetArgsForConfigure(service_, &args);
|
| args.SetBoolean("was_aborted", true);
|
| - flow_handler_->ShowChooseDataTypes(args);
|
| + flow_handler_->ShowConfigure(args);
|
| break;
|
| }
|
| + case SyncSetupWizard::SETTING_UP: {
|
| + flow_handler_->ShowSettingUp();
|
| + break;
|
| + }
|
| case SyncSetupWizard::FATAL_ERROR: {
|
| // This shows the user the "Could not connect to server" error.
|
| // TODO(sync): Update this error messaging.
|
| @@ -492,8 +580,8 @@
|
| DictionaryValue args;
|
| if (start == SyncSetupWizard::GAIA_LOGIN)
|
| SyncSetupFlow::GetArgsForGaiaLogin(service, &args);
|
| - else if (start == SyncSetupWizard::CHOOSE_DATA_TYPES)
|
| - SyncSetupFlow::GetArgsForChooseDataTypes(service, &args);
|
| + else if (start == SyncSetupWizard::CONFIGURE)
|
| + SyncSetupFlow::GetArgsForConfigure(service, &args);
|
| std::string json_args;
|
| base::JSONWriter::Write(&args, false, &json_args);
|
|
|
| @@ -519,3 +607,55 @@
|
| #endif // defined(OS_MACOSX)
|
| return flow;
|
| }
|
| +
|
| +void SyncSetupFlow::OnUserSubmittedAuth(const std::string& username,
|
| + const std::string& password,
|
| + const std::string& captcha,
|
| + const std::string& access_code) {
|
| + service_->OnUserSubmittedAuth(username, password, captcha, access_code);
|
| +}
|
| +
|
| +void SyncSetupFlow::OnUserConfigured(const SyncConfiguration& configuration) {
|
| + // Store the configuration in case we need more information.
|
| + configuration_ = configuration;
|
| + configuration_pending_ = true;
|
| +
|
| + // If the user is activating secondary passphrase for the first time,
|
| + // we need to prompt them to enter one.
|
| + if (configuration.use_secondary_passphrase &&
|
| + !service_->IsUsingSecondaryPassphrase()) {
|
| + Advance(SyncSetupWizard::CREATE_PASSPHRASE);
|
| + return;
|
| + }
|
| +
|
| + OnConfigurationComplete();
|
| +}
|
| +
|
| +void SyncSetupFlow::OnConfigurationComplete() {
|
| + if (!configuration_pending_)
|
| + return;
|
| +
|
| + // Go to the "loading..." screen."
|
| + Advance(SyncSetupWizard::SETTING_UP);
|
| +
|
| + // If we are activating the passphrase, we need to have one supplied.
|
| + DCHECK(service_->IsUsingSecondaryPassphrase() ||
|
| + !configuration_.use_secondary_passphrase ||
|
| + configuration_.secondary_passphrase.length() > 0);
|
| +
|
| + if (configuration_.use_secondary_passphrase &&
|
| + !service_->IsUsingSecondaryPassphrase())
|
| + service_->SetSecondaryPassphrase(configuration_.secondary_passphrase);
|
| +
|
| + service_->OnUserChoseDatatypes(configuration_.sync_everything,
|
| + configuration_.data_types);
|
| +
|
| + configuration_pending_ = false;
|
| +}
|
| +
|
| +void SyncSetupFlow::OnPassphraseEntry(const std::string& passphrase) {
|
| + if (configuration_pending_) {
|
| + configuration_.secondary_passphrase = passphrase;
|
| + OnConfigurationComplete();
|
| + }
|
| +}
|
|
|