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