Home | History | Annotate | Download | only in importer
      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/importer/in_process_importer_bridge.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/file_util.h"
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "chrome/browser/importer/external_process_importer_host.h"
     11 #include "chrome/browser/search_engines/template_url.h"
     12 #include "chrome/browser/search_engines/template_url_parser.h"
     13 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
     14 #include "chrome/browser/search_engines/template_url_service.h"
     15 #include "chrome/common/importer/imported_bookmark_entry.h"
     16 #include "chrome/common/importer/imported_favicon_usage.h"
     17 #include "content/public/browser/browser_thread.h"
     18 #include "content/public/common/password_form.h"
     19 #include "ui/base/l10n/l10n_util.h"
     20 
     21 #if defined(OS_WIN)
     22 #include "components/webdata/encryptor/ie7_password.h"
     23 #endif
     24 
     25 #include <iterator>
     26 
     27 namespace {
     28 
     29 history::URLRows ConvertImporterURLRowsToHistoryURLRows(
     30     const std::vector<ImporterURLRow>& rows) {
     31   history::URLRows converted;
     32   converted.reserve(rows.size());
     33   for (std::vector<ImporterURLRow>::const_iterator it = rows.begin();
     34        it != rows.end(); ++it) {
     35     history::URLRow row(it->url);
     36     row.set_title(it->title);
     37     row.set_visit_count(it->visit_count);
     38     row.set_typed_count(it->typed_count);
     39     row.set_last_visit(it->last_visit);
     40     row.set_hidden(it->hidden);
     41     converted.push_back(row);
     42   }
     43   return converted;
     44 }
     45 
     46 history::VisitSource ConvertImporterVisitSourceToHistoryVisitSource(
     47     importer::VisitSource visit_source) {
     48   switch (visit_source) {
     49     case importer::VISIT_SOURCE_BROWSED:
     50       return history::SOURCE_BROWSED;
     51     case importer::VISIT_SOURCE_FIREFOX_IMPORTED:
     52       return history::SOURCE_FIREFOX_IMPORTED;
     53     case importer::VISIT_SOURCE_IE_IMPORTED:
     54       return history::SOURCE_IE_IMPORTED;
     55     case importer::VISIT_SOURCE_SAFARI_IMPORTED:
     56       return history::SOURCE_SAFARI_IMPORTED;
     57   }
     58   NOTREACHED();
     59   return history::SOURCE_SYNCED;
     60 }
     61 
     62 }  // namespace
     63 
     64 using content::BrowserThread;
     65 
     66 namespace {
     67 
     68 // FirefoxURLParameterFilter is used to remove parameter mentioning Firefox from
     69 // the search URL when importing search engines.
     70 class FirefoxURLParameterFilter : public TemplateURLParser::ParameterFilter {
     71  public:
     72   FirefoxURLParameterFilter() {}
     73   virtual ~FirefoxURLParameterFilter() {}
     74 
     75   // TemplateURLParser::ParameterFilter method.
     76   virtual bool KeepParameter(const std::string& key,
     77                              const std::string& value) OVERRIDE {
     78     std::string low_value = StringToLowerASCII(value);
     79     if (low_value.find("mozilla") != std::string::npos ||
     80         low_value.find("firefox") != std::string::npos ||
     81         low_value.find("moz:") != std::string::npos) {
     82       return false;
     83     }
     84     return true;
     85   }
     86 
     87  private:
     88   DISALLOW_COPY_AND_ASSIGN(FirefoxURLParameterFilter);
     89 };
     90 
     91 // Creates a TemplateURL with the |keyword| and |url|. |title| may be empty.
     92 // This function transfers ownership of the created TemplateURL to the caller.
     93 TemplateURL* CreateTemplateURL(const string16& title,
     94                                const string16& keyword,
     95                                const GURL& url) {
     96   // Skip if the url is invalid.
     97   if (!url.is_valid())
     98     return NULL;
     99 
    100   TemplateURLData data;
    101   if (keyword.empty())
    102     data.SetKeyword(TemplateURLService::GenerateKeyword(url));
    103   else
    104     data.SetKeyword(keyword);
    105   // We set short name by using the title if it exists.
    106   // Otherwise, we use the shortcut.
    107   data.short_name = title.empty() ? keyword : title;
    108   data.SetURL(TemplateURLRef::DisplayURLToURLRef(UTF8ToUTF16(url.spec())));
    109   return new TemplateURL(NULL, data);
    110 }
    111 
    112 // Parses the OpenSearch XML files in |xml_files| and populates |search_engines|
    113 // with the resulting TemplateURLs.
    114 void ParseSearchEnginesFromFirefoxXMLData(
    115     const std::vector<std::string>& xml_data,
    116     std::vector<TemplateURL*>* search_engines) {
    117   DCHECK(search_engines);
    118 
    119   typedef std::map<std::string, TemplateURL*> SearchEnginesMap;
    120   SearchEnginesMap search_engine_for_url;
    121   FirefoxURLParameterFilter param_filter;
    122   // The first XML file represents the default search engine in Firefox 3, so we
    123   // need to keep it on top of the list.
    124   SearchEnginesMap::const_iterator default_turl = search_engine_for_url.end();
    125   for (std::vector<std::string>::const_iterator xml_iter =
    126            xml_data.begin(); xml_iter != xml_data.end(); ++xml_iter) {
    127     TemplateURL* template_url = TemplateURLParser::Parse(NULL, true,
    128         xml_iter->data(), xml_iter->length(), &param_filter);
    129     if (template_url) {
    130       SearchEnginesMap::iterator iter =
    131           search_engine_for_url.find(template_url->url());
    132       if (iter == search_engine_for_url.end()) {
    133         iter = search_engine_for_url.insert(
    134             std::make_pair(template_url->url(), template_url)).first;
    135       } else {
    136         // We have already found a search engine with the same URL.  We give
    137         // priority to the latest one found, as GetSearchEnginesXMLFiles()
    138         // returns a vector with first Firefox default search engines and then
    139         // the user's ones.  We want to give priority to the user ones.
    140         delete iter->second;
    141         iter->second = template_url;
    142       }
    143       if (default_turl == search_engine_for_url.end())
    144         default_turl = iter;
    145     }
    146   }
    147 
    148   // Put the results in the |search_engines| vector.
    149   for (SearchEnginesMap::iterator t_iter = search_engine_for_url.begin();
    150        t_iter != search_engine_for_url.end(); ++t_iter) {
    151     if (t_iter == default_turl)
    152       search_engines->insert(search_engines->begin(), default_turl->second);
    153     else
    154       search_engines->push_back(t_iter->second);
    155   }
    156 }
    157 
    158 }  // namespace
    159 
    160 InProcessImporterBridge::InProcessImporterBridge(
    161     ProfileWriter* writer,
    162     base::WeakPtr<ExternalProcessImporterHost> host) : writer_(writer),
    163                                                        host_(host) {
    164 }
    165 
    166 void InProcessImporterBridge::AddBookmarks(
    167     const std::vector<ImportedBookmarkEntry>& bookmarks,
    168     const string16& first_folder_name) {
    169   BrowserThread::PostTask(
    170       BrowserThread::UI, FROM_HERE,
    171       base::Bind(&ProfileWriter::AddBookmarks, writer_, bookmarks,
    172                  first_folder_name));
    173 }
    174 
    175 void InProcessImporterBridge::AddHomePage(const GURL& home_page) {
    176   BrowserThread::PostTask(
    177       BrowserThread::UI, FROM_HERE,
    178       base::Bind(&ProfileWriter::AddHomepage, writer_, home_page));
    179 }
    180 
    181 #if defined(OS_WIN)
    182 void InProcessImporterBridge::AddIE7PasswordInfo(
    183     const importer::ImporterIE7PasswordInfo& password_info) {
    184   IE7PasswordInfo ie7_password_info;
    185   ie7_password_info.url_hash = password_info.url_hash;
    186   ie7_password_info.encrypted_data = password_info.encrypted_data;
    187   ie7_password_info.date_created = password_info.date_created;
    188 
    189   BrowserThread::PostTask(
    190       BrowserThread::UI, FROM_HERE,
    191       base::Bind(&ProfileWriter::AddIE7PasswordInfo, writer_,
    192                  ie7_password_info));
    193 }
    194 #endif  // OS_WIN
    195 
    196 void InProcessImporterBridge::SetFavicons(
    197     const std::vector<ImportedFaviconUsage>& favicons) {
    198   BrowserThread::PostTask(
    199       BrowserThread::UI, FROM_HERE,
    200       base::Bind(&ProfileWriter::AddFavicons, writer_, favicons));
    201 }
    202 
    203 void InProcessImporterBridge::SetHistoryItems(
    204     const std::vector<ImporterURLRow>& rows,
    205     importer::VisitSource visit_source) {
    206   history::URLRows converted_rows =
    207       ConvertImporterURLRowsToHistoryURLRows(rows);
    208   history::VisitSource converted_visit_source =
    209       ConvertImporterVisitSourceToHistoryVisitSource(visit_source);
    210   BrowserThread::PostTask(BrowserThread::UI,
    211                           FROM_HERE,
    212                           base::Bind(&ProfileWriter::AddHistoryPage,
    213                                      writer_,
    214                                      converted_rows,
    215                                      converted_visit_source));
    216 }
    217 
    218 void InProcessImporterBridge::SetKeywords(
    219     const std::vector<importer::URLKeywordInfo>& url_keywords,
    220     bool unique_on_host_and_path) {
    221   ScopedVector<TemplateURL> owned_template_urls;
    222   for (size_t i = 0; i < url_keywords.size(); ++i) {
    223     owned_template_urls.push_back(
    224         CreateTemplateURL(url_keywords[i].display_name,
    225                           url_keywords[i].keyword,
    226                           url_keywords[i].url));
    227   }
    228   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
    229       base::Bind(&ProfileWriter::AddKeywords, writer_,
    230                  base::Passed(&owned_template_urls), unique_on_host_and_path));
    231 }
    232 
    233 void InProcessImporterBridge::SetFirefoxSearchEnginesXMLData(
    234     const std::vector<std::string>& search_engine_data) {
    235   std::vector<TemplateURL*> search_engines;
    236   ParseSearchEnginesFromFirefoxXMLData(search_engine_data, &search_engines);
    237 
    238   ScopedVector<TemplateURL> owned_template_urls;
    239   std::copy(search_engines.begin(), search_engines.end(),
    240             std::back_inserter(owned_template_urls));
    241 
    242   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
    243       base::Bind(&ProfileWriter::AddKeywords, writer_,
    244                  base::Passed(&owned_template_urls), true));
    245 }
    246 
    247 void InProcessImporterBridge::SetPasswordForm(
    248     const content::PasswordForm& form) {
    249   BrowserThread::PostTask(
    250       BrowserThread::UI, FROM_HERE,
    251       base::Bind(&ProfileWriter::AddPasswordForm, writer_, form));
    252 }
    253 
    254 void InProcessImporterBridge::NotifyStarted() {
    255   BrowserThread::PostTask(
    256       BrowserThread::UI, FROM_HERE,
    257       base::Bind(&ExternalProcessImporterHost::NotifyImportStarted, host_));
    258 }
    259 
    260 void InProcessImporterBridge::NotifyItemStarted(importer::ImportItem item) {
    261   BrowserThread::PostTask(
    262       BrowserThread::UI, FROM_HERE,
    263       base::Bind(&ExternalProcessImporterHost::NotifyImportItemStarted,
    264                  host_, item));
    265 }
    266 
    267 void InProcessImporterBridge::NotifyItemEnded(importer::ImportItem item) {
    268   BrowserThread::PostTask(
    269       BrowserThread::UI, FROM_HERE,
    270       base::Bind(&ExternalProcessImporterHost::NotifyImportItemEnded,
    271                  host_, item));
    272 }
    273 
    274 void InProcessImporterBridge::NotifyEnded() {
    275   BrowserThread::PostTask(
    276       BrowserThread::UI, FROM_HERE,
    277       base::Bind(&ExternalProcessImporterHost::NotifyImportEnded, host_));
    278 }
    279 
    280 string16 InProcessImporterBridge::GetLocalizedString(int message_id) {
    281   return l10n_util::GetStringUTF16(message_id);
    282 }
    283 
    284 InProcessImporterBridge::~InProcessImporterBridge() {}
    285