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/import_data_handler.h" 6 7#include <string> 8 9#include "base/basictypes.h" 10#include "base/bind.h" 11#include "base/bind_helpers.h" 12#include "base/memory/scoped_ptr.h" 13#include "base/strings/string16.h" 14#include "base/strings/string_number_conversions.h" 15#include "base/strings/string_util.h" 16#include "base/strings/utf_string_conversions.h" 17#include "base/threading/thread_restrictions.h" 18#include "base/values.h" 19#include "chrome/browser/browser_process.h" 20#include "chrome/browser/importer/external_process_importer_host.h" 21#include "chrome/browser/importer/importer_list.h" 22#include "chrome/browser/importer/importer_uma.h" 23#include "chrome/browser/profiles/profile.h" 24#include "chrome/browser/ui/browser_finder.h" 25#include "chrome/browser/ui/browser_window.h" 26#include "chrome/browser/ui/chrome_select_file_policy.h" 27#include "chrome/grit/chromium_strings.h" 28#include "chrome/grit/generated_resources.h" 29#include "content/public/browser/browser_thread.h" 30#include "content/public/browser/web_ui.h" 31 32using content::BrowserThread; 33 34namespace options { 35 36ImportDataHandler::ImportDataHandler() 37 : importer_host_(NULL), 38 import_did_succeed_(false) { 39 DCHECK_CURRENTLY_ON(BrowserThread::UI); 40} 41 42ImportDataHandler::~ImportDataHandler() { 43 DCHECK_CURRENTLY_ON(BrowserThread::UI); 44 45 if (importer_host_) 46 importer_host_->set_observer(NULL); 47 48 if (select_file_dialog_.get()) 49 select_file_dialog_->ListenerDestroyed(); 50} 51 52void ImportDataHandler::GetLocalizedValues( 53 base::DictionaryValue* localized_strings) { 54 DCHECK_CURRENTLY_ON(BrowserThread::UI); 55 DCHECK(localized_strings); 56 57 static OptionsStringResource resources[] = { 58 {"importFromLabel", IDS_IMPORT_FROM_LABEL}, 59 {"importLoading", IDS_IMPORT_LOADING_PROFILES}, 60 {"importDescription", IDS_IMPORT_ITEMS_LABEL}, 61 {"importHistory", IDS_IMPORT_HISTORY_CHKBOX}, 62 {"importFavorites", IDS_IMPORT_FAVORITES_CHKBOX}, 63 {"importSearch", IDS_IMPORT_SEARCH_ENGINES_CHKBOX}, 64 {"importPasswords", IDS_IMPORT_PASSWORDS_CHKBOX}, 65 {"importAutofillFormData", IDS_IMPORT_AUTOFILL_FORM_DATA_CHKBOX}, 66 {"importChooseFile", IDS_IMPORT_CHOOSE_FILE}, 67 {"importCommit", IDS_IMPORT_COMMIT}, 68 {"noProfileFound", IDS_IMPORT_NO_PROFILE_FOUND}, 69 {"importSucceeded", IDS_IMPORT_SUCCEEDED}, 70 {"findYourImportedBookmarks", IDS_IMPORT_FIND_YOUR_BOOKMARKS}, 71#if defined(OS_MACOSX) 72 {"macPasswordKeychain", IDS_IMPORT_PASSWORD_KEYCHAIN_WARNING}, 73#endif 74 }; 75 76 RegisterStrings(localized_strings, resources, arraysize(resources)); 77 RegisterTitle(localized_strings, "importDataOverlay", 78 IDS_IMPORT_SETTINGS_TITLE); 79} 80 81void ImportDataHandler::InitializeHandler() { 82 DCHECK_CURRENTLY_ON(BrowserThread::UI); 83 84 importer_list_.reset(new ImporterList()); 85 importer_list_->DetectSourceProfiles( 86 g_browser_process->GetApplicationLocale(), 87 true, // include_interactive_profiles? 88 base::Bind(&ImportDataHandler::InitializePage, base::Unretained(this))); 89} 90 91void ImportDataHandler::RegisterMessages() { 92 DCHECK_CURRENTLY_ON(BrowserThread::UI); 93 94 web_ui()->RegisterMessageCallback( 95 "importData", 96 base::Bind(&ImportDataHandler::ImportData, base::Unretained(this))); 97 web_ui()->RegisterMessageCallback( 98 "chooseBookmarksFile", 99 base::Bind(&ImportDataHandler::HandleChooseBookmarksFile, 100 base::Unretained(this))); 101} 102 103void ImportDataHandler::StartImport( 104 const importer::SourceProfile& source_profile, 105 uint16 imported_items) { 106 DCHECK_CURRENTLY_ON(BrowserThread::UI); 107 108 if (!imported_items) 109 return; 110 111 // If another import is already ongoing, let it finish silently. 112 if (importer_host_) 113 importer_host_->set_observer(NULL); 114 115 base::FundamentalValue importing(true); 116 web_ui()->CallJavascriptFunction("ImportDataOverlay.setImportingState", 117 importing); 118 import_did_succeed_ = false; 119 120 importer_host_ = new ExternalProcessImporterHost(); 121 importer_host_->set_observer(this); 122 Profile* profile = Profile::FromWebUI(web_ui()); 123 importer_host_->StartImportSettings(source_profile, profile, 124 imported_items, 125 new ProfileWriter(profile)); 126 127 importer::LogImporterUseToMetrics("ImportDataHandler", 128 source_profile.importer_type); 129} 130 131void ImportDataHandler::ImportData(const base::ListValue* args) { 132 DCHECK_CURRENTLY_ON(BrowserThread::UI); 133 134 std::string string_value; 135 136 int browser_index; 137 if (!args->GetString(0, &string_value) || 138 !base::StringToInt(string_value, &browser_index)) { 139 NOTREACHED(); 140 return; 141 } 142 143 uint16 selected_items = importer::NONE; 144 if (args->GetString(1, &string_value) && string_value == "true") { 145 selected_items |= importer::HISTORY; 146 } 147 if (args->GetString(2, &string_value) && string_value == "true") { 148 selected_items |= importer::FAVORITES; 149 } 150 if (args->GetString(3, &string_value) && string_value == "true") { 151 selected_items |= importer::PASSWORDS; 152 } 153 if (args->GetString(4, &string_value) && string_value == "true") { 154 selected_items |= importer::SEARCH_ENGINES; 155 } 156 if (args->GetString(5, &string_value) && string_value == "true") { 157 selected_items |= importer::AUTOFILL_FORM_DATA; 158 } 159 160 const importer::SourceProfile& source_profile = 161 importer_list_->GetSourceProfileAt(browser_index); 162 uint16 supported_items = source_profile.services_supported; 163 164 uint16 imported_items = (selected_items & supported_items); 165 if (imported_items) { 166 StartImport(source_profile, imported_items); 167 } else { 168 LOG(WARNING) << "There were no settings to import from '" 169 << source_profile.importer_name << "'."; 170 } 171} 172 173void ImportDataHandler::InitializePage() { 174 DCHECK_CURRENTLY_ON(BrowserThread::UI); 175 176 base::ListValue browser_profiles; 177 for (size_t i = 0; i < importer_list_->count(); ++i) { 178 const importer::SourceProfile& source_profile = 179 importer_list_->GetSourceProfileAt(i); 180 uint16 browser_services = source_profile.services_supported; 181 182 base::DictionaryValue* browser_profile = new base::DictionaryValue(); 183 browser_profile->SetString("name", source_profile.importer_name); 184 browser_profile->SetInteger("index", i); 185 browser_profile->SetBoolean("history", 186 (browser_services & importer::HISTORY) != 0); 187 browser_profile->SetBoolean("favorites", 188 (browser_services & importer::FAVORITES) != 0); 189 browser_profile->SetBoolean("passwords", 190 (browser_services & importer::PASSWORDS) != 0); 191 browser_profile->SetBoolean("search", 192 (browser_services & importer::SEARCH_ENGINES) != 0); 193 browser_profile->SetBoolean("autofill-form-data", 194 (browser_services & importer::AUTOFILL_FORM_DATA) != 0); 195 196 browser_profile->SetBoolean("show_bottom_bar", 197#if defined(OS_MACOSX) 198 source_profile.importer_type == importer::TYPE_SAFARI); 199#else 200 false); 201#endif 202 203 browser_profiles.Append(browser_profile); 204 } 205 206 web_ui()->CallJavascriptFunction("ImportDataOverlay.updateSupportedBrowsers", 207 browser_profiles); 208} 209 210void ImportDataHandler::ImportStarted() { 211 DCHECK_CURRENTLY_ON(BrowserThread::UI); 212} 213 214void ImportDataHandler::ImportItemStarted(importer::ImportItem item) { 215 DCHECK_CURRENTLY_ON(BrowserThread::UI); 216 217 // TODO(csilv): show progress detail in the web view. 218} 219 220void ImportDataHandler::ImportItemEnded(importer::ImportItem item) { 221 DCHECK_CURRENTLY_ON(BrowserThread::UI); 222 223 // TODO(csilv): show progress detail in the web view. 224 import_did_succeed_ = true; 225} 226 227void ImportDataHandler::ImportEnded() { 228 DCHECK_CURRENTLY_ON(BrowserThread::UI); 229 230 importer_host_->set_observer(NULL); 231 importer_host_ = NULL; 232 233 if (import_did_succeed_) { 234 web_ui()->CallJavascriptFunction("ImportDataOverlay.confirmSuccess"); 235 } else { 236 base::FundamentalValue state(false); 237 web_ui()->CallJavascriptFunction("ImportDataOverlay.setImportingState", 238 state); 239 web_ui()->CallJavascriptFunction("ImportDataOverlay.dismiss"); 240 } 241} 242 243void ImportDataHandler::FileSelected(const base::FilePath& path, 244 int /*index*/, 245 void* /*params*/) { 246 DCHECK_CURRENTLY_ON(BrowserThread::UI); 247 248 importer::SourceProfile source_profile; 249 source_profile.importer_type = importer::TYPE_BOOKMARKS_FILE; 250 source_profile.source_path = path; 251 252 StartImport(source_profile, importer::FAVORITES); 253} 254 255void ImportDataHandler::HandleChooseBookmarksFile(const base::ListValue* args) { 256 DCHECK_CURRENTLY_ON(BrowserThread::UI); 257 258 DCHECK(args && args->empty()); 259 select_file_dialog_ = ui::SelectFileDialog::Create( 260 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); 261 262 ui::SelectFileDialog::FileTypeInfo file_type_info; 263 file_type_info.extensions.resize(1); 264 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html")); 265 266 Browser* browser = 267 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()); 268 269 select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE, 270 base::string16(), 271 base::FilePath(), 272 &file_type_info, 273 0, 274 base::FilePath::StringType(), 275 browser->window()->GetNativeWindow(), 276 NULL); 277} 278 279} // namespace options 280