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/external_process_importer_client.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/importer/external_process_importer_host.h"
11 #include "chrome/browser/importer/in_process_importer_bridge.h"
12 #include "chrome/common/importer/firefox_importer_utils.h"
13 #include "chrome/common/importer/imported_bookmark_entry.h"
14 #include "chrome/common/importer/profile_import_process_messages.h"
15 #include "chrome/grit/generated_resources.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/utility_process_host.h"
18 #include "grit/components_strings.h"
19 #include "ui/base/l10n/l10n_util.h"
21 using content::BrowserThread
;
22 using content::UtilityProcessHost
;
24 ExternalProcessImporterClient::ExternalProcessImporterClient(
25 base::WeakPtr
<ExternalProcessImporterHost
> importer_host
,
26 const importer::SourceProfile
& source_profile
,
28 InProcessImporterBridge
* bridge
)
29 : total_bookmarks_count_(0),
30 total_history_rows_count_(0),
31 total_favicons_count_(0),
32 process_importer_host_(importer_host
),
33 source_profile_(source_profile
),
37 process_importer_host_
->NotifyImportStarted();
40 void ExternalProcessImporterClient::Start() {
41 AddRef(); // balanced in Cleanup.
42 BrowserThread::ID thread_id
;
43 CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_id
));
44 BrowserThread::PostTask(
45 BrowserThread::IO
, FROM_HERE
,
46 base::Bind(&ExternalProcessImporterClient::StartProcessOnIOThread
,
51 void ExternalProcessImporterClient::Cancel() {
56 BrowserThread::PostTask(
57 BrowserThread::IO
, FROM_HERE
,
59 &ExternalProcessImporterClient::CancelImportProcessOnIOThread
,
64 void ExternalProcessImporterClient::OnProcessCrashed(int exit_code
) {
65 DLOG(ERROR
) << __FUNCTION__
;
69 // If the host is still around, cancel the import; otherwise it means the
70 // import was already cancelled or completed and this message can be dropped.
71 if (process_importer_host_
.get())
72 process_importer_host_
->Cancel();
75 bool ExternalProcessImporterClient::OnMessageReceived(
76 const IPC::Message
& message
) {
78 IPC_BEGIN_MESSAGE_MAP(ExternalProcessImporterClient
, message
)
79 // Notification messages about the state of the import process.
80 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Started
,
82 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Finished
,
84 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_ImportItem_Started
,
86 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_ImportItem_Finished
,
88 // Data messages containing items to be written to the user profile.
89 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHistoryImportStart
,
91 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHistoryImportGroup
,
93 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHomePageImportReady
,
94 OnHomePageImportReady
)
95 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyBookmarksImportStart
,
96 OnBookmarksImportStart
)
97 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyBookmarksImportGroup
,
98 OnBookmarksImportGroup
)
99 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFaviconsImportStart
,
100 OnFaviconsImportStart
)
101 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFaviconsImportGroup
,
102 OnFaviconsImportGroup
)
103 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyPasswordFormReady
,
104 OnPasswordFormImportReady
)
105 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyKeywordsReady
,
106 OnKeywordsImportReady
)
107 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFirefoxSearchEngData
,
108 OnFirefoxSearchEngineDataReceived
)
109 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_AutofillFormDataImportStart
,
110 OnAutofillFormDataImportStart
)
111 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_AutofillFormDataImportGroup
,
112 OnAutofillFormDataImportGroup
)
114 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyIE7PasswordInfo
,
115 OnIE7PasswordReceived
)
117 IPC_MESSAGE_UNHANDLED(handled
= false)
118 IPC_END_MESSAGE_MAP()
122 void ExternalProcessImporterClient::OnImportStart() {
126 bridge_
->NotifyStarted();
129 void ExternalProcessImporterClient::OnImportFinished(
130 bool succeeded
, const std::string
& error_msg
) {
135 LOG(WARNING
) << "Import failed. Error: " << error_msg
;
139 void ExternalProcessImporterClient::OnImportItemStart(int item_data
) {
143 bridge_
->NotifyItemStarted(static_cast<importer::ImportItem
>(item_data
));
146 void ExternalProcessImporterClient::OnImportItemFinished(int item_data
) {
150 importer::ImportItem import_item
=
151 static_cast<importer::ImportItem
>(item_data
);
152 bridge_
->NotifyItemEnded(import_item
);
153 BrowserThread::PostTask(
154 BrowserThread::IO
, FROM_HERE
,
155 base::Bind(&ExternalProcessImporterClient::NotifyItemFinishedOnIOThread
,
160 void ExternalProcessImporterClient::OnHistoryImportStart(
161 size_t total_history_rows_count
) {
165 total_history_rows_count_
= total_history_rows_count
;
166 history_rows_
.reserve(total_history_rows_count
);
169 void ExternalProcessImporterClient::OnHistoryImportGroup(
170 const std::vector
<ImporterURLRow
>& history_rows_group
,
175 history_rows_
.insert(history_rows_
.end(), history_rows_group
.begin(),
176 history_rows_group
.end());
177 if (history_rows_
.size() >= total_history_rows_count_
)
178 bridge_
->SetHistoryItems(history_rows_
,
179 static_cast<importer::VisitSource
>(visit_source
));
182 void ExternalProcessImporterClient::OnHomePageImportReady(
183 const GURL
& home_page
) {
187 bridge_
->AddHomePage(home_page
);
190 void ExternalProcessImporterClient::OnBookmarksImportStart(
191 const base::string16
& first_folder_name
,
192 size_t total_bookmarks_count
) {
196 bookmarks_first_folder_name_
= first_folder_name
;
197 total_bookmarks_count_
= total_bookmarks_count
;
198 bookmarks_
.reserve(total_bookmarks_count
);
201 void ExternalProcessImporterClient::OnBookmarksImportGroup(
202 const std::vector
<ImportedBookmarkEntry
>& bookmarks_group
) {
206 // Collect sets of bookmarks from importer process until we have reached
207 // total_bookmarks_count_:
208 bookmarks_
.insert(bookmarks_
.end(), bookmarks_group
.begin(),
209 bookmarks_group
.end());
210 if (bookmarks_
.size() >= total_bookmarks_count_
)
211 bridge_
->AddBookmarks(bookmarks_
, bookmarks_first_folder_name_
);
214 void ExternalProcessImporterClient::OnFaviconsImportStart(
215 size_t total_favicons_count
) {
219 total_favicons_count_
= total_favicons_count
;
220 favicons_
.reserve(total_favicons_count
);
223 void ExternalProcessImporterClient::OnFaviconsImportGroup(
224 const favicon_base::FaviconUsageDataList
& favicons_group
) {
228 favicons_
.insert(favicons_
.end(), favicons_group
.begin(),
229 favicons_group
.end());
230 if (favicons_
.size() >= total_favicons_count_
)
231 bridge_
->SetFavicons(favicons_
);
234 void ExternalProcessImporterClient::OnPasswordFormImportReady(
235 const autofill::PasswordForm
& form
) {
239 bridge_
->SetPasswordForm(form
);
242 void ExternalProcessImporterClient::OnKeywordsImportReady(
243 const std::vector
<importer::SearchEngineInfo
>& search_engines
,
244 bool unique_on_host_and_path
) {
247 bridge_
->SetKeywords(search_engines
, unique_on_host_and_path
);
250 void ExternalProcessImporterClient::OnFirefoxSearchEngineDataReceived(
251 const std::vector
<std::string
> search_engine_data
) {
254 bridge_
->SetFirefoxSearchEnginesXMLData(search_engine_data
);
257 void ExternalProcessImporterClient::OnAutofillFormDataImportStart(
258 size_t total_autofill_form_data_entry_count
) {
262 total_autofill_form_data_entry_count_
= total_autofill_form_data_entry_count
;
263 autofill_form_data_
.reserve(total_autofill_form_data_entry_count
);
266 void ExternalProcessImporterClient::OnAutofillFormDataImportGroup(
267 const std::vector
<ImporterAutofillFormDataEntry
>&
268 autofill_form_data_entry_group
) {
272 autofill_form_data_
.insert(autofill_form_data_
.end(),
273 autofill_form_data_entry_group
.begin(),
274 autofill_form_data_entry_group
.end());
275 if (autofill_form_data_
.size() >= total_autofill_form_data_entry_count_
)
276 bridge_
->SetAutofillFormData(autofill_form_data_
);
280 void ExternalProcessImporterClient::OnIE7PasswordReceived(
281 const importer::ImporterIE7PasswordInfo
& importer_password_info
) {
284 bridge_
->AddIE7PasswordInfo(importer_password_info
);
288 ExternalProcessImporterClient::~ExternalProcessImporterClient() {}
290 void ExternalProcessImporterClient::Cleanup() {
294 if (process_importer_host_
.get())
295 process_importer_host_
->NotifyImportEnded();
299 void ExternalProcessImporterClient::CancelImportProcessOnIOThread() {
300 if (utility_process_host_
.get())
301 utility_process_host_
->Send(new ProfileImportProcessMsg_CancelImport());
304 void ExternalProcessImporterClient::NotifyItemFinishedOnIOThread(
305 importer::ImportItem import_item
) {
306 utility_process_host_
->Send(
307 new ProfileImportProcessMsg_ReportImportItemFinished(import_item
));
310 void ExternalProcessImporterClient::StartProcessOnIOThread(
311 BrowserThread::ID thread_id
) {
312 utility_process_host_
= UtilityProcessHost::Create(
313 this, BrowserThread::GetMessageLoopProxyForThread(thread_id
).get())
315 utility_process_host_
->SetName(l10n_util::GetStringUTF16(
316 IDS_UTILITY_PROCESS_PROFILE_IMPORTER_NAME
));
317 utility_process_host_
->DisableSandbox();
319 #if defined(OS_MACOSX)
320 base::EnvironmentMap env
;
321 std::string dylib_path
= GetFirefoxDylibPath().value();
322 if (!dylib_path
.empty())
323 env
["DYLD_FALLBACK_LIBRARY_PATH"] = dylib_path
;
324 utility_process_host_
->SetEnv(env
);
327 // Dictionary of all localized strings that could be needed by the importer
328 // in the external process.
329 base::DictionaryValue localized_strings
;
330 localized_strings
.SetString(
331 base::IntToString(IDS_BOOKMARK_GROUP
),
332 l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP
));
333 localized_strings
.SetString(
334 base::IntToString(IDS_BOOKMARK_GROUP_FROM_FIREFOX
),
335 l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_FIREFOX
));
336 localized_strings
.SetString(
337 base::IntToString(IDS_BOOKMARK_GROUP_FROM_SAFARI
),
338 l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_SAFARI
));
339 localized_strings
.SetString(
340 base::IntToString(IDS_IMPORT_FROM_FIREFOX
),
341 l10n_util::GetStringUTF8(IDS_IMPORT_FROM_FIREFOX
));
342 localized_strings
.SetString(
343 base::IntToString(IDS_IMPORT_FROM_ICEWEASEL
),
344 l10n_util::GetStringUTF8(IDS_IMPORT_FROM_ICEWEASEL
));
345 localized_strings
.SetString(
346 base::IntToString(IDS_IMPORT_FROM_SAFARI
),
347 l10n_util::GetStringUTF8(IDS_IMPORT_FROM_SAFARI
));
348 localized_strings
.SetString(
349 base::IntToString(IDS_BOOKMARK_BAR_FOLDER_NAME
),
350 l10n_util::GetStringUTF8(IDS_BOOKMARK_BAR_FOLDER_NAME
));
352 utility_process_host_
->Send(new ProfileImportProcessMsg_StartImport(
353 source_profile_
, items_
, localized_strings
));