Home | History | Annotate | Download | only in options
      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 
     32 using content::BrowserThread;
     33 
     34 namespace options {
     35 
     36 ImportDataHandler::ImportDataHandler()
     37     : importer_host_(NULL),
     38       import_did_succeed_(false) {
     39   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     40 }
     41 
     42 ImportDataHandler::~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 
     52 void 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 
     81 void 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 
     91 void 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 
    103 void 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 
    131 void 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 
    173 void 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 
    210 void ImportDataHandler::ImportStarted() {
    211   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    212 }
    213 
    214 void ImportDataHandler::ImportItemStarted(importer::ImportItem item) {
    215   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    216 
    217   // TODO(csilv): show progress detail in the web view.
    218 }
    219 
    220 void 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 
    227 void 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 
    243 void 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 
    255 void 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