external_process_importer_client.cc revision a93a17c8d99d686bd4a1511e5504e5e6cc9fcadf
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/bookmarks/imported_bookmark_entry.h" 10#include "chrome/browser/browser_process.h" 11#include "chrome/browser/importer/external_process_importer_host.h" 12#include "chrome/browser/importer/firefox_importer_utils.h" 13#include "chrome/browser/importer/importer_host.h" 14#include "chrome/browser/importer/in_process_importer_bridge.h" 15#include "chrome/browser/importer/profile_import_process_messages.h" 16#include "chrome/browser/search_engines/template_url.h" 17#include "chrome/browser/search_engines/template_url_service.h" 18#include "content/public/browser/browser_thread.h" 19#include "content/public/browser/utility_process_host.h" 20#include "grit/generated_resources.h" 21#include "ui/base/l10n/l10n_util.h" 22 23using content::BrowserThread; 24using content::UtilityProcessHost; 25 26ExternalProcessImporterClient::ExternalProcessImporterClient( 27 ExternalProcessImporterHost* importer_host, 28 const importer::SourceProfile& source_profile, 29 uint16 items, 30 InProcessImporterBridge* bridge) 31 : total_bookmarks_count_(0), 32 total_history_rows_count_(0), 33 total_favicons_count_(0), 34 process_importer_host_(importer_host), 35 source_profile_(source_profile), 36 items_(items), 37 bridge_(bridge), 38 cancelled_(false) { 39 process_importer_host_->NotifyImportStarted(); 40} 41 42void ExternalProcessImporterClient::Start() { 43 AddRef(); // balanced in Cleanup. 44 BrowserThread::ID thread_id; 45 CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_id)); 46 BrowserThread::PostTask( 47 BrowserThread::IO, FROM_HERE, 48 base::Bind(&ExternalProcessImporterClient::StartProcessOnIOThread, 49 this, 50 thread_id)); 51} 52 53void ExternalProcessImporterClient::Cancel() { 54 if (cancelled_) 55 return; 56 57 cancelled_ = true; 58 BrowserThread::PostTask( 59 BrowserThread::IO, FROM_HERE, 60 base::Bind( 61 &ExternalProcessImporterClient::CancelImportProcessOnIOThread, 62 this)); 63 Release(); 64} 65 66void ExternalProcessImporterClient::OnProcessCrashed(int exit_code) { 67 if (cancelled_) 68 return; 69 70 process_importer_host_->Cancel(); 71} 72 73bool ExternalProcessImporterClient::OnMessageReceived( 74 const IPC::Message& message) { 75 bool handled = true; 76 IPC_BEGIN_MESSAGE_MAP(ExternalProcessImporterClient, message) 77 // Notification messages about the state of the import process. 78 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Started, 79 OnImportStart) 80 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Finished, 81 OnImportFinished) 82 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_ImportItem_Started, 83 OnImportItemStart) 84 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_ImportItem_Finished, 85 OnImportItemFinished) 86 // Data messages containing items to be written to the user profile. 87 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHistoryImportStart, 88 OnHistoryImportStart) 89 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHistoryImportGroup, 90 OnHistoryImportGroup) 91 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHomePageImportReady, 92 OnHomePageImportReady) 93 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyBookmarksImportStart, 94 OnBookmarksImportStart) 95 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyBookmarksImportGroup, 96 OnBookmarksImportGroup) 97 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFaviconsImportStart, 98 OnFaviconsImportStart) 99 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFaviconsImportGroup, 100 OnFaviconsImportGroup) 101 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyPasswordFormReady, 102 OnPasswordFormImportReady) 103 IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyKeywordsReady, 104 OnKeywordsImportReady) 105 IPC_MESSAGE_UNHANDLED(handled = false) 106 IPC_END_MESSAGE_MAP() 107 return handled; 108} 109 110void ExternalProcessImporterClient::OnImportStart() { 111 if (cancelled_) 112 return; 113 114 bridge_->NotifyStarted(); 115} 116 117void ExternalProcessImporterClient::OnImportFinished( 118 bool succeeded, const std::string& error_msg) { 119 if (cancelled_) 120 return; 121 122 if (!succeeded) 123 LOG(WARNING) << "Import failed. Error: " << error_msg; 124 Cleanup(); 125} 126 127void ExternalProcessImporterClient::OnImportItemStart(int item_data) { 128 if (cancelled_) 129 return; 130 131 bridge_->NotifyItemStarted(static_cast<importer::ImportItem>(item_data)); 132} 133 134void ExternalProcessImporterClient::OnImportItemFinished(int item_data) { 135 if (cancelled_) 136 return; 137 138 importer::ImportItem import_item = 139 static_cast<importer::ImportItem>(item_data); 140 bridge_->NotifyItemEnded(import_item); 141 BrowserThread::PostTask( 142 BrowserThread::IO, FROM_HERE, 143 base::Bind(&ExternalProcessImporterClient::NotifyItemFinishedOnIOThread, 144 this, 145 import_item)); 146} 147 148void ExternalProcessImporterClient::OnHistoryImportStart( 149 size_t total_history_rows_count) { 150 if (cancelled_) 151 return; 152 153 total_history_rows_count_ = total_history_rows_count; 154 history_rows_.reserve(total_history_rows_count); 155} 156 157void ExternalProcessImporterClient::OnHistoryImportGroup( 158 const history::URLRows& history_rows_group, 159 int visit_source) { 160 if (cancelled_) 161 return; 162 163 history_rows_.insert(history_rows_.end(), history_rows_group.begin(), 164 history_rows_group.end()); 165 if (history_rows_.size() == total_history_rows_count_) 166 bridge_->SetHistoryItems(history_rows_, 167 static_cast<history::VisitSource>(visit_source)); 168} 169 170void ExternalProcessImporterClient::OnHomePageImportReady( 171 const GURL& home_page) { 172 if (cancelled_) 173 return; 174 175 bridge_->AddHomePage(home_page); 176} 177 178void ExternalProcessImporterClient::OnBookmarksImportStart( 179 const string16& first_folder_name, 180 size_t total_bookmarks_count) { 181 if (cancelled_) 182 return; 183 184 bookmarks_first_folder_name_ = first_folder_name; 185 total_bookmarks_count_ = total_bookmarks_count; 186 bookmarks_.reserve(total_bookmarks_count); 187} 188 189void ExternalProcessImporterClient::OnBookmarksImportGroup( 190 const std::vector<ImportedBookmarkEntry>& bookmarks_group) { 191 if (cancelled_) 192 return; 193 194 // Collect sets of bookmarks from importer process until we have reached 195 // total_bookmarks_count_: 196 bookmarks_.insert(bookmarks_.end(), bookmarks_group.begin(), 197 bookmarks_group.end()); 198 if (bookmarks_.size() == total_bookmarks_count_) 199 bridge_->AddBookmarks(bookmarks_, bookmarks_first_folder_name_); 200} 201 202void ExternalProcessImporterClient::OnFaviconsImportStart( 203 size_t total_favicons_count) { 204 if (cancelled_) 205 return; 206 207 total_favicons_count_ = total_favicons_count; 208 favicons_.reserve(total_favicons_count); 209} 210 211void ExternalProcessImporterClient::OnFaviconsImportGroup( 212 const std::vector<ImportedFaviconUsage>& favicons_group) { 213 if (cancelled_) 214 return; 215 216 favicons_.insert(favicons_.end(), favicons_group.begin(), 217 favicons_group.end()); 218 if (favicons_.size() == total_favicons_count_) 219 bridge_->SetFavicons(favicons_); 220} 221 222void ExternalProcessImporterClient::OnPasswordFormImportReady( 223 const content::PasswordForm& form) { 224 if (cancelled_) 225 return; 226 227 bridge_->SetPasswordForm(form); 228} 229 230void ExternalProcessImporterClient::OnKeywordsImportReady( 231 const std::vector<TemplateURL*>& template_urls, 232 bool unique_on_host_and_path) { 233 if (cancelled_) 234 return; 235 236 bridge_->SetKeywords(template_urls, unique_on_host_and_path); 237 // The pointers in |template_urls| have now been deleted. 238} 239 240ExternalProcessImporterClient::~ExternalProcessImporterClient() {} 241 242void ExternalProcessImporterClient::Cleanup() { 243 if (cancelled_) 244 return; 245 246 if (process_importer_host_) 247 process_importer_host_->NotifyImportEnded(); 248 Release(); 249} 250 251void ExternalProcessImporterClient::CancelImportProcessOnIOThread() { 252 if (utility_process_host_) 253 utility_process_host_->Send(new ProfileImportProcessMsg_CancelImport()); 254} 255 256void ExternalProcessImporterClient::NotifyItemFinishedOnIOThread( 257 importer::ImportItem import_item) { 258 utility_process_host_->Send( 259 new ProfileImportProcessMsg_ReportImportItemFinished(import_item)); 260} 261 262void ExternalProcessImporterClient::StartProcessOnIOThread( 263 BrowserThread::ID thread_id) { 264 utility_process_host_ = 265 UtilityProcessHost::Create( 266 this, 267 BrowserThread::GetMessageLoopProxyForThread(thread_id))->AsWeakPtr(); 268 utility_process_host_->DisableSandbox(); 269 270#if defined(OS_MACOSX) 271 base::EnvironmentVector env; 272 std::string dylib_path = GetFirefoxDylibPath().value(); 273 if (!dylib_path.empty()) 274 env.push_back(std::make_pair("DYLD_FALLBACK_LIBRARY_PATH", dylib_path)); 275 utility_process_host_->SetEnv(env); 276#endif 277 278 // Dictionary of all localized strings that could be needed by the importer 279 // in the external process. 280 DictionaryValue localized_strings; 281 localized_strings.SetString( 282 base::IntToString(IDS_BOOKMARK_GROUP_FROM_FIREFOX), 283 l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_FIREFOX)); 284 localized_strings.SetString( 285 base::IntToString(IDS_BOOKMARK_GROUP_FROM_SAFARI), 286 l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_SAFARI)); 287 localized_strings.SetString( 288 base::IntToString(IDS_IMPORT_FROM_FIREFOX), 289 l10n_util::GetStringUTF8(IDS_IMPORT_FROM_FIREFOX)); 290 localized_strings.SetString( 291 base::IntToString(IDS_IMPORT_FROM_GOOGLE_TOOLBAR), 292 l10n_util::GetStringUTF8(IDS_IMPORT_FROM_GOOGLE_TOOLBAR)); 293 localized_strings.SetString( 294 base::IntToString(IDS_IMPORT_FROM_SAFARI), 295 l10n_util::GetStringUTF8(IDS_IMPORT_FROM_SAFARI)); 296 localized_strings.SetString( 297 base::IntToString(IDS_BOOKMARK_BAR_FOLDER_NAME), 298 l10n_util::GetStringUTF8(IDS_BOOKMARK_BAR_FOLDER_NAME)); 299 300 utility_process_host_->Send(new ProfileImportProcessMsg_StartImport( 301 source_profile_, items_, localized_strings)); 302} 303