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 "content/public/browser/browser_thread.h"
16 #include "content/public/browser/utility_process_host.h"
17 #include "grit/generated_resources.h"
18 #include "ui/base/l10n/l10n_util.h"
20 using content::BrowserThread
;
21 using content::UtilityProcessHost
;
23 ExternalProcessImporterClient::ExternalProcessImporterClient(
24 base::WeakPtr
<ExternalProcessImporterHost
> importer_host
,
25 const importer::SourceProfile
& source_profile
,
27 InProcessImporterBridge
* bridge
)
28 : total_bookmarks_count_(0),
29 total_history_rows_count_(0),
30 total_favicons_count_(0),
31 process_importer_host_(importer_host
),
32 source_profile_(source_profile
),
36 process_importer_host_
->NotifyImportStarted();
39 void ExternalProcessImporterClient::Start() {
40 AddRef(); // balanced in Cleanup.
41 BrowserThread::ID thread_id
;
42 CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_id
));
43 BrowserThread::PostTask(
44 BrowserThread::IO
, FROM_HERE
,
45 base::Bind(&ExternalProcessImporterClient::StartProcessOnIOThread
,
50 void ExternalProcessImporterClient::Cancel() {
55 BrowserThread::PostTask(
56 BrowserThread::IO
, FROM_HERE
,
58 &ExternalProcessImporterClient::CancelImportProcessOnIOThread
,
63 void ExternalProcessImporterClient::OnProcessCrashed(int exit_code
) {
64 DLOG(ERROR
) << __FUNCTION__
;
68 // If the host is still around, cancel the import; otherwise it means the
69 // import was already cancelled or completed and this message can be dropped.
70 if (process_importer_host_
.get())
71 process_importer_host_
->Cancel();
74 bool ExternalProcessImporterClient::OnMessageReceived(
75 const IPC::Message
& message
) {
77 IPC_BEGIN_MESSAGE_MAP(ExternalProcessImporterClient
, message
)
78 // Notification messages about the state of the import process.
79 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Started
,
81 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Finished
,
83 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_ImportItem_Started
,
85 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_ImportItem_Finished
,
87 // Data messages containing items to be written to the user profile.
88 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHistoryImportStart
,
90 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHistoryImportGroup
,
92 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHomePageImportReady
,
93 OnHomePageImportReady
)
94 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyBookmarksImportStart
,
95 OnBookmarksImportStart
)
96 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyBookmarksImportGroup
,
97 OnBookmarksImportGroup
)
98 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFaviconsImportStart
,
99 OnFaviconsImportStart
)
100 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFaviconsImportGroup
,
101 OnFaviconsImportGroup
)
102 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyPasswordFormReady
,
103 OnPasswordFormImportReady
)
104 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyKeywordsReady
,
105 OnKeywordsImportReady
)
106 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFirefoxSearchEngData
,
107 OnFirefoxSearchEngineDataReceived
)
109 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyIE7PasswordInfo
,
110 OnIE7PasswordReceived
)
112 IPC_MESSAGE_UNHANDLED(handled
= false)
113 IPC_END_MESSAGE_MAP()
117 void ExternalProcessImporterClient::OnImportStart() {
121 bridge_
->NotifyStarted();
124 void ExternalProcessImporterClient::OnImportFinished(
125 bool succeeded
, const std::string
& error_msg
) {
130 LOG(WARNING
) << "Import failed. Error: " << error_msg
;
134 void ExternalProcessImporterClient::OnImportItemStart(int item_data
) {
138 bridge_
->NotifyItemStarted(static_cast<importer::ImportItem
>(item_data
));
141 void ExternalProcessImporterClient::OnImportItemFinished(int item_data
) {
145 importer::ImportItem import_item
=
146 static_cast<importer::ImportItem
>(item_data
);
147 bridge_
->NotifyItemEnded(import_item
);
148 BrowserThread::PostTask(
149 BrowserThread::IO
, FROM_HERE
,
150 base::Bind(&ExternalProcessImporterClient::NotifyItemFinishedOnIOThread
,
155 void ExternalProcessImporterClient::OnHistoryImportStart(
156 size_t total_history_rows_count
) {
160 total_history_rows_count_
= total_history_rows_count
;
161 history_rows_
.reserve(total_history_rows_count
);
164 void ExternalProcessImporterClient::OnHistoryImportGroup(
165 const std::vector
<ImporterURLRow
>& history_rows_group
,
170 history_rows_
.insert(history_rows_
.end(), history_rows_group
.begin(),
171 history_rows_group
.end());
172 if (history_rows_
.size() == total_history_rows_count_
)
173 bridge_
->SetHistoryItems(history_rows_
,
174 static_cast<importer::VisitSource
>(visit_source
));
177 void ExternalProcessImporterClient::OnHomePageImportReady(
178 const GURL
& home_page
) {
182 bridge_
->AddHomePage(home_page
);
185 void ExternalProcessImporterClient::OnBookmarksImportStart(
186 const base::string16
& first_folder_name
,
187 size_t total_bookmarks_count
) {
191 bookmarks_first_folder_name_
= first_folder_name
;
192 total_bookmarks_count_
= total_bookmarks_count
;
193 bookmarks_
.reserve(total_bookmarks_count
);
196 void ExternalProcessImporterClient::OnBookmarksImportGroup(
197 const std::vector
<ImportedBookmarkEntry
>& bookmarks_group
) {
201 // Collect sets of bookmarks from importer process until we have reached
202 // total_bookmarks_count_:
203 bookmarks_
.insert(bookmarks_
.end(), bookmarks_group
.begin(),
204 bookmarks_group
.end());
205 if (bookmarks_
.size() == total_bookmarks_count_
)
206 bridge_
->AddBookmarks(bookmarks_
, bookmarks_first_folder_name_
);
209 void ExternalProcessImporterClient::OnFaviconsImportStart(
210 size_t total_favicons_count
) {
214 total_favicons_count_
= total_favicons_count
;
215 favicons_
.reserve(total_favicons_count
);
218 void ExternalProcessImporterClient::OnFaviconsImportGroup(
219 const std::vector
<ImportedFaviconUsage
>& favicons_group
) {
223 favicons_
.insert(favicons_
.end(), favicons_group
.begin(),
224 favicons_group
.end());
225 if (favicons_
.size() == total_favicons_count_
)
226 bridge_
->SetFavicons(favicons_
);
229 void ExternalProcessImporterClient::OnPasswordFormImportReady(
230 const autofill::PasswordForm
& form
) {
234 bridge_
->SetPasswordForm(form
);
237 void ExternalProcessImporterClient::OnKeywordsImportReady(
238 const std::vector
<importer::URLKeywordInfo
>& url_keywords
,
239 bool unique_on_host_and_path
) {
242 bridge_
->SetKeywords(url_keywords
, unique_on_host_and_path
);
245 void ExternalProcessImporterClient::OnFirefoxSearchEngineDataReceived(
246 const std::vector
<std::string
> search_engine_data
) {
249 bridge_
->SetFirefoxSearchEnginesXMLData(search_engine_data
);
253 void ExternalProcessImporterClient::OnIE7PasswordReceived(
254 const importer::ImporterIE7PasswordInfo
& importer_password_info
) {
257 bridge_
->AddIE7PasswordInfo(importer_password_info
);
261 ExternalProcessImporterClient::~ExternalProcessImporterClient() {}
263 void ExternalProcessImporterClient::Cleanup() {
267 if (process_importer_host_
.get())
268 process_importer_host_
->NotifyImportEnded();
272 void ExternalProcessImporterClient::CancelImportProcessOnIOThread() {
273 if (utility_process_host_
.get())
274 utility_process_host_
->Send(new ProfileImportProcessMsg_CancelImport());
277 void ExternalProcessImporterClient::NotifyItemFinishedOnIOThread(
278 importer::ImportItem import_item
) {
279 utility_process_host_
->Send(
280 new ProfileImportProcessMsg_ReportImportItemFinished(import_item
));
283 void ExternalProcessImporterClient::StartProcessOnIOThread(
284 BrowserThread::ID thread_id
) {
285 utility_process_host_
= UtilityProcessHost::Create(
286 this, BrowserThread::GetMessageLoopProxyForThread(thread_id
).get())
288 utility_process_host_
->DisableSandbox();
290 #if defined(OS_MACOSX)
291 base::EnvironmentMap env
;
292 std::string dylib_path
= GetFirefoxDylibPath().value();
293 if (!dylib_path
.empty())
294 env
["DYLD_FALLBACK_LIBRARY_PATH"] = dylib_path
;
295 utility_process_host_
->SetEnv(env
);
298 // Dictionary of all localized strings that could be needed by the importer
299 // in the external process.
300 base::DictionaryValue localized_strings
;
301 localized_strings
.SetString(
302 base::IntToString(IDS_BOOKMARK_GROUP
),
303 l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP
));
304 localized_strings
.SetString(
305 base::IntToString(IDS_BOOKMARK_GROUP_FROM_FIREFOX
),
306 l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_FIREFOX
));
307 localized_strings
.SetString(
308 base::IntToString(IDS_BOOKMARK_GROUP_FROM_SAFARI
),
309 l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_SAFARI
));
310 localized_strings
.SetString(
311 base::IntToString(IDS_IMPORT_FROM_FIREFOX
),
312 l10n_util::GetStringUTF8(IDS_IMPORT_FROM_FIREFOX
));
313 localized_strings
.SetString(
314 base::IntToString(IDS_IMPORT_FROM_ICEWEASEL
),
315 l10n_util::GetStringUTF8(IDS_IMPORT_FROM_ICEWEASEL
));
316 localized_strings
.SetString(
317 base::IntToString(IDS_IMPORT_FROM_SAFARI
),
318 l10n_util::GetStringUTF8(IDS_IMPORT_FROM_SAFARI
));
319 localized_strings
.SetString(
320 base::IntToString(IDS_BOOKMARK_BAR_FOLDER_NAME
),
321 l10n_util::GetStringUTF8(IDS_BOOKMARK_BAR_FOLDER_NAME
));
323 utility_process_host_
->Send(new ProfileImportProcessMsg_StartImport(
324 source_profile_
, items_
, localized_strings
));