d9e781a776edbdc348232b117b2e9a1baf052b5a
[platform/framework/web/crosswalk.git] / src / chrome / browser / importer / external_process_importer_client.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/external_process_importer_client.h"
6
7 #include "base/bind.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"
19
20 using content::BrowserThread;
21 using content::UtilityProcessHost;
22
23 ExternalProcessImporterClient::ExternalProcessImporterClient(
24     base::WeakPtr<ExternalProcessImporterHost> importer_host,
25     const importer::SourceProfile& source_profile,
26     uint16 items,
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),
33       items_(items),
34       bridge_(bridge),
35       cancelled_(false) {
36   process_importer_host_->NotifyImportStarted();
37 }
38
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,
46                  this,
47                  thread_id));
48 }
49
50 void ExternalProcessImporterClient::Cancel() {
51   if (cancelled_)
52     return;
53
54   cancelled_ = true;
55   BrowserThread::PostTask(
56       BrowserThread::IO, FROM_HERE,
57       base::Bind(
58           &ExternalProcessImporterClient::CancelImportProcessOnIOThread,
59           this));
60   Release();
61 }
62
63 void ExternalProcessImporterClient::OnProcessCrashed(int exit_code) {
64   DLOG(ERROR) << __FUNCTION__;
65   if (cancelled_)
66     return;
67
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();
72 }
73
74 bool ExternalProcessImporterClient::OnMessageReceived(
75     const IPC::Message& message) {
76   bool handled = true;
77   IPC_BEGIN_MESSAGE_MAP(ExternalProcessImporterClient, message)
78     // Notification messages about the state of the import process.
79     IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Started,
80                         OnImportStart)
81     IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Finished,
82                         OnImportFinished)
83     IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_ImportItem_Started,
84                         OnImportItemStart)
85     IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_ImportItem_Finished,
86                         OnImportItemFinished)
87     // Data messages containing items to be written to the user profile.
88     IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHistoryImportStart,
89                         OnHistoryImportStart)
90     IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHistoryImportGroup,
91                         OnHistoryImportGroup)
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)
108 #if defined(OS_WIN)
109     IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyIE7PasswordInfo,
110                         OnIE7PasswordReceived)
111 #endif
112     IPC_MESSAGE_UNHANDLED(handled = false)
113   IPC_END_MESSAGE_MAP()
114   return handled;
115 }
116
117 void ExternalProcessImporterClient::OnImportStart() {
118   if (cancelled_)
119     return;
120
121   bridge_->NotifyStarted();
122 }
123
124 void ExternalProcessImporterClient::OnImportFinished(
125     bool succeeded, const std::string& error_msg) {
126   if (cancelled_)
127     return;
128
129   if (!succeeded)
130     LOG(WARNING) << "Import failed.  Error: " << error_msg;
131   Cleanup();
132 }
133
134 void ExternalProcessImporterClient::OnImportItemStart(int item_data) {
135   if (cancelled_)
136     return;
137
138   bridge_->NotifyItemStarted(static_cast<importer::ImportItem>(item_data));
139 }
140
141 void ExternalProcessImporterClient::OnImportItemFinished(int item_data) {
142   if (cancelled_)
143     return;
144
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,
151                  this,
152                  import_item));
153 }
154
155 void ExternalProcessImporterClient::OnHistoryImportStart(
156     size_t total_history_rows_count) {
157   if (cancelled_)
158     return;
159
160   total_history_rows_count_ = total_history_rows_count;
161   history_rows_.reserve(total_history_rows_count);
162 }
163
164 void ExternalProcessImporterClient::OnHistoryImportGroup(
165     const std::vector<ImporterURLRow>& history_rows_group,
166     int visit_source) {
167   if (cancelled_)
168     return;
169
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));
175 }
176
177 void ExternalProcessImporterClient::OnHomePageImportReady(
178     const GURL& home_page) {
179   if (cancelled_)
180     return;
181
182   bridge_->AddHomePage(home_page);
183 }
184
185 void ExternalProcessImporterClient::OnBookmarksImportStart(
186     const base::string16& first_folder_name,
187     size_t total_bookmarks_count) {
188   if (cancelled_)
189     return;
190
191   bookmarks_first_folder_name_ = first_folder_name;
192   total_bookmarks_count_ = total_bookmarks_count;
193   bookmarks_.reserve(total_bookmarks_count);
194 }
195
196 void ExternalProcessImporterClient::OnBookmarksImportGroup(
197     const std::vector<ImportedBookmarkEntry>& bookmarks_group) {
198   if (cancelled_)
199     return;
200
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_);
207 }
208
209 void ExternalProcessImporterClient::OnFaviconsImportStart(
210     size_t total_favicons_count) {
211   if (cancelled_)
212     return;
213
214   total_favicons_count_ = total_favicons_count;
215   favicons_.reserve(total_favicons_count);
216 }
217
218 void ExternalProcessImporterClient::OnFaviconsImportGroup(
219     const std::vector<ImportedFaviconUsage>& favicons_group) {
220   if (cancelled_)
221     return;
222
223   favicons_.insert(favicons_.end(), favicons_group.begin(),
224                     favicons_group.end());
225   if (favicons_.size() == total_favicons_count_)
226     bridge_->SetFavicons(favicons_);
227 }
228
229 void ExternalProcessImporterClient::OnPasswordFormImportReady(
230     const autofill::PasswordForm& form) {
231   if (cancelled_)
232     return;
233
234   bridge_->SetPasswordForm(form);
235 }
236
237 void ExternalProcessImporterClient::OnKeywordsImportReady(
238     const std::vector<importer::URLKeywordInfo>& url_keywords,
239     bool unique_on_host_and_path) {
240   if (cancelled_)
241     return;
242   bridge_->SetKeywords(url_keywords, unique_on_host_and_path);
243 }
244
245 void ExternalProcessImporterClient::OnFirefoxSearchEngineDataReceived(
246     const std::vector<std::string> search_engine_data) {
247   if (cancelled_)
248     return;
249   bridge_->SetFirefoxSearchEnginesXMLData(search_engine_data);
250 }
251
252 #if defined(OS_WIN)
253 void ExternalProcessImporterClient::OnIE7PasswordReceived(
254     const importer::ImporterIE7PasswordInfo& importer_password_info) {
255   if (cancelled_)
256     return;
257   bridge_->AddIE7PasswordInfo(importer_password_info);
258 }
259 #endif
260
261 ExternalProcessImporterClient::~ExternalProcessImporterClient() {}
262
263 void ExternalProcessImporterClient::Cleanup() {
264   if (cancelled_)
265     return;
266
267   if (process_importer_host_.get())
268     process_importer_host_->NotifyImportEnded();
269   Release();
270 }
271
272 void ExternalProcessImporterClient::CancelImportProcessOnIOThread() {
273   if (utility_process_host_.get())
274     utility_process_host_->Send(new ProfileImportProcessMsg_CancelImport());
275 }
276
277 void ExternalProcessImporterClient::NotifyItemFinishedOnIOThread(
278     importer::ImportItem import_item) {
279   utility_process_host_->Send(
280       new ProfileImportProcessMsg_ReportImportItemFinished(import_item));
281 }
282
283 void ExternalProcessImporterClient::StartProcessOnIOThread(
284     BrowserThread::ID thread_id) {
285   utility_process_host_ = UtilityProcessHost::Create(
286       this, BrowserThread::GetMessageLoopProxyForThread(thread_id).get())
287       ->AsWeakPtr();
288   utility_process_host_->DisableSandbox();
289
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);
296 #endif
297
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));
322
323   utility_process_host_->Send(new ProfileImportProcessMsg_StartImport(
324       source_profile_, items_, localized_strings));
325 }