1 // Copyright (c) 2011 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 "chrome/browser/browser_process.h" 8 #include "chrome/browser/importer/external_process_importer_host.h" 9 #include "chrome/browser/importer/importer_host.h" 10 #include "chrome/browser/importer/in_process_importer_bridge.h" 11 #include "chrome/browser/importer/profile_import_process_host.h" 12 #include "chrome/browser/search_engines/template_url.h" 13 #include "chrome/browser/search_engines/template_url_model.h" 14 #include "content/browser/browser_thread.h" 15 #include "content/browser/renderer_host/resource_dispatcher_host.h" 16 17 ExternalProcessImporterClient::ExternalProcessImporterClient( 18 ExternalProcessImporterHost* importer_host, 19 const importer::SourceProfile& source_profile, 20 uint16 items, 21 InProcessImporterBridge* bridge, 22 bool import_to_bookmark_bar) 23 : bookmarks_options_(0), 24 total_bookmarks_count_(0), 25 total_history_rows_count_(0), 26 total_favicons_count_(0), 27 process_importer_host_(importer_host), 28 profile_import_process_host_(NULL), 29 source_profile_(source_profile), 30 items_(items), 31 import_to_bookmark_bar_(import_to_bookmark_bar), 32 bridge_(bridge), 33 cancelled_(false) { 34 bridge_->AddRef(); 35 process_importer_host_->NotifyImportStarted(); 36 } 37 38 ExternalProcessImporterClient::~ExternalProcessImporterClient() { 39 bridge_->Release(); 40 } 41 42 void 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 NewRunnableMethod( 49 this, 50 &ExternalProcessImporterClient::StartImportProcessOnIOThread, 51 thread_id)); 52 } 53 54 void ExternalProcessImporterClient::Cancel() { 55 if (cancelled_) 56 return; 57 58 cancelled_ = true; 59 if (profile_import_process_host_) { 60 BrowserThread::PostTask( 61 BrowserThread::IO, FROM_HERE, 62 NewRunnableMethod(this, 63 &ExternalProcessImporterClient::CancelImportProcessOnIOThread)); 64 } 65 Release(); 66 } 67 68 void ExternalProcessImporterClient::Cleanup() { 69 if (cancelled_) 70 return; 71 72 if (process_importer_host_) 73 process_importer_host_->NotifyImportEnded(); 74 Release(); 75 } 76 77 void ExternalProcessImporterClient::StartImportProcessOnIOThread( 78 BrowserThread::ID thread_id) { 79 profile_import_process_host_ = 80 new ProfileImportProcessHost(this, thread_id); 81 profile_import_process_host_->StartProfileImportProcess( 82 source_profile_, items_, import_to_bookmark_bar_); 83 } 84 85 void ExternalProcessImporterClient::CancelImportProcessOnIOThread() { 86 profile_import_process_host_->CancelProfileImportProcess(); 87 } 88 89 void ExternalProcessImporterClient::NotifyItemFinishedOnIOThread( 90 importer::ImportItem import_item) { 91 profile_import_process_host_->ReportImportItemFinished(import_item); 92 } 93 94 void ExternalProcessImporterClient::OnProcessCrashed(int exit_code) { 95 if (cancelled_) 96 return; 97 98 process_importer_host_->Cancel(); 99 } 100 101 void ExternalProcessImporterClient::OnImportStart() { 102 if (cancelled_) 103 return; 104 105 bridge_->NotifyStarted(); 106 } 107 108 void ExternalProcessImporterClient::OnImportFinished( 109 bool succeeded, const std::string& error_msg) { 110 if (cancelled_) 111 return; 112 113 if (!succeeded) 114 LOG(WARNING) << "Import failed. Error: " << error_msg; 115 Cleanup(); 116 } 117 118 void ExternalProcessImporterClient::OnImportItemStart(int item_data) { 119 if (cancelled_) 120 return; 121 122 bridge_->NotifyItemStarted(static_cast<importer::ImportItem>(item_data)); 123 } 124 125 void ExternalProcessImporterClient::OnImportItemFinished(int item_data) { 126 if (cancelled_) 127 return; 128 129 importer::ImportItem import_item = 130 static_cast<importer::ImportItem>(item_data); 131 bridge_->NotifyItemEnded(import_item); 132 BrowserThread::PostTask( 133 BrowserThread::IO, FROM_HERE, 134 NewRunnableMethod(this, 135 &ExternalProcessImporterClient::NotifyItemFinishedOnIOThread, 136 import_item)); 137 } 138 139 void ExternalProcessImporterClient::OnHistoryImportStart( 140 size_t total_history_rows_count) { 141 if (cancelled_) 142 return; 143 144 total_history_rows_count_ = total_history_rows_count; 145 history_rows_.reserve(total_history_rows_count); 146 } 147 148 void ExternalProcessImporterClient::OnHistoryImportGroup( 149 const std::vector<history::URLRow>& history_rows_group, 150 int visit_source) { 151 if (cancelled_) 152 return; 153 154 history_rows_.insert(history_rows_.end(), history_rows_group.begin(), 155 history_rows_group.end()); 156 if (history_rows_.size() == total_history_rows_count_) 157 bridge_->SetHistoryItems(history_rows_, 158 static_cast<history::VisitSource>(visit_source)); 159 } 160 161 void ExternalProcessImporterClient::OnHomePageImportReady( 162 const GURL& home_page) { 163 if (cancelled_) 164 return; 165 166 bridge_->AddHomePage(home_page); 167 } 168 169 void ExternalProcessImporterClient::OnBookmarksImportStart( 170 const string16& first_folder_name, 171 int options, 172 size_t total_bookmarks_count) { 173 if (cancelled_) 174 return; 175 176 bookmarks_first_folder_name_ = first_folder_name; 177 bookmarks_options_ = options; 178 total_bookmarks_count_ = total_bookmarks_count; 179 bookmarks_.reserve(total_bookmarks_count); 180 } 181 182 void ExternalProcessImporterClient::OnBookmarksImportGroup( 183 const std::vector<ProfileWriter::BookmarkEntry>& bookmarks_group) { 184 if (cancelled_) 185 return; 186 187 // Collect sets of bookmarks from importer process until we have reached 188 // total_bookmarks_count_: 189 bookmarks_.insert(bookmarks_.end(), bookmarks_group.begin(), 190 bookmarks_group.end()); 191 if (bookmarks_.size() == total_bookmarks_count_) { 192 bridge_->AddBookmarkEntries(bookmarks_, bookmarks_first_folder_name_, 193 bookmarks_options_); 194 } 195 } 196 197 void ExternalProcessImporterClient::OnFaviconsImportStart( 198 size_t total_favicons_count) { 199 if (cancelled_) 200 return; 201 202 total_favicons_count_ = total_favicons_count; 203 favicons_.reserve(total_favicons_count); 204 } 205 206 void ExternalProcessImporterClient::OnFaviconsImportGroup( 207 const std::vector<history::ImportedFaviconUsage>& favicons_group) { 208 if (cancelled_) 209 return; 210 211 favicons_.insert(favicons_.end(), favicons_group.begin(), 212 favicons_group.end()); 213 if (favicons_.size() == total_favicons_count_) 214 bridge_->SetFavicons(favicons_); 215 } 216 217 void ExternalProcessImporterClient::OnPasswordFormImportReady( 218 const webkit_glue::PasswordForm& form) { 219 if (cancelled_) 220 return; 221 222 bridge_->SetPasswordForm(form); 223 } 224 225 void ExternalProcessImporterClient::OnKeywordsImportReady( 226 const std::vector<TemplateURL>& template_urls, 227 int default_keyword_index, bool unique_on_host_and_path) { 228 if (cancelled_) 229 return; 230 231 std::vector<TemplateURL*> template_url_vec; 232 template_url_vec.reserve(template_urls.size()); 233 std::vector<TemplateURL>::const_iterator iter; 234 for (iter = template_urls.begin(); 235 iter != template_urls.end(); 236 ++iter) { 237 template_url_vec.push_back(new TemplateURL(*iter)); 238 } 239 bridge_->SetKeywords(template_url_vec, default_keyword_index, 240 unique_on_host_and_path); 241 } 242