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.
5 #include "chrome/browser/importer/in_process_importer_bridge.h"
8 #include "base/files/file_util.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/importer/external_process_importer_host.h"
12 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
13 #include "chrome/common/importer/imported_bookmark_entry.h"
14 #include "chrome/common/importer/importer_autofill_form_data_entry.h"
15 #include "components/autofill/core/browser/webdata/autofill_entry.h"
16 #include "components/autofill/core/common/password_form.h"
17 #include "components/favicon_base/favicon_usage_data.h"
18 #include "components/search_engines/template_url.h"
19 #include "components/search_engines/template_url_parser.h"
20 #include "components/search_engines/template_url_prepopulate_data.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "ui/base/l10n/l10n_util.h"
25 #include "components/os_crypt/ie7_password_win.h"
32 history::URLRows
ConvertImporterURLRowsToHistoryURLRows(
33 const std::vector
<ImporterURLRow
>& rows
) {
34 history::URLRows converted
;
35 converted
.reserve(rows
.size());
36 for (std::vector
<ImporterURLRow
>::const_iterator it
= rows
.begin();
37 it
!= rows
.end(); ++it
) {
38 history::URLRow
row(it
->url
);
39 row
.set_title(it
->title
);
40 row
.set_visit_count(it
->visit_count
);
41 row
.set_typed_count(it
->typed_count
);
42 row
.set_last_visit(it
->last_visit
);
43 row
.set_hidden(it
->hidden
);
44 converted
.push_back(row
);
49 history::VisitSource
ConvertImporterVisitSourceToHistoryVisitSource(
50 importer::VisitSource visit_source
) {
51 switch (visit_source
) {
52 case importer::VISIT_SOURCE_BROWSED
:
53 return history::SOURCE_BROWSED
;
54 case importer::VISIT_SOURCE_FIREFOX_IMPORTED
:
55 return history::SOURCE_FIREFOX_IMPORTED
;
56 case importer::VISIT_SOURCE_IE_IMPORTED
:
57 return history::SOURCE_IE_IMPORTED
;
58 case importer::VISIT_SOURCE_SAFARI_IMPORTED
:
59 return history::SOURCE_SAFARI_IMPORTED
;
62 return history::SOURCE_SYNCED
;
67 using content::BrowserThread
;
71 // FirefoxURLParameterFilter is used to remove parameter mentioning Firefox from
72 // the search URL when importing search engines.
73 class FirefoxURLParameterFilter
: public TemplateURLParser::ParameterFilter
{
75 FirefoxURLParameterFilter() {}
76 ~FirefoxURLParameterFilter() override
{}
78 // TemplateURLParser::ParameterFilter method.
79 bool KeepParameter(const std::string
& key
,
80 const std::string
& value
) override
{
81 std::string low_value
= base::ToLowerASCII(value
);
82 if (low_value
.find("mozilla") != std::string::npos
||
83 low_value
.find("firefox") != std::string::npos
||
84 low_value
.find("moz:") != std::string::npos
) {
91 DISALLOW_COPY_AND_ASSIGN(FirefoxURLParameterFilter
);
94 // Attempts to create a TemplateURL from the provided data. |title| is optional.
95 // If TemplateURL creation fails, returns NULL.
96 // This function transfers ownership of the created TemplateURL to the caller.
97 TemplateURL
* CreateTemplateURL(const base::string16
& url
,
98 const base::string16
& keyword
,
99 const base::string16
& title
) {
100 if (url
.empty() || keyword
.empty())
102 TemplateURLData data
;
103 data
.SetKeyword(keyword
);
104 // We set short name by using the title if it exists.
105 // Otherwise, we use the shortcut.
106 data
.SetShortName(title
.empty() ? keyword
: title
);
107 data
.SetURL(TemplateURLRef::DisplayURLToURLRef(url
));
108 return new TemplateURL(data
);
111 // Parses the OpenSearch XML files in |xml_files| and populates |search_engines|
112 // with the resulting TemplateURLs.
113 void ParseSearchEnginesFromFirefoxXMLData(
114 const std::vector
<std::string
>& xml_data
,
115 std::vector
<TemplateURL
*>* search_engines
) {
116 DCHECK(search_engines
);
118 typedef std::map
<std::string
, TemplateURL
*> SearchEnginesMap
;
119 SearchEnginesMap search_engine_for_url
;
120 FirefoxURLParameterFilter param_filter
;
121 // The first XML file represents the default search engine in Firefox 3, so we
122 // need to keep it on top of the list.
123 SearchEnginesMap::const_iterator default_turl
= search_engine_for_url
.end();
124 for (std::vector
<std::string
>::const_iterator xml_iter
=
125 xml_data
.begin(); xml_iter
!= xml_data
.end(); ++xml_iter
) {
126 TemplateURL
* template_url
= TemplateURLParser::Parse(
127 UIThreadSearchTermsData(NULL
), true,
128 xml_iter
->data(), xml_iter
->length(), ¶m_filter
);
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
;
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.
141 iter
->second
= template_url
;
143 if (default_turl
== search_engine_for_url
.end())
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
);
154 search_engines
->push_back(t_iter
->second
);
160 InProcessImporterBridge::InProcessImporterBridge(
161 ProfileWriter
* writer
,
162 base::WeakPtr
<ExternalProcessImporterHost
> host
) : writer_(writer
),
166 void InProcessImporterBridge::AddBookmarks(
167 const std::vector
<ImportedBookmarkEntry
>& bookmarks
,
168 const base::string16
& first_folder_name
) {
169 BrowserThread::PostTask(
170 BrowserThread::UI
, FROM_HERE
,
171 base::Bind(&ProfileWriter::AddBookmarks
, writer_
, bookmarks
,
175 void InProcessImporterBridge::AddHomePage(const GURL
& home_page
) {
176 BrowserThread::PostTask(
177 BrowserThread::UI
, FROM_HERE
,
178 base::Bind(&ProfileWriter::AddHomepage
, writer_
, home_page
));
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
;
189 BrowserThread::PostTask(
190 BrowserThread::UI
, FROM_HERE
,
191 base::Bind(&ProfileWriter::AddIE7PasswordInfo
, writer_
,
196 void InProcessImporterBridge::SetFavicons(
197 const favicon_base::FaviconUsageDataList
& favicons
) {
198 BrowserThread::PostTask(
199 BrowserThread::UI
, FROM_HERE
,
200 base::Bind(&ProfileWriter::AddFavicons
, writer_
, favicons
));
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
,
212 base::Bind(&ProfileWriter::AddHistoryPage
,
215 converted_visit_source
));
218 void InProcessImporterBridge::SetKeywords(
219 const std::vector
<importer::SearchEngineInfo
>& search_engines
,
220 bool unique_on_host_and_path
) {
221 ScopedVector
<TemplateURL
> owned_template_urls
;
222 for (const auto& search_engine
: search_engines
) {
223 TemplateURL
* owned_template_url
=
224 CreateTemplateURL(search_engine
.url
,
225 search_engine
.keyword
,
226 search_engine
.display_name
);
227 if (owned_template_url
)
228 owned_template_urls
.push_back(owned_template_url
);
230 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
231 base::Bind(&ProfileWriter::AddKeywords
, writer_
,
232 base::Passed(&owned_template_urls
), unique_on_host_and_path
));
235 void InProcessImporterBridge::SetFirefoxSearchEnginesXMLData(
236 const std::vector
<std::string
>& search_engine_data
) {
237 std::vector
<TemplateURL
*> search_engines
;
238 ParseSearchEnginesFromFirefoxXMLData(search_engine_data
, &search_engines
);
240 ScopedVector
<TemplateURL
> owned_template_urls
;
241 std::copy(search_engines
.begin(), search_engines
.end(),
242 std::back_inserter(owned_template_urls
));
244 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
245 base::Bind(&ProfileWriter::AddKeywords
, writer_
,
246 base::Passed(&owned_template_urls
), true));
249 void InProcessImporterBridge::SetPasswordForm(
250 const autofill::PasswordForm
& form
) {
251 BrowserThread::PostTask(
252 BrowserThread::UI
, FROM_HERE
,
253 base::Bind(&ProfileWriter::AddPasswordForm
, writer_
, form
));
256 void InProcessImporterBridge::SetAutofillFormData(
257 const std::vector
<ImporterAutofillFormDataEntry
>& entries
) {
258 std::vector
<autofill::AutofillEntry
> autofill_entries
;
259 for (size_t i
= 0; i
< entries
.size(); ++i
) {
260 autofill_entries
.push_back(autofill::AutofillEntry(
261 autofill::AutofillKey(entries
[i
].name
, entries
[i
].value
),
262 entries
[i
].first_used
,
263 entries
[i
].last_used
));
266 BrowserThread::PostTask(BrowserThread::UI
,
268 base::Bind(&ProfileWriter::AddAutofillFormDataEntries
,
273 void InProcessImporterBridge::NotifyStarted() {
274 BrowserThread::PostTask(
275 BrowserThread::UI
, FROM_HERE
,
276 base::Bind(&ExternalProcessImporterHost::NotifyImportStarted
, host_
));
279 void InProcessImporterBridge::NotifyItemStarted(importer::ImportItem item
) {
280 BrowserThread::PostTask(
281 BrowserThread::UI
, FROM_HERE
,
282 base::Bind(&ExternalProcessImporterHost::NotifyImportItemStarted
,
286 void InProcessImporterBridge::NotifyItemEnded(importer::ImportItem item
) {
287 BrowserThread::PostTask(
288 BrowserThread::UI
, FROM_HERE
,
289 base::Bind(&ExternalProcessImporterHost::NotifyImportItemEnded
,
293 void InProcessImporterBridge::NotifyEnded() {
294 BrowserThread::PostTask(
295 BrowserThread::UI
, FROM_HERE
,
296 base::Bind(&ExternalProcessImporterHost::NotifyImportEnded
, host_
));
299 base::string16
InProcessImporterBridge::GetLocalizedString(int message_id
) {
300 return l10n_util::GetStringUTF16(message_id
);
303 InProcessImporterBridge::~InProcessImporterBridge() {}