summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/DEPS1
-rw-r--r--chrome/browser/cocoa/import_progress_dialog.h4
-rw-r--r--chrome/browser/cocoa/import_progress_dialog.mm18
-rw-r--r--chrome/browser/first_run_mac.mm3
-rw-r--r--chrome/browser/gtk/import_progress_dialog_gtk.cc4
-rw-r--r--chrome/browser/importer/firefox2_importer.cc40
-rw-r--r--chrome/browser/importer/firefox3_importer.cc34
-rw-r--r--chrome/browser/importer/importer.cc387
-rw-r--r--chrome/browser/importer/importer.h280
-rw-r--r--chrome/browser/importer/importer_bridge.cc90
-rw-r--r--chrome/browser/importer/importer_bridge.h81
-rw-r--r--chrome/browser/importer/importer_list.cc2
-rw-r--r--chrome/browser/importer/importer_messages.h369
-rw-r--r--chrome/browser/importer/importer_messages_internal.h80
-rw-r--r--chrome/browser/importer/importer_unittest.cc12
-rw-r--r--chrome/browser/importer/safari_importer.mm36
-rw-r--r--chrome/browser/importer/toolbar_importer.cc47
-rw-r--r--chrome/browser/importer/toolbar_importer.h10
-rw-r--r--chrome/browser/importer/toolbar_importer_unittest.cc33
-rw-r--r--chrome/browser/profile_import_process_host.cc169
-rw-r--r--chrome/browser/profile_import_process_host.h142
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--chrome/chrome_browser.gypi5
-rw-r--r--chrome/chrome_tests.gypi5
-rw-r--r--chrome/profile_import/DEPS6
-rw-r--r--chrome/profile_import/profile_import_thread.cc175
-rw-r--r--chrome/profile_import/profile_import_thread.h79
27 files changed, 1892 insertions, 222 deletions
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 7120cb8..5380f75 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -4,6 +4,7 @@ include_rules = [
"+chrome/installer",
"+chrome/personalization",
"+chrome/plugin", # For Mac plugin interpose library.
+ "+chrome/profile_import",
"+chrome/tools/profiles", # For history unit tests.
"+chrome/views",
"+grit", # For generated headers
diff --git a/chrome/browser/cocoa/import_progress_dialog.h b/chrome/browser/cocoa/import_progress_dialog.h
index 41e401d..72f2cc2 100644
--- a/chrome/browser/cocoa/import_progress_dialog.h
+++ b/chrome/browser/cocoa/import_progress_dialog.h
@@ -19,7 +19,6 @@ class ImporterObserverBridge;
scoped_ptr<ImporterObserverBridge> import_host_observer_bridge_;
ImporterHost* importer_host_; // (weak)
ImportObserver* observer_; // (weak)
- BOOL importing_;
// Strings bound to static labels in the UI dialog.
NSString* explanatory_text_;
@@ -50,7 +49,6 @@ class ImporterObserverBridge;
// Methods called by importer_host via ImporterObserverBridge.
- (void)ImportItemStarted:(importer::ImportItem)item;
- (void)ImportItemEnded:(importer::ImportItem)item;
-- (void)ImportStarted;
- (void)ImportEnded;
@property(retain) NSString* explanatoryText;
@@ -86,7 +84,7 @@ class ImporterObserverBridge : public ImporterHost::Observer {
// Invoked when the import begins.
virtual void ImportStarted() {
- [owner_ ImportStarted];
+ // Not needed for out of process import.
}
// Invoked when the source profile has been imported.
diff --git a/chrome/browser/cocoa/import_progress_dialog.mm b/chrome/browser/cocoa/import_progress_dialog.mm
index 765e4d1..b8966fd 100644
--- a/chrome/browser/cocoa/import_progress_dialog.mm
+++ b/chrome/browser/cocoa/import_progress_dialog.mm
@@ -112,7 +112,6 @@ NSString* keyForImportItem(importer::ImportItem item) {
[super dealloc];
}
-
- (IBAction)showWindow:(id)sender {
NSWindow* win = [self window];
[win center];
@@ -126,13 +125,12 @@ NSString* keyForImportItem(importer::ImportItem item) {
}
- (IBAction)cancel:(id)sender {
- [self closeDialog];
- if (importing_) {
- importer_host_->Cancel();
- } else {
- [self release];
- }
+ // The ImporterHost will notify import_host_observer_bridge_ that import has
+ // ended, which will trigger the ImportEnded method, in which this object is
+ // released.
+ importer_host_->Cancel();
}
+
- (void)ImportItemStarted:(importer::ImportItem)item {
[self setValue:progress_text_ forKey:keyForImportItem(item)];
}
@@ -141,12 +139,7 @@ NSString* keyForImportItem(importer::ImportItem item) {
[self setValue:done_text_ forKey:keyForImportItem(item)];
}
-- (void)ImportStarted {
- importing_ = YES;
-}
-
- (void)ImportEnded {
- importing_ = NO;
importer_host_->SetObserver(NULL);
if (observer_)
observer_->ImportComplete();
@@ -184,7 +177,6 @@ void StartImportingWithUI(gfx::NativeWindow parent_window,
new ProfileWriter(target_profile),
first_run);
-
// Display the window while spinning a message loop.
// For details on why we need a modal message loop see http://crbug.com/19169
NSWindow* progress_window = [progress_dialog_ window];
diff --git a/chrome/browser/first_run_mac.mm b/chrome/browser/first_run_mac.mm
index b6bcbab..3a73403 100644
--- a/chrome/browser/first_run_mac.mm
+++ b/chrome/browser/first_run_mac.mm
@@ -64,7 +64,7 @@ bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
}
FirstRunController::FirstRunController()
- : importer_host_(new ImporterHost) {
+ : importer_host_(new ExternalProcessImporterHost) {
}
void FirstRunController::FirstRunDone() {
@@ -72,7 +72,6 @@ void FirstRunController::FirstRunDone() {
// TODO(jeremy): Implement
// FirstRun::SetShowFirstRunBubblePref();
// FirstRun::SetShowWelcomePagePref();
-
delete this;
}
diff --git a/chrome/browser/gtk/import_progress_dialog_gtk.cc b/chrome/browser/gtk/import_progress_dialog_gtk.cc
index 946e1d9..09e30da 100644
--- a/chrome/browser/gtk/import_progress_dialog_gtk.cc
+++ b/chrome/browser/gtk/import_progress_dialog_gtk.cc
@@ -62,7 +62,7 @@ void ImportProgressDialogGtk::StartImport(GtkWindow* parent,
////////////////////////////////////////////////////////////////////////////////
// ImporterHost::Observer implementation:
-void ImportProgressDialogGtk::ImportItemStarted(ImportItem item) {
+void ImportProgressDialogGtk::ImportItemStarted(importer::ImportItem item) {
DCHECK(items_ & item);
switch (item) {
case FAVORITES:
@@ -86,7 +86,7 @@ void ImportProgressDialogGtk::ImportItemStarted(ImportItem item) {
}
}
-void ImportProgressDialogGtk::ImportItemEnded(ImportItem item) {
+void ImportProgressDialogGtk::ImportItemEnded(importer::ImportItem item) {
DCHECK(items_ & item);
switch (item) {
case FAVORITES:
diff --git a/chrome/browser/importer/firefox2_importer.cc b/chrome/browser/importer/firefox2_importer.cc
index 655638c..211bfc9 100644
--- a/chrome/browser/importer/firefox2_importer.cc
+++ b/chrome/browser/importer/firefox2_importer.cc
@@ -7,7 +7,6 @@
#include <string>
#include <vector>
-#include "app/l10n_util.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/i18n/icu_string_conversions.h"
@@ -19,6 +18,7 @@
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/importer/firefox_importer_utils.h"
#include "chrome/browser/importer/importer_bridge.h"
+#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/browser/importer/mork_reader.h"
#include "chrome/browser/importer/nss_decryptor.h"
#include "chrome/browser/search_engines/template_url.h"
@@ -47,43 +47,44 @@ Firefox2Importer::Firefox2Importer() : parsing_bookmarks_html_file_(false) {
Firefox2Importer::~Firefox2Importer() {
}
-void Firefox2Importer::StartImport(ProfileInfo profile_info,
+void Firefox2Importer::StartImport(importer::ProfileInfo profile_info,
uint16 items,
ImporterBridge* bridge) {
bridge_ = bridge;
source_path_ = profile_info.source_path;
app_path_ = profile_info.app_path;
- parsing_bookmarks_html_file_ = (profile_info.browser_type == BOOKMARKS_HTML);
+ parsing_bookmarks_html_file_ =
+ (profile_info.browser_type == importer::BOOKMARKS_HTML);
// The order here is important!
bridge_->NotifyStarted();
- if ((items & HOME_PAGE) && !cancelled())
+ if ((items & importer::HOME_PAGE) && !cancelled())
ImportHomepage(); // Doesn't have a UI item.
// Note history should be imported before bookmarks because bookmark import
// will also import favicons and we store favicon for a URL only if the URL
// exist in history or bookmarks.
- if ((items & HISTORY) && !cancelled()) {
- bridge_->NotifyItemStarted(HISTORY);
+ if ((items & importer::HISTORY) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::HISTORY);
ImportHistory();
- bridge_->NotifyItemEnded(HISTORY);
+ bridge_->NotifyItemEnded(importer::HISTORY);
}
- if ((items & FAVORITES) && !cancelled()) {
- bridge_->NotifyItemStarted(FAVORITES);
+ if ((items & importer::FAVORITES) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::FAVORITES);
ImportBookmarks();
- bridge_->NotifyItemEnded(FAVORITES);
+ bridge_->NotifyItemEnded(importer::FAVORITES);
}
- if ((items & SEARCH_ENGINES) && !cancelled()) {
- bridge_->NotifyItemStarted(SEARCH_ENGINES);
+ if ((items & importer::SEARCH_ENGINES) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::SEARCH_ENGINES);
ImportSearchEngines();
- bridge_->NotifyItemEnded(SEARCH_ENGINES);
+ bridge_->NotifyItemEnded(importer::SEARCH_ENGINES);
}
- if ((items & PASSWORDS) && !cancelled()) {
- bridge_->NotifyItemStarted(PASSWORDS);
+ if ((items & importer::PASSWORDS) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::PASSWORDS);
ImportPasswords();
- bridge_->NotifyItemEnded(PASSWORDS);
+ bridge_->NotifyItemEnded(importer::PASSWORDS);
}
bridge_->NotifyEnded();
}
@@ -263,10 +264,9 @@ void Firefox2Importer::ImportBookmarks() {
if (!parsing_bookmarks_html_file_)
file = file.AppendASCII("bookmarks.html");
std::wstring first_folder_name;
- if (parsing_bookmarks_html_file_)
- first_folder_name = l10n_util::GetString(IDS_BOOKMARK_GROUP);
- else
- first_folder_name = l10n_util::GetString(IDS_BOOKMARK_GROUP_FROM_FIREFOX);
+ first_folder_name = bridge_->GetLocalizedString(
+ parsing_bookmarks_html_file_ ? IDS_BOOKMARK_GROUP :
+ IDS_BOOKMARK_GROUP_FROM_FIREFOX);
ImportBookmarksFile(file, default_urls, import_to_bookmark_bar(),
first_folder_name, this, &bookmarks, &template_urls,
diff --git a/chrome/browser/importer/firefox3_importer.cc b/chrome/browser/importer/firefox3_importer.cc
index 6010f45..775e8ca 100644
--- a/chrome/browser/importer/firefox3_importer.cc
+++ b/chrome/browser/importer/firefox3_importer.cc
@@ -6,7 +6,6 @@
#include <set>
-#include "app/l10n_util.h"
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/scoped_ptr.h"
@@ -16,6 +15,7 @@
#include "chrome/browser/importer/firefox2_importer.h"
#include "chrome/browser/importer/firefox_importer_utils.h"
#include "chrome/browser/importer/importer_bridge.h"
+#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/browser/importer/nss_decryptor.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/common/time_format.h"
@@ -33,7 +33,7 @@ using importer::ProfileInfo;
using importer::SEARCH_ENGINES;
using webkit_glue::PasswordForm;
-void Firefox3Importer::StartImport(ProfileInfo profile_info,
+void Firefox3Importer::StartImport(importer::ProfileInfo profile_info,
uint16 items,
ImporterBridge* bridge) {
bridge_ = bridge;
@@ -43,32 +43,32 @@ void Firefox3Importer::StartImport(ProfileInfo profile_info,
// The order here is important!
bridge_->NotifyStarted();
- if ((items & HOME_PAGE) && !cancelled())
+ if ((items & importer::HOME_PAGE) && !cancelled())
ImportHomepage(); // Doesn't have a UI item.
// Note history should be imported before bookmarks because bookmark import
// will also import favicons and we store favicon for a URL only if the URL
// exist in history or bookmarks.
- if ((items & HISTORY) && !cancelled()) {
- bridge_->NotifyItemStarted(HISTORY);
+ if ((items & importer::HISTORY) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::HISTORY);
ImportHistory();
- bridge_->NotifyItemEnded(HISTORY);
+ bridge_->NotifyItemEnded(importer::HISTORY);
}
- if ((items & FAVORITES) && !cancelled()) {
- bridge_->NotifyItemStarted(FAVORITES);
+ if ((items & importer::FAVORITES) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::FAVORITES);
ImportBookmarks();
- bridge_->NotifyItemEnded(FAVORITES);
+ bridge_->NotifyItemEnded(importer::FAVORITES);
}
- if ((items & SEARCH_ENGINES) && !cancelled()) {
- bridge_->NotifyItemStarted(SEARCH_ENGINES);
+ if ((items & importer::SEARCH_ENGINES) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::SEARCH_ENGINES);
ImportSearchEngines();
- bridge_->NotifyItemEnded(SEARCH_ENGINES);
+ bridge_->NotifyItemEnded(importer::SEARCH_ENGINES);
}
- if ((items & PASSWORDS) && !cancelled()) {
- bridge_->NotifyItemStarted(PASSWORDS);
+ if ((items & importer::PASSWORDS) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::PASSWORDS);
ImportPasswords();
- bridge_->NotifyItemEnded(PASSWORDS);
+ bridge_->NotifyItemEnded(importer::PASSWORDS);
}
bridge_->NotifyEnded();
}
@@ -177,7 +177,7 @@ void Firefox3Importer::ImportBookmarks() {
}
std::wstring firefox_folder =
- l10n_util::GetString(IDS_BOOKMARK_GROUP_FROM_FIREFOX);
+ bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_FIREFOX);
for (size_t i = 0; i < list.size(); ++i) {
BookmarkItem* item = list[i];
@@ -253,7 +253,7 @@ void Firefox3Importer::ImportBookmarks() {
// Write into profile.
if (!bookmarks.empty() && !cancelled()) {
const std::wstring& first_folder_name =
- l10n_util::GetString(IDS_BOOKMARK_GROUP_FROM_FIREFOX);
+ bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_FIREFOX);
int options = 0;
if (import_to_bookmark_bar())
options = ProfileWriter::IMPORT_TO_BOOKMARK_BAR;
diff --git a/chrome/browser/importer/importer.cc b/chrome/browser/importer/importer.cc
index 3b660a1..aac856e 100644
--- a/chrome/browser/importer/importer.cc
+++ b/chrome/browser/importer/importer.cc
@@ -5,7 +5,6 @@
#include "chrome/browser/importer/importer.h"
#include "app/l10n_util.h"
-#include "base/string_util.h"
#include "base/thread.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/browser_list.h"
@@ -13,12 +12,10 @@
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/importer/firefox_profile_lock.h"
#include "chrome/browser/importer/importer_bridge.h"
-#include "chrome/browser/pref_service.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/browser/webdata/web_data_service.h"
#include "chrome/common/notification_service.h"
-#include "chrome/common/pref_names.h"
#include "gfx/codec/png_codec.h"
#include "gfx/favicon_size.h"
#include "grit/generated_resources.h"
@@ -171,7 +168,7 @@ void ImporterHost::StartImportSettings(
// will be notified.
writer_ = writer;
importer_ = importer_list_.CreateImporterByType(profile_info.browser_type);
- // If we fail to create Importer, exit as we can not do anything.
+ // If we fail to create Importer, exit as we cannot do anything.
if (!importer_) {
ImportEnded();
return;
@@ -179,38 +176,13 @@ void ImporterHost::StartImportSettings(
importer_->AddRef();
- bool import_to_bookmark_bar = first_run;
- if (target_profile && target_profile->GetBookmarkModel()->IsLoaded()) {
- std::vector<GURL> starred_urls;
- target_profile->GetBookmarkModel()->GetBookmarks(&starred_urls);
- import_to_bookmark_bar = (starred_urls.size() == 0);
- }
- importer_->set_import_to_bookmark_bar(import_to_bookmark_bar);
+ importer_->set_import_to_bookmark_bar(ShouldImportToBookmarkBar(first_run));
scoped_refptr<ImporterBridge> bridge(
new InProcessImporterBridge(writer_.get(), this));
task_ = NewRunnableMethod(importer_, &Importer::StartImport,
profile_info, items, bridge);
- // We should lock the Firefox profile directory to prevent corruption.
- if (profile_info.browser_type == importer::FIREFOX2 ||
- profile_info.browser_type == importer::FIREFOX3) {
- firefox_lock_.reset(new FirefoxProfileLock(profile_info.source_path));
- if (!firefox_lock_->HasAcquired()) {
- // If fail to acquire the lock, we set the source unreadable and
- // show a warning dialog.
- // However, if we're running without a UI (silently) and trying to
- // import just the home page, then import anyway. The home page setting
- // is stored in an unlocked text file, so it is the only preference safe
- // to import even if Firefox is running.
- if (items == importer::HOME_PAGE && first_run && this->headless_) {
- AddRef();
- InvokeTaskIfDone();
- return;
- }
- is_source_readable_ = false;
- ShowWarningDialog();
- }
- }
+ CheckForFirefoxLock(profile_info, items, first_run);
#if defined(OS_WIN)
// For google toolbar import, we need the user to log in and store their GAIA
@@ -238,26 +210,7 @@ void ImporterHost::StartImportSettings(
}
#endif
- // BookmarkModel should be loaded before adding IE favorites. So we observe
- // the BookmarkModel if needed, and start the task after it has been loaded.
- if ((items & importer::FAVORITES) && !writer_->BookmarkModelIsLoaded()) {
- target_profile->GetBookmarkModel()->AddObserver(this);
- waiting_for_bookmarkbar_model_ = true;
- installed_bookmark_observer_ = true;
- }
-
- // Observes the TemplateURLModel if needed to import search engines from the
- // other browser. We also check to see if we're importing bookmarks because
- // we can import bookmark keywords from Firefox as search engines.
- if ((items & importer::SEARCH_ENGINES) || (items & importer::FAVORITES)) {
- if (!writer_->TemplateURLModelIsLoaded()) {
- TemplateURLModel* model = target_profile->GetTemplateURLModel();
- registrar_.Add(this, NotificationType::TEMPLATE_URL_MODEL_LOADED,
- Source<TemplateURLModel>(model));
- model->Load();
- }
- }
-
+ CheckForLoadedModels(items);
AddRef();
InvokeTaskIfDone();
}
@@ -299,3 +252,335 @@ void ImporterHost::ImportEnded() {
observer_->ImportEnded();
Release();
}
+
+bool ImporterHost::ShouldImportToBookmarkBar(bool first_run) {
+ bool import_to_bookmark_bar = first_run;
+ if (profile_ && profile_->GetBookmarkModel()->IsLoaded()) {
+ std::vector<GURL> starred_urls;
+ profile_->GetBookmarkModel()->GetBookmarks(&starred_urls);
+ import_to_bookmark_bar = (starred_urls.size() == 0);
+ }
+ return import_to_bookmark_bar;
+}
+
+void ImporterHost::CheckForFirefoxLock(
+ const importer::ProfileInfo& profile_info, uint16 items, bool first_run) {
+ if (profile_info.browser_type == importer::FIREFOX2 ||
+ profile_info.browser_type == importer::FIREFOX3) {
+ DCHECK(!firefox_lock_.get());
+ firefox_lock_.reset(new FirefoxProfileLock(profile_info.source_path));
+ if (!firefox_lock_->HasAcquired()) {
+ // If fail to acquire the lock, we set the source unreadable and
+ // show a warning dialog, unless running without UI.
+ is_source_readable_ = false;
+ if (!this->headless_)
+ ShowWarningDialog();
+ }
+ }
+}
+
+void ImporterHost::CheckForLoadedModels(uint16 items) {
+ // BookmarkModel should be loaded before adding IE favorites. So we observe
+ // the BookmarkModel if needed, and start the task after it has been loaded.
+ if ((items & importer::FAVORITES) && !writer_->BookmarkModelIsLoaded()) {
+ profile_->GetBookmarkModel()->AddObserver(this);
+ waiting_for_bookmarkbar_model_ = true;
+ installed_bookmark_observer_ = true;
+ }
+
+ // Observes the TemplateURLModel if needed to import search engines from the
+ // other browser. We also check to see if we're importing bookmarks because
+ // we can import bookmark keywords from Firefox as search engines.
+ if ((items & importer::SEARCH_ENGINES) || (items & importer::FAVORITES)) {
+ if (!writer_->TemplateURLModelIsLoaded()) {
+ TemplateURLModel* model = profile_->GetTemplateURLModel();
+ registrar_.Add(this, NotificationType::TEMPLATE_URL_MODEL_LOADED,
+ Source<TemplateURLModel>(model));
+ model->Load();
+ }
+ }
+}
+
+ExternalProcessImporterHost::ExternalProcessImporterHost()
+ : cancelled_(false),
+ import_process_launched_(false) {
+}
+
+void ExternalProcessImporterHost::Loaded(BookmarkModel* model) {
+ DCHECK(model->IsLoaded());
+ model->RemoveObserver(this);
+ waiting_for_bookmarkbar_model_ = false;
+ installed_bookmark_observer_ = false;
+
+ std::vector<GURL> starred_urls;
+ model->GetBookmarks(&starred_urls);
+ // Because the import process is running externally, the decision whether
+ // to import to the bookmark bar must be stored here so that it can be
+ // passed to the importer when the import task is invoked.
+ import_to_bookmark_bar_ = (starred_urls.size() == 0);
+ InvokeTaskIfDone();
+}
+
+void ExternalProcessImporterHost::Cancel() {
+ cancelled_ = true;
+ if (import_process_launched_)
+ client_->Cancel();
+ ImportEnded(); // Tells the observer that we're done, and releases us.
+}
+
+void ExternalProcessImporterHost::StartImportSettings(
+ const importer::ProfileInfo& profile_info,
+ Profile* target_profile,
+ uint16 items,
+ ProfileWriter* writer,
+ bool first_run) {
+ DCHECK(!profile_);
+ profile_ = target_profile;
+ writer_ = writer;
+ profile_info_ = &profile_info;
+ items_ = items;
+
+ import_to_bookmark_bar_ = ShouldImportToBookmarkBar(first_run);
+ CheckForFirefoxLock(profile_info, items, first_run);
+ CheckForLoadedModels(items);
+
+ ImporterHost::AddRef(); // Balanced in ImporterHost::ImportEnded.
+ InvokeTaskIfDone();
+}
+
+void ExternalProcessImporterHost::InvokeTaskIfDone() {
+ if (waiting_for_bookmarkbar_model_ || !registrar_.IsEmpty() ||
+ !is_source_readable_ || cancelled_)
+ return;
+
+ // The in-process half of the bridge which catches data from the IPC pipe
+ // and feeds it to the ProfileWriter. The external process half of the
+ // bridge lives in the external process -- see ProfileImportThread.
+ // The ExternalProcessImporterClient created in the next line owns this
+ // bridge, and will delete it.
+ InProcessImporterBridge* bridge =
+ new InProcessImporterBridge(writer_.get(), this);
+ client_ = new ExternalProcessImporterClient(this, *profile_info_, items_,
+ bridge, import_to_bookmark_bar_);
+ import_process_launched_ = true;
+ client_->Start();
+}
+
+ExternalProcessImporterClient::ExternalProcessImporterClient(
+ ExternalProcessImporterHost* importer_host,
+ const importer::ProfileInfo& profile_info,
+ int items,
+ InProcessImporterBridge* bridge,
+ bool import_to_bookmark_bar)
+ : process_importer_host_(importer_host),
+ profile_info_(profile_info),
+ items_(items),
+ import_to_bookmark_bar_(import_to_bookmark_bar),
+ bridge_(bridge),
+ cancelled_(FALSE) {
+ bridge_->AddRef();
+ process_importer_host_->ImportStarted();
+}
+
+ExternalProcessImporterClient::~ExternalProcessImporterClient() {
+ bridge_->Release();
+}
+
+void ExternalProcessImporterClient::Start() {
+ AddRef(); // balanced in Cleanup.
+ ChromeThread::ID thread_id;
+ CHECK(ChromeThread::GetCurrentThreadIdentifier(&thread_id));
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(this,
+ &ExternalProcessImporterClient::StartProcessOnIOThread,
+ g_browser_process->resource_dispatcher_host(), thread_id));
+}
+
+void ExternalProcessImporterClient::StartProcessOnIOThread(
+ ResourceDispatcherHost* rdh,
+ ChromeThread::ID thread_id) {
+ profile_import_process_host_ =
+ new ProfileImportProcessHost(rdh, this, thread_id);
+ profile_import_process_host_->StartProfileImportProcess(profile_info_,
+ items_, import_to_bookmark_bar_);
+}
+
+void ExternalProcessImporterClient::Cancel() {
+ if (cancelled_)
+ return;
+
+ cancelled_ = true;
+ if (profile_import_process_host_) {
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(this,
+ &ExternalProcessImporterClient::CancelImportProcessOnIOThread));
+ }
+ Release();
+}
+
+void ExternalProcessImporterClient::CancelImportProcessOnIOThread() {
+ profile_import_process_host_->CancelProfileImportProcess();
+}
+
+void ExternalProcessImporterClient::NotifyItemFinishedOnIOThread(
+ importer::ImportItem import_item) {
+ profile_import_process_host_->ReportImportItemFinished(import_item);
+}
+
+void ExternalProcessImporterClient::OnProcessCrashed() {
+ if (cancelled_)
+ return;
+
+ process_importer_host_->Cancel();
+}
+
+void ExternalProcessImporterClient::Cleanup() {
+ if (cancelled_)
+ return;
+
+ if (process_importer_host_)
+ process_importer_host_->ImportEnded();
+ Release();
+}
+
+void ExternalProcessImporterClient::OnImportStart() {
+ if (cancelled_)
+ return;
+
+ bridge_->NotifyStarted();
+}
+
+void ExternalProcessImporterClient::OnImportFinished(bool succeeded,
+ std::string error_msg) {
+ if (cancelled_)
+ return;
+
+ if (!succeeded)
+ LOG(WARNING) << "Import failed. Error: " << error_msg;
+ Cleanup();
+}
+
+void ExternalProcessImporterClient::OnImportItemStart(int item_data) {
+ if (cancelled_)
+ return;
+
+ bridge_->NotifyItemStarted(static_cast<importer::ImportItem>(item_data));
+}
+
+void ExternalProcessImporterClient::OnImportItemFinished(int item_data) {
+ if (cancelled_)
+ return;
+
+ importer::ImportItem import_item =
+ static_cast<importer::ImportItem>(item_data);
+ bridge_->NotifyItemEnded(import_item);
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(this,
+ &ExternalProcessImporterClient::NotifyItemFinishedOnIOThread,
+ import_item));
+}
+
+void ExternalProcessImporterClient::OnHistoryImportStart(
+ size_t total_history_rows_count) {
+ if (cancelled_)
+ return;
+
+ total_history_rows_count_ = total_history_rows_count;
+ history_rows_.reserve(total_history_rows_count);
+}
+
+void ExternalProcessImporterClient::OnHistoryImportGroup(
+ const std::vector<history::URLRow> &history_rows_group) {
+ if (cancelled_)
+ return;
+
+ history_rows_.insert(history_rows_.end(), history_rows_group.begin(),
+ history_rows_group.end());
+ if (history_rows_.size() == total_history_rows_count_)
+ bridge_->SetHistoryItems(history_rows_);
+}
+
+void ExternalProcessImporterClient::OnHomePageImportReady(
+ const GURL& home_page) {
+ if (cancelled_)
+ return;
+
+ bridge_->AddHomePage(home_page);
+}
+
+void ExternalProcessImporterClient::OnBookmarksImportStart(
+ const std::wstring first_folder_name,
+ int options, size_t total_bookmarks_count) {
+ if (cancelled_)
+ return;
+
+ bookmarks_first_folder_name_ = first_folder_name;
+ bookmarks_options_ = options;
+ total_bookmarks_count_ = total_bookmarks_count;
+ bookmarks_.reserve(total_bookmarks_count);
+}
+
+void ExternalProcessImporterClient::OnBookmarksImportGroup(
+ const std::vector<ProfileWriter::BookmarkEntry>& bookmarks_group) {
+ if (cancelled_)
+ return;
+
+ // Collect sets of bookmarks from importer process until we have reached
+ // total_bookmarks_count_:
+ bookmarks_.insert(bookmarks_.end(), bookmarks_group.begin(),
+ bookmarks_group.end());
+ if (bookmarks_.size() == total_bookmarks_count_) {
+ bridge_->AddBookmarkEntries(bookmarks_, bookmarks_first_folder_name_,
+ bookmarks_options_);
+ }
+}
+
+void ExternalProcessImporterClient::OnFavIconsImportStart(
+ size_t total_fav_icons_count) {
+ if (cancelled_)
+ return;
+
+ total_fav_icons_count_ = total_fav_icons_count;
+ fav_icons_.reserve(total_fav_icons_count);
+}
+
+void ExternalProcessImporterClient::OnFavIconsImportGroup(
+ const std::vector<history::ImportedFavIconUsage>& fav_icons_group) {
+ if (cancelled_)
+ return;
+
+ fav_icons_.insert(fav_icons_.end(), fav_icons_group.begin(),
+ fav_icons_group.end());
+ if (fav_icons_.size() == total_fav_icons_count_)
+ bridge_->SetFavIcons(fav_icons_);
+}
+
+void ExternalProcessImporterClient::OnPasswordFormImportReady(
+ const webkit_glue::PasswordForm& form) {
+ if (cancelled_)
+ return;
+
+ bridge_->SetPasswordForm(form);
+}
+
+void ExternalProcessImporterClient::OnKeywordsImportReady(
+ const std::vector<TemplateURL>& template_urls,
+ int default_keyword_index, bool unique_on_host_and_path) {
+ if (cancelled_)
+ return;
+
+ std::vector<TemplateURL*> template_url_vec;
+ template_url_vec.reserve(template_urls.size());
+ std::vector<TemplateURL>::const_iterator iter;
+ for (iter = template_urls.begin();
+ iter != template_urls.end();
+ ++iter) {
+ template_url_vec.push_back(new TemplateURL(*iter));
+ }
+ bridge_->SetKeywords(template_url_vec, default_keyword_index,
+ unique_on_host_and_path);
+}
+
diff --git a/chrome/browser/importer/importer.h b/chrome/browser/importer/importer.h
index d0ea428..a6c34ce 100644
--- a/chrome/browser/importer/importer.h
+++ b/chrome/browser/importer/importer.h
@@ -15,9 +15,11 @@
#include "base/scoped_ptr.h"
#include "base/time.h"
#include "chrome/browser/bookmarks/bookmark_model_observer.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/browser/importer/importer_list.h"
#include "chrome/browser/importer/profile_writer.h"
+#include "chrome/browser/profile_import_process_host.h"
#include "chrome/common/notification_registrar.h"
#include "gfx/native_widget_types.h"
#include "googleurl/src/gurl.h"
@@ -25,7 +27,9 @@
using importer::ImportItem;
using importer::ProfileInfo;
+class ExternalProcessImporterClient;
class ImporterBridge;
+class InProcessImporterBridge;
class Profile;
class Task;
class TemplateURL;
@@ -88,16 +92,21 @@ class ImporterHost : public base::RefCountedThreadSafe<ImporterHost>,
// button. |is_continue| is true when user clicked the "Continue" button.
void OnLockViewEnd(bool is_continue);
- // Starts the process of importing the settings and data depending
- // on what the user selected.
- void StartImportSettings(const ProfileInfo& profile_info,
- Profile* target_profile,
- uint16 items,
- ProfileWriter* writer,
- bool first_run);
-
- // Cancel
- void Cancel();
+ // Starts the process of importing the settings and data depending on what
+ // the user selected.
+ // |profile_info| -- browser profile to import.
+ // |target_profile| -- profile to import into.
+ // |items| -- specifies which data to import (mask of ImportItems).
+ // |writer| -- called to actually write data back to the profile.
+ // |first_run| -- true if this method is being called during first run.
+ virtual void StartImportSettings(const importer::ProfileInfo& profile_info,
+ Profile* target_profile,
+ uint16 items,
+ ProfileWriter* writer,
+ bool first_run);
+
+ // Cancel import.
+ virtual void Cancel();
// When in headless mode, the importer will not show the warning dialog and
// the outcome is as if the user had canceled the import operation.
@@ -119,11 +128,11 @@ class ImporterHost : public base::RefCountedThreadSafe<ImporterHost>,
public:
virtual ~Observer() {}
// Invoked when data for the specified item is about to be collected.
- virtual void ImportItemStarted(ImportItem item) = 0;
+ virtual void ImportItemStarted(importer::ImportItem item) = 0;
// Invoked when data for the specified item has been collected from the
// source profile and is now ready for further processing.
- virtual void ImportItemEnded(ImportItem item) = 0;
+ virtual void ImportItemEnded(importer::ImportItem item) = 0;
// Invoked when the import begins.
virtual void ImportStarted() = 0;
@@ -137,16 +146,16 @@ class ImporterHost : public base::RefCountedThreadSafe<ImporterHost>,
// of the import process. The middle functions are notifications that the
// harvesting of a particular source of data (specified by |item|) is under
// way.
- void ImportStarted();
- void ImportItemStarted(ImportItem item);
- void ImportItemEnded(ImportItem item);
- void ImportEnded();
+ virtual void ImportStarted();
+ virtual void ImportItemStarted(importer::ImportItem item);
+ virtual void ImportItemEnded(importer::ImportItem item);
+ virtual void ImportEnded();
int GetAvailableProfileCount() const {
- return importer_list_.GetAvailableProfileCount();
+ return importer_list_.GetAvailableProfileCount();
}
- // Returns the name of the profile at the 'index' slot. The profiles are
+ // Returns the name of the profile at the 'index' slot. The profiles are
// ordered such that the profile at index 0 is the likely default browser.
std::wstring GetSourceProfileNameAt(int index) const {
return importer_list_.GetSourceProfileNameAt(index);
@@ -154,40 +163,54 @@ class ImporterHost : public base::RefCountedThreadSafe<ImporterHost>,
// Returns the ProfileInfo at the specified index. The ProfileInfo should be
// passed to StartImportSettings().
- const ProfileInfo& GetSourceProfileInfoAt(int index) const {
+ const importer::ProfileInfo& GetSourceProfileInfoAt(int index) const {
return importer_list_.GetSourceProfileInfoAt(index);
}
// Returns the ProfileInfo with the given browser type.
- const ProfileInfo& GetSourceProfileInfoForBrowserType(
+ const importer::ProfileInfo& GetSourceProfileInfoForBrowserType(
int browser_type) const {
return importer_list_.GetSourceProfileInfoForBrowserType(browser_type);
}
-
- private:
+ protected:
friend class base::RefCountedThreadSafe<ImporterHost>;
~ImporterHost();
- // If we're not waiting on any model to finish loading, invokes the task_.
- void InvokeTaskIfDone();
+ // Returns true if importer should import to bookmark bar.
+ bool ShouldImportToBookmarkBar(bool first_run);
- NotificationRegistrar registrar_;
- ImporterList importer_list_;
+ // Make sure that Firefox isn't running, if import browser is Firefox. Show
+ // the user a dialog to notify that they need to close FF to continue.
+ // |profile_info| holds the browser type and source path.
+ // |items| is a mask of all ImportItems that are to be imported.
+ // |first_run| is true if this method is being called during first run.
+ void CheckForFirefoxLock(const importer::ProfileInfo& profile_info,
+ uint16 items, bool first_run);
+
+ // Make sure BookmarkModel and TemplateURLModel are loaded before import
+ // process starts, if bookmarks and / or search engines are among the items
+ // which are to be imported.
+ void CheckForLoadedModels(uint16 items);
// Profile we're importing from.
Profile* profile_;
Observer* observer_;
- scoped_refptr<ProfileWriter> writer_;
+ // TODO(mirandac): task_ and importer_ should be private. Can't just put
+ // them there without changing the order of construct/destruct, so do this
+ // after main CL has been committed.
// The task is the process of importing settings from other browsers.
Task* task_;
// The importer used in the task;
Importer* importer_;
+ // Writes data from the importer back to the profile.
+ scoped_refptr<ProfileWriter> writer_;
+
// True if we're waiting for the model to finish loading.
bool waiting_for_bookmarkbar_model_;
@@ -200,15 +223,214 @@ class ImporterHost : public base::RefCountedThreadSafe<ImporterHost>,
// True if UI is not to be shown.
bool headless_;
+ // Receives notification when the TemplateURLModel has loaded.
+ NotificationRegistrar registrar_;
+
// Parent Window to use when showing any modal dialog boxes.
gfx::NativeWindow parent_window_;
// Firefox profile lock.
scoped_ptr<FirefoxProfileLock> firefox_lock_;
+ private:
+ // Launches the thread that starts the import task, unless bookmark or
+ // template model are not yet loaded. If load is not detected, this method
+ // will be called when the loading observer sees that model loading is
+ // complete.
+ virtual void InvokeTaskIfDone();
+
+ // Used to create an importer of the appropriate type.
+ ImporterList importer_list_;
+
DISALLOW_COPY_AND_ASSIGN(ImporterHost);
};
+// This class manages the import process. It creates the in-process half of
+// the importer bridge and the external process importer client.
+class ExternalProcessImporterHost : public ImporterHost {
+ public:
+ ExternalProcessImporterHost();
+
+ // Called when the BookmarkModel has finished loading. Calls InvokeTaskIfDone
+ // to start importing.
+ virtual void Loaded(BookmarkModel* model);
+
+ // Methods inherited from ImporterHost.
+ virtual void StartImportSettings(const importer::ProfileInfo& profile_info,
+ Profile* target_profile,
+ uint16 items,
+ ProfileWriter* writer,
+ bool first_run);
+
+ virtual void Cancel();
+
+ protected:
+ // Launches the ExternalProcessImporterClient unless bookmark or template
+ // model are not yet loaded. If load is not detected, this method will be
+ // called when the loading observer sees that model loading is complete.
+ virtual void InvokeTaskIfDone();
+
+ private:
+ // Used to pass notifications from the browser side to the external process.
+ ExternalProcessImporterClient* client_;
+
+ // Data for the external importer: ------------------------------------------
+ // Information about a profile needed for importing.
+ const importer::ProfileInfo* profile_info_;
+
+ // Mask of items to be imported (see importer::ImportItem).
+ uint16 items_;
+
+ // Whether to import bookmarks to the bookmark bar.
+ bool import_to_bookmark_bar_;
+
+ // True if the import process has been cancelled.
+ bool cancelled_;
+
+ // True if the import process has been launched. This prevents race
+ // conditions on import cancel.
+ bool import_process_launched_;
+
+ // End of external importer data --------------------------------------------
+
+ DISALLOW_COPY_AND_ASSIGN(ExternalProcessImporterHost);
+};
+
+// This class is the client for the ProfileImportProcessHost. It collects
+// notifications from this process host and feeds data back to the importer
+// host, who actually does the writing.
+class ExternalProcessImporterClient
+ : public ProfileImportProcessHost::ImportProcessClient {
+ public:
+ ExternalProcessImporterClient(ExternalProcessImporterHost* importer_host,
+ const importer::ProfileInfo& profile_info,
+ int items,
+ InProcessImporterBridge* bridge,
+ bool import_to_bookmark_bar);
+
+ ~ExternalProcessImporterClient();
+
+ // Launches the task to start the external process.
+ virtual void Start();
+
+ // Creates a new ProfileImportProcessHost, which launches the import process.
+ virtual void StartProcessOnIOThread(ResourceDispatcherHost* rdh,
+ ChromeThread::ID thread_id);
+
+ // Called by the ExternalProcessImporterHost on import cancel.
+ virtual void Cancel();
+
+ // Cancel import process on IO thread.
+ void CancelImportProcessOnIOThread();
+
+ // Report item completely downloaded on IO thread.
+ void NotifyItemFinishedOnIOThread(importer::ImportItem import_item);
+
+ // Cancel import on process crash.
+ virtual void OnProcessCrashed();
+
+ // Notifies the importerhost that import has finished, and calls Release().
+ void Cleanup();
+
+ // ProfileImportProcessHost messages ----------------------------------------
+ // The following methods are called by ProfileImportProcessHost when the
+ // corresponding message has been received from the import process.
+ virtual void OnImportStart();
+ virtual void OnImportFinished(bool succeeded, std::string error_msg);
+ virtual void OnImportItemStart(int item_data);
+ virtual void OnImportItemFinished(int item_data);
+
+ // Called on first message received when importing history; gives total
+ // number of rows to be imported.
+ virtual void OnHistoryImportStart(size_t total_history_rows_count);
+
+ // Called when a group of URLRows has been received.
+ virtual void OnHistoryImportGroup(
+ const std::vector<history::URLRow> &history_rows_group);
+
+ // Called when the home page has been received.
+ virtual void OnHomePageImportReady(const GURL& home_page);
+
+ // First message received when importing bookmarks.
+ // |first_folder_name| can be NULL.
+ // |options| is described in ProfileWriter::BookmarkOptions.
+ // |total_bookmarks_count| is the total number of bookmarks to be imported.
+ virtual void OnBookmarksImportStart(
+ const std::wstring first_folder_name,
+ int options, size_t total_bookmarks_count);
+
+ // Called when a group of bookmarks has been received.
+ virtual void OnBookmarksImportGroup(
+ const std::vector<ProfileWriter::BookmarkEntry>& bookmarks_group);
+
+ // First message received when importing favicons. |total_fav_icons_size|
+ // gives the total number of fav icons to be imported.
+ virtual void OnFavIconsImportStart(size_t total_fav_icons_count);
+
+ // Called when a group of favicons has been received.
+ virtual void OnFavIconsImportGroup(
+ const std::vector<history::ImportedFavIconUsage>& fav_icons_group);
+
+ // Called when the passwordform has been received.
+ virtual void OnPasswordFormImportReady(
+ const webkit_glue::PasswordForm& form);
+
+ // Called when search engines have been received.
+ virtual void OnKeywordsImportReady(
+ const std::vector<TemplateURL>& template_urls,
+ int default_keyword_index, bool unique_on_host_and_path);
+
+ // End ProfileImportProcessHost messages ------------------------------------
+
+ private:
+ // These variables store data being collected from the importer until the
+ // entire group has been collected and is ready to be written to the profile.
+ std::vector<history::URLRow> history_rows_;
+ std::vector<ProfileWriter::BookmarkEntry> bookmarks_;
+ std::vector<history::ImportedFavIconUsage> fav_icons_;
+
+ // Usually some variation on IDS_BOOKMARK_GROUP_...; the name of the folder
+ // under which imported bookmarks will be placed.
+ std::wstring bookmarks_first_folder_name_;
+
+ // Determines how bookmarks should be added (ProfileWriter::BookmarkOptions).
+ int bookmarks_options_;
+
+ // Total number of bookmarks to import.
+ size_t total_bookmarks_count_;
+
+ // Total number of history items to import.
+ size_t total_history_rows_count_;
+
+ // Total number of fav icons to import.
+ size_t total_fav_icons_count_;
+
+ // Notifications received from the ProfileImportProcessHost are passed back
+ // to process_importer_host_, which calls the ProfileWriter to record the
+ // import data. When the import process is done, process_importer_host_
+ // deletes itself.
+ ExternalProcessImporterHost* process_importer_host_;
+
+ // Handles sending messages to the external process. Deletes itself when
+ // the external process dies (see ChildProcessHost::OnChildDied).
+ ProfileImportProcessHost* profile_import_process_host_;
+
+ // Data to be passed from the importer host to the external importer.
+ const importer::ProfileInfo& profile_info_;
+ int items_;
+ bool import_to_bookmark_bar_;
+
+ // Takes import data coming over IPC and delivers it to be written by the
+ // ProfileWriter. Released by ExternalProcessImporterClient in its
+ // destructor.
+ InProcessImporterBridge* bridge_;
+
+ // True if import process has been cancelled.
+ bool cancelled_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExternalProcessImporterClient);
+};
+
// The base class of all importers.
class Importer : public base::RefCountedThreadSafe<Importer> {
public:
@@ -218,7 +440,7 @@ class Importer : public base::RefCountedThreadSafe<Importer> {
// Since we do async import, the importer should invoke
// ImporterHost::Finished() to notify its host that import
// stuff have been finished.
- virtual void StartImport(ProfileInfo profile_info,
+ virtual void StartImport(importer::ProfileInfo profile_info,
uint16 items,
ImporterBridge* bridge) = 0;
@@ -279,7 +501,7 @@ class ImportObserver {
void StartImportingWithUI(gfx::NativeWindow parent_window,
int16 items,
ImporterHost* coordinator,
- const ProfileInfo& source_profile,
+ const importer::ProfileInfo& source_profile,
Profile* target_profile,
ImportObserver* observer,
bool first_run);
diff --git a/chrome/browser/importer/importer_bridge.cc b/chrome/browser/importer/importer_bridge.cc
index 782f12b..2a913d2 100644
--- a/chrome/browser/importer/importer_bridge.cc
+++ b/chrome/browser/importer/importer_bridge.cc
@@ -4,17 +4,23 @@
#include "chrome/browser/importer/importer_bridge.h"
+#include "app/l10n_util.h"
+#include "base/scoped_ptr.h"
+#include "base/values.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/importer/importer.h"
#if defined(OS_WIN)
#include "chrome/browser/password_manager/ie7_password.h"
#endif
+#include "chrome/common/child_thread.h"
+#include "chrome/browser/importer/importer_messages.h"
+#include "chrome/profile_import/profile_import_thread.h"
#include "webkit/glue/password_form.h"
InProcessImporterBridge::InProcessImporterBridge(ProfileWriter* writer,
ImporterHost* host)
- : ImporterBridge(writer, host) {
+ : writer_(writer), host_(host) {
}
void InProcessImporterBridge::AddBookmarkEntries(
@@ -29,7 +35,7 @@ void InProcessImporterBridge::AddBookmarkEntries(
}
void InProcessImporterBridge::AddHomePage(const GURL &home_page) {
- ChromeThread::PostTask(
+ ChromeThread::PostTask(
ChromeThread::UI, FROM_HERE,
NewRunnableMethod(writer_, &ProfileWriter::AddHomepage, home_page));
}
@@ -99,3 +105,83 @@ void InProcessImporterBridge::NotifyEnded() {
ChromeThread::UI, FROM_HERE,
NewRunnableMethod(host_, &ImporterHost::ImportEnded));
}
+
+std::wstring InProcessImporterBridge::GetLocalizedString(int message_id) {
+ return l10n_util::GetString(message_id);
+}
+
+ExternalProcessImporterBridge::ExternalProcessImporterBridge(
+ ProfileImportThread* profile_import_thread,
+ const DictionaryValue& localized_strings)
+ : profile_import_thread_(profile_import_thread),
+ localized_strings_(localized_strings) {
+}
+
+void ExternalProcessImporterBridge::AddBookmarkEntries(
+ const std::vector<ProfileWriter::BookmarkEntry>& bookmarks,
+ const std::wstring& first_folder_name, int options) {
+ profile_import_thread_->NotifyBookmarksImportReady(bookmarks,
+ first_folder_name, options);
+}
+
+void ExternalProcessImporterBridge::AddHomePage(const GURL &home_page) {
+ // TODO(mirandac): remove home page import from code base.
+ // http://crbug.com/45678 :-)
+ NOTIMPLEMENTED();
+}
+
+#if defined(OS_WIN)
+void ExternalProcessImporterBridge::AddIE7PasswordInfo(
+ const IE7PasswordInfo password_info) {
+ NOTIMPLEMENTED();
+}
+#endif
+
+void ExternalProcessImporterBridge::SetFavIcons(
+ const std::vector<history::ImportedFavIconUsage>& fav_icons) {
+ profile_import_thread_->NotifyFavIconsImportReady(fav_icons);
+}
+
+void ExternalProcessImporterBridge::SetHistoryItems(
+ const std::vector<history::URLRow> &rows) {
+ profile_import_thread_->NotifyHistoryImportReady(rows);
+}
+
+void ExternalProcessImporterBridge::SetKeywords(
+ const std::vector<TemplateURL*>& template_urls,
+ int default_keyword_index,
+ bool unique_on_host_and_path) {
+ profile_import_thread_->NotifyKeywordsReady(template_urls,
+ default_keyword_index, unique_on_host_and_path);
+}
+
+void ExternalProcessImporterBridge::SetPasswordForm(
+ const webkit_glue::PasswordForm& form) {
+ // TODO(mirandac): http://crbug.com/18775
+ NOTIMPLEMENTED();
+}
+
+void ExternalProcessImporterBridge::NotifyItemStarted(
+ importer::ImportItem item) {
+ profile_import_thread_->NotifyItemStarted(item);
+}
+
+void ExternalProcessImporterBridge::NotifyItemEnded(importer::ImportItem item) {
+ profile_import_thread_->NotifyItemEnded(item);
+}
+
+void ExternalProcessImporterBridge::NotifyStarted() {
+ profile_import_thread_->NotifyStarted();
+}
+
+void ExternalProcessImporterBridge::NotifyEnded() {
+ // The internal process detects import end when all items have been received.
+}
+
+std::wstring ExternalProcessImporterBridge::GetLocalizedString(
+ int message_id) {
+ std::wstring message;
+ localized_strings_.GetString(IntToWString(message_id), &message);
+ return message;
+}
+
diff --git a/chrome/browser/importer/importer_bridge.h b/chrome/browser/importer/importer_bridge.h
index 14025e6..c6358da 100644
--- a/chrome/browser/importer/importer_bridge.h
+++ b/chrome/browser/importer/importer_bridge.h
@@ -10,20 +10,20 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/ref_counted.h"
#include "base/string16.h"
-
-#include "chrome/browser/importer/importer.h"
+#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/importer/importer_data_types.h"
// TODO: remove this, see friend declaration in ImporterBridge.
#include "chrome/browser/importer/toolbar_importer.h"
+class ProfileImportThread;
+class DictionaryValue;
+class ImporterHost;
+
class ImporterBridge : public base::RefCountedThreadSafe<ImporterBridge> {
public:
- ImporterBridge(ProfileWriter* writer,
- ImporterHost* host)
- : writer_(writer),
- host_(host) {
- }
+ ImporterBridge() { }
virtual void AddBookmarkEntries(
const std::vector<ProfileWriter::BookmarkEntry>& bookmarks,
@@ -57,6 +57,12 @@ class ImporterBridge : public base::RefCountedThreadSafe<ImporterBridge> {
// Notifies the coordinator that the entire import operation has completed.
virtual void NotifyEnded() = 0;
+ // For InProcessImporters this calls l10n_util. For ExternalProcessImporters
+ // this calls the set of strings we've ported over to the external process.
+ // It's good to avoid having to create a separate ResourceBundle for the
+ // external import process, since the importer only needs a few strings.
+ virtual std::wstring GetLocalizedString(int message_id) = 0;
+
protected:
friend class base::RefCountedThreadSafe<ImporterBridge>;
// TODO: In order to run Toolbar5Importer OOP we need to cut this
@@ -66,9 +72,6 @@ class ImporterBridge : public base::RefCountedThreadSafe<ImporterBridge> {
virtual ~ImporterBridge() {}
- ProfileWriter* writer_;
- ImporterHost* host_;
-
DISALLOW_COPY_AND_ASSIGN(ImporterBridge);
};
@@ -77,7 +80,8 @@ class InProcessImporterBridge : public ImporterBridge {
InProcessImporterBridge(ProfileWriter* writer,
ImporterHost* host);
- // Methods inherited from ImporterBridge.
+ // Methods inherited from ImporterBridge. On the internal side, these
+ // methods launch tasks to write the data to the profile with the |writer_|.
virtual void AddBookmarkEntries(
const std::vector<ProfileWriter::BookmarkEntry>& bookmarks,
const std::wstring& first_folder_name,
@@ -89,7 +93,7 @@ class InProcessImporterBridge : public ImporterBridge {
#endif
virtual void SetFavIcons(
- const std::vector<history::ImportedFavIconUsage>& fav_icons);
+ const std::vector<history::ImportedFavIconUsage>& fav_icons);
virtual void SetHistoryItems(const std::vector<history::URLRow> &rows);
virtual void SetKeywords(const std::vector<TemplateURL*>& template_urls,
int default_keyword_index,
@@ -100,11 +104,64 @@ class InProcessImporterBridge : public ImporterBridge {
virtual void NotifyItemEnded(importer::ImportItem item);
virtual void NotifyStarted();
virtual void NotifyEnded();
+ virtual std::wstring GetLocalizedString(int message_id);
private:
~InProcessImporterBridge() {}
+ ProfileWriter* const writer_; // weak
+ ImporterHost* const host_; // weak
+
DISALLOW_COPY_AND_ASSIGN(InProcessImporterBridge);
};
+// When the importer is run in an external process, the bridge is effectively
+// split in half by the IPC infrastructure. The external bridge receives data
+// and notifications from the importer, and sends it across IPC. The
+// internal bridge gathers the data from the IPC host and writes it to the
+// profile.
+class ExternalProcessImporterBridge : public ImporterBridge {
+ public:
+ ExternalProcessImporterBridge(ProfileImportThread* profile_import_thread,
+ const DictionaryValue& localized_strings);
+
+ // Methods inherited from ImporterBridge. On the external side, these
+ // methods gather data and give it to a ProfileImportThread to pass back
+ // to the browser process.
+ virtual void AddBookmarkEntries(
+ const std::vector<ProfileWriter::BookmarkEntry>& bookmarks,
+ const std::wstring& first_folder_name, int options);
+ virtual void AddHomePage(const GURL &home_page);
+
+#if defined(OS_WIN)
+ virtual void AddIE7PasswordInfo(const IE7PasswordInfo password_info);
+#endif
+
+ virtual void SetFavIcons(
+ const std::vector<history::ImportedFavIconUsage>& fav_icons);
+ virtual void SetHistoryItems(const std::vector<history::URLRow> &rows);
+ virtual void SetKeywords(const std::vector<TemplateURL*>& template_urls,
+ int default_keyword_index,
+ bool unique_on_host_and_path);
+ virtual void SetPasswordForm(const webkit_glue::PasswordForm& form);
+
+ virtual void NotifyItemStarted(importer::ImportItem item);
+ virtual void NotifyItemEnded(importer::ImportItem item);
+ virtual void NotifyStarted();
+ virtual void NotifyEnded();
+ virtual std::wstring GetLocalizedString(int message_id);
+
+ private:
+ ~ExternalProcessImporterBridge() {}
+
+ // Call back to send data and messages across IPC.
+ ProfileImportThread* const profile_import_thread_;
+
+ // Holds strings needed by the external importer because the resource
+ // bundle isn't available to the external process.
+ const DictionaryValue& localized_strings_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExternalProcessImporterBridge);
+};
+
#endif // CHROME_BROWSER_IMPORTER_IMPORTER_BRIDGE_H_
diff --git a/chrome/browser/importer/importer_list.cc b/chrome/browser/importer/importer_list.cc
index 2fdd559..0919489 100644
--- a/chrome/browser/importer/importer_list.cc
+++ b/chrome/browser/importer/importer_list.cc
@@ -153,7 +153,7 @@ void ImporterList::DetectFirefoxProfiles() {
if (firefox->app_path.empty())
firefox->app_path = app_path;
firefox->services_supported = importer::HISTORY | importer::FAVORITES |
- importer::COOKIES | importer::PASSWORDS | importer::SEARCH_ENGINES;
+ importer::PASSWORDS | importer::SEARCH_ENGINES;
source_profiles_.push_back(firefox);
}
diff --git a/chrome/browser/importer/importer_messages.h b/chrome/browser/importer/importer_messages.h
new file mode 100644
index 0000000..0ed8002
--- /dev/null
+++ b/chrome/browser/importer/importer_messages.h
@@ -0,0 +1,369 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_IMPORTER_IMPORTER_MESSAGES_H_
+#define CHROME_BROWSER_IMPORTER_IMPORTER_MESSAGES_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "chrome/browser/history/history_types.h"
+#include "chrome/browser/importer/importer_data_types.h"
+#include "chrome/browser/importer/profile_writer.h"
+#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/common/common_param_traits.h"
+#include "ipc/ipc_message_utils.h"
+
+namespace IPC {
+
+// Traits for importer::ProfileInfo struct to pack/unpack.
+template <>
+struct ParamTraits<importer::ProfileInfo> {
+ typedef importer::ProfileInfo param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.description);
+ WriteParam(m, static_cast<int>(p.browser_type));
+ WriteParam(m, p.source_path);
+ WriteParam(m, p.app_path);
+ WriteParam(m, static_cast<int>(p.services_supported));
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ if (!ReadParam(m, iter, &p->description))
+ return false;
+
+ int browser_type = 0;
+ if (!ReadParam(m, iter, &browser_type))
+ return false;
+ p->browser_type = static_cast<importer::ProfileType>(browser_type);
+
+ if (!ReadParam(m, iter, &p->source_path) ||
+ !ReadParam(m, iter, &p->app_path))
+ return false;
+
+ int services_supported = 0;
+ if (!ReadParam(m, iter, &services_supported))
+ return false;
+ p->services_supported = static_cast<uint16>(services_supported);
+
+ return true;
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"(");
+ LogParam(p.description, l);
+ l->append(L", ");
+ LogParam(static_cast<int>(p.browser_type), l);
+ l->append(L", ");
+ LogParam(p.source_path, l);
+ l->append(L", ");
+ LogParam(p.app_path, l);
+ l->append(L", ");
+ LogParam(static_cast<int>(p.services_supported), l);
+ l->append(L")");
+ }
+}; // ParamTraits<importer::ProfileInfo>
+
+// Traits for history::URLRow to pack/unpack.
+template <>
+struct ParamTraits<history::URLRow> {
+ typedef history::URLRow param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.id());
+ WriteParam(m, p.url());
+ WriteParam(m, p.title());
+ WriteParam(m, p.visit_count());
+ WriteParam(m, p.typed_count());
+ WriteParam(m, p.last_visit());
+ WriteParam(m, p.hidden());
+ WriteParam(m, p.favicon_id());
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ history::URLID id;
+ GURL url;
+ std::wstring title;
+ int visit_count, typed_count;
+ base::Time last_visit;
+ bool hidden;
+ history::FavIconID favicon_id;
+ if (!ReadParam(m, iter, &id) ||
+ !ReadParam(m, iter, &url) ||
+ !ReadParam(m, iter, &title) ||
+ !ReadParam(m, iter, &visit_count) ||
+ !ReadParam(m, iter, &typed_count) ||
+ !ReadParam(m, iter, &last_visit) ||
+ !ReadParam(m, iter, &hidden) ||
+ !ReadParam(m, iter, &favicon_id))
+ return false;
+ *p = history::URLRow(url, id);
+ p->set_title(title);
+ p->set_visit_count(visit_count);
+ p->set_typed_count(typed_count);
+ p->set_last_visit(last_visit);
+ p->set_hidden(hidden);
+ p->set_favicon_id(favicon_id);
+ return true;
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"(");
+ LogParam(p.id(), l);
+ l->append(L", ");
+ LogParam(p.url(), l);
+ l->append(L", ");
+ LogParam(p.title(), l);
+ l->append(L", ");
+ LogParam(p.visit_count(), l);
+ l->append(L", ");
+ LogParam(p.typed_count(), l);
+ l->append(L", ");
+ LogParam(p.last_visit(), l);
+ l->append(L", ");
+ LogParam(p.hidden(), l);
+ l->append(L", ");
+ LogParam(p.favicon_id(), l);
+ l->append(L")");
+ }
+}; // ParamTraits<history::URLRow>
+
+// Traits for ProfileWriter::BookmarkEntry to pack/unpack.
+template <>
+struct ParamTraits<ProfileWriter::BookmarkEntry> {
+ typedef ProfileWriter::BookmarkEntry param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.in_toolbar);
+ WriteParam(m, p.url);
+ WriteParam(m, p.path);
+ WriteParam(m, p.title);
+ WriteParam(m, p.creation_time);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return
+ (ReadParam(m, iter, &p->in_toolbar)) &&
+ (ReadParam(m, iter, &p->url)) &&
+ (ReadParam(m, iter, &p->path)) &&
+ (ReadParam(m, iter, &p->title)) &&
+ (ReadParam(m, iter, &p->creation_time));
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"(");
+ LogParam(p.in_toolbar, l);
+ l->append(L", ");
+ LogParam(p.url, l);
+ l->append(L", ");
+ LogParam(p.path, l);
+ l->append(L", ");
+ LogParam(p.title, l);
+ l->append(L", ");
+ LogParam(p.creation_time, l);
+ l->append(L")");
+ }
+}; // ParamTraits<ProfileWriter::BookmarkEntry>
+
+// Traits for history::ImportedFavIconUsage.
+template <>
+struct ParamTraits<history::ImportedFavIconUsage> {
+ typedef history::ImportedFavIconUsage param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.favicon_url);
+ WriteParam(m, p.png_data);
+ WriteParam(m, p.urls);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return
+ ReadParam(m, iter, &p->favicon_url) &&
+ ReadParam(m, iter, &p->png_data) &&
+ ReadParam(m, iter, &p->urls);
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"(");
+ LogParam(p.favicon_url, l);
+ l->append(L", ");
+ LogParam(p.png_data, l);
+ l->append(L", ");
+ LogParam(p.urls, l);
+ l->append(L")");
+ }
+}; // ParamTraits<history::ImportedFavIconUsage
+
+// Traits for TemplateURLRef
+template <>
+struct ParamTraits<TemplateURLRef> {
+ typedef TemplateURLRef param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.url());
+ WriteParam(m, p.index_offset());
+ WriteParam(m, p.page_offset());
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ std::wstring url;
+ int index_offset;
+ int page_offset;
+ if (!ReadParam(m, iter, &url) ||
+ !ReadParam(m, iter, &index_offset) ||
+ !ReadParam(m, iter, &page_offset))
+ return false;
+ *p = TemplateURLRef(url, index_offset, page_offset);
+ return true;
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"<TemplateURLRef>");
+ }
+};
+
+// Traits for TemplateURL::ImageRef
+template <>
+struct ParamTraits<TemplateURL::ImageRef> {
+ typedef TemplateURL::ImageRef param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.type);
+ WriteParam(m, p.width);
+ WriteParam(m, p.height);
+ WriteParam(m, p.url);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ std::wstring type;
+ int width;
+ int height;
+ GURL url;
+ if (!ReadParam(m, iter, &type) ||
+ !ReadParam(m, iter, &width) ||
+ !ReadParam(m, iter, &height) ||
+ !ReadParam(m, iter, &url))
+ return false;
+ *p = TemplateURL::ImageRef(type, width, height, url); // here in
+ return true;
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"<TemplateURL::ImageRef>");
+ }
+};
+
+// Traits for TemplateURL
+template <>
+struct ParamTraits<TemplateURL> {
+ typedef TemplateURL param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.short_name());
+ WriteParam(m, p.description());
+ if (p.suggestions_url()) {
+ WriteParam(m, true);
+ WriteParam(m, *p.suggestions_url());
+ } else {
+ WriteParam(m, false);
+ }
+ WriteParam(m, *p.url());
+ WriteParam(m, p.originating_url());
+ WriteParam(m, p.keyword());
+ WriteParam(m, p.autogenerate_keyword());
+ WriteParam(m, p.show_in_default_list());
+ WriteParam(m, p.safe_for_autoreplace());
+ WriteParam(m, p.image_refs().size());
+
+ std::vector<TemplateURL::ImageRef>::const_iterator iter;
+ for (iter = p.image_refs().begin(); iter != p.image_refs().end(); ++iter) {
+ WriteParam(m, iter->type);
+ WriteParam(m, iter->width);
+ WriteParam(m, iter->height);
+ WriteParam(m, iter->url);
+ }
+
+ WriteParam(m, p.languages());
+ WriteParam(m, p.input_encodings());
+ WriteParam(m, p.date_created());
+ WriteParam(m, p.usage_count());
+ WriteParam(m, p.prepopulate_id());
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ std::wstring short_name;
+ std::wstring description;
+ bool includes_suggestions_url;
+ TemplateURLRef suggestions_url;
+ TemplateURLRef url;
+ GURL originating_url;
+ std::wstring keyword;
+ bool autogenerate_keyword;
+ bool show_in_default_list;
+ bool safe_for_autoreplace;
+ std::vector<std::wstring> languages;
+ std::vector<std::string> input_encodings;
+ base::Time date_created;
+ int usage_count;
+ int prepopulate_id;
+
+ if (!ReadParam(m, iter, &short_name) ||
+ !ReadParam(m, iter, &description))
+ return false;
+
+ if (!ReadParam(m, iter, &includes_suggestions_url))
+ return false;
+ if (includes_suggestions_url) {
+ if (!ReadParam(m, iter, &suggestions_url))
+ return false;
+ }
+
+ size_t image_refs_size = 0;
+ if (!ReadParam(m, iter, &url) ||
+ !ReadParam(m, iter, &originating_url) ||
+ !ReadParam(m, iter, &keyword) ||
+ !ReadParam(m, iter, &autogenerate_keyword) ||
+ !ReadParam(m, iter, &show_in_default_list) ||
+ !ReadParam(m, iter, &safe_for_autoreplace) ||
+ !ReadParam(m, iter, &image_refs_size))
+ return false;
+
+ *p = TemplateURL();
+ for (size_t i = 0; i < image_refs_size; ++i) {
+ std::wstring type;
+ int width;
+ int height;
+ GURL url;
+ if (!ReadParam(m, iter, &type) ||
+ !ReadParam(m, iter, &width) ||
+ !ReadParam(m, iter, &height) ||
+ !ReadParam(m, iter, &url))
+ return false;
+ p->add_image_ref(TemplateURL::ImageRef(type, width, height, url));
+ }
+
+ if (!ReadParam(m, iter, &languages) ||
+ !ReadParam(m, iter, &input_encodings) ||
+ !ReadParam(m, iter, &date_created) ||
+ !ReadParam(m, iter, &usage_count) ||
+ !ReadParam(m, iter, &prepopulate_id))
+ return false;
+
+ p->set_short_name(short_name);
+ p->set_description(description);
+ p->SetSuggestionsURL(suggestions_url.url(), suggestions_url.index_offset(),
+ suggestions_url.page_offset());
+ p->SetURL(url.url(), url.index_offset(), url.page_offset());
+ p->set_originating_url(originating_url);
+ p->set_keyword(keyword);
+ p->set_autogenerate_keyword(autogenerate_keyword);
+ p->set_show_in_default_list(show_in_default_list);
+ p->set_safe_for_autoreplace(safe_for_autoreplace);
+
+ std::vector<std::wstring>::const_iterator lang_iter;
+ for (lang_iter = languages.begin();
+ lang_iter != languages.end();
+ ++lang_iter) {
+ p->add_language(*lang_iter);
+ }
+ p->set_input_encodings(input_encodings);
+ p->set_date_created(date_created);
+ p->set_usage_count(usage_count);
+ p->set_prepopulate_id(prepopulate_id);
+ return true;
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"<TemplateURL>");
+ }
+};
+
+} // namespace IPC
+
+#define MESSAGES_INTERNAL_FILE \
+ "chrome/browser/importer/importer_messages_internal.h"
+#include "ipc/ipc_message_macros.h"
+
+#endif // CHROME_BROWSER_IMPORTER_IMPORTER_MESSAGES_H_
diff --git a/chrome/browser/importer/importer_messages_internal.h b/chrome/browser/importer/importer_messages_internal.h
new file mode 100644
index 0000000..b247237
--- /dev/null
+++ b/chrome/browser/importer/importer_messages_internal.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+#include <vector>
+
+#include "chrome/browser/history/history_types.h"
+#include "chrome/browser/importer/importer_data_types.h"
+#include "ipc/ipc_message_macros.h"
+#include "webkit/glue/password_form.h"
+
+//-----------------------------------------------------------------------------
+// ProfileImportProcess messages
+// These are messages sent from the browser to the profile import process.
+IPC_BEGIN_MESSAGES(ProfileImportProcess)
+ IPC_MESSAGE_CONTROL4(ProfileImportProcessMsg_StartImport,
+ importer::ProfileInfo /* ProfileInfo struct */,
+ int /* bitmask of items to import */,
+ DictionaryValue /* localized strings */,
+ bool /* import to bookmark bar */)
+
+ IPC_MESSAGE_CONTROL0(ProfileImportProcessMsg_CancelImport)
+
+ IPC_MESSAGE_CONTROL1(ProfileImportProcessMsg_ReportImportItemFinished,
+ int /* ImportItem */)
+IPC_END_MESSAGES(ProfileImportProcess)
+
+//---------------------------------------------------------------------------
+// ProfileImportProcessHost messages
+// These are messages sent from the profile import process to the browser.
+IPC_BEGIN_MESSAGES(ProfileImportProcessHost)
+ // These messages send information about the status of the import and
+ // individual import tasks.
+ IPC_MESSAGE_CONTROL0(ProfileImportProcessHostMsg_Import_Started)
+
+ IPC_MESSAGE_CONTROL2(ProfileImportProcessHostMsg_Import_Finished,
+ bool /* was import successful? */,
+ std::string /* error message, if any */)
+
+ IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_ImportItem_Started,
+ int /* ImportItem */)
+
+ IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_ImportItem_Finished,
+ int /* ImportItem */)
+
+ // These messages send data from the external importer process back to
+ // the process host so it can be written to the profile.
+ IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_NotifyHistoryImportStart,
+ int /* total number of history::URLRow items */)
+
+ IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_NotifyHistoryImportGroup,
+ std::vector<history::URLRow>)
+
+ IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_NotifyHomePageImportReady,
+ GURL /* GURL of home page */)
+
+ IPC_MESSAGE_CONTROL3(ProfileImportProcessHostMsg_NotifyBookmarksImportStart,
+ std::wstring /* first folder name */,
+ int /* options */,
+ int /* total number of bookmarks */)
+
+ IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_NotifyBookmarksImportGroup,
+ std::vector<ProfileWriter::BookmarkEntry>)
+
+ IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_NotifyFavIconsImportStart,
+ int /* total number of FavIcons */)
+
+ IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_NotifyFavIconsImportGroup,
+ std::vector<history::ImportedFavIconUsage> )
+
+ IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_NotifyPasswordFormReady,
+ webkit_glue::PasswordForm )
+
+ IPC_MESSAGE_CONTROL3(ProfileImportProcessHostMsg_NotifyKeywordsReady,
+ std::vector<TemplateURL>,
+ int, /* default keyword index */
+ bool /* unique on host and path */)
+IPC_END_MESSAGES(ProfileImportProcessHost)
+
diff --git a/chrome/browser/importer/importer_unittest.cc b/chrome/browser/importer/importer_unittest.cc
index 3da8361..8a9f50c 100644
--- a/chrome/browser/importer/importer_unittest.cc
+++ b/chrome/browser/importer/importer_unittest.cc
@@ -205,8 +205,8 @@ class TestObserver : public ProfileWriter,
password_count_ = 0;
}
- virtual void ImportItemStarted(ImportItem item) {}
- virtual void ImportItemEnded(ImportItem item) {}
+ virtual void ImportItemStarted(importer::ImportItem item) {}
+ virtual void ImportItemEnded(importer::ImportItem item) {}
virtual void ImportStarted() {}
virtual void ImportEnded() {
MessageLoop::current()->Quit();
@@ -554,8 +554,8 @@ class FirefoxObserver : public ProfileWriter,
keyword_count_ = 0;
}
- virtual void ImportItemStarted(ImportItem item) {}
- virtual void ImportItemEnded(ImportItem item) {}
+ virtual void ImportItemStarted(importer::ImportItem item) {}
+ virtual void ImportItemEnded(importer::ImportItem item) {}
virtual void ImportStarted() {}
virtual void ImportEnded() {
MessageLoop::current()->Quit();
@@ -750,8 +750,8 @@ class Firefox3Observer : public ProfileWriter,
import_search_engines_(import_search_engines) {
}
- virtual void ImportItemStarted(ImportItem item) {}
- virtual void ImportItemEnded(ImportItem item) {}
+ virtual void ImportItemStarted(importer::ImportItem item) {}
+ virtual void ImportItemEnded(importer::ImportItem item) {}
virtual void ImportStarted() {}
virtual void ImportEnded() {
MessageLoop::current()->Quit();
diff --git a/chrome/browser/importer/safari_importer.mm b/chrome/browser/importer/safari_importer.mm
index e503165..b124b84 100644
--- a/chrome/browser/importer/safari_importer.mm
+++ b/chrome/browser/importer/safari_importer.mm
@@ -9,7 +9,6 @@
#include <map>
#include <vector>
-#include "app/l10n_util.h"
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/scoped_nsobject.h"
@@ -18,6 +17,7 @@
#include "base/time.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/importer/importer_bridge.h"
+#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/common/sqlite_utils.h"
#include "chrome/common/url_constants.h"
#include "googleurl/src/gurl.h"
@@ -57,7 +57,7 @@ SafariImporter::~SafariImporter() {
bool SafariImporter::CanImport(const FilePath& library_dir,
uint16 *services_supported) {
DCHECK(services_supported);
- *services_supported = NONE;
+ *services_supported = importer::NONE;
// Import features are toggled by the following:
// bookmarks import: existence of ~/Library/Safari/Bookmarks.plist file.
@@ -68,37 +68,36 @@ bool SafariImporter::CanImport(const FilePath& library_dir,
using file_util::PathExists;
if (PathExists(bookmarks_path))
- *services_supported |= FAVORITES;
+ *services_supported |= importer::FAVORITES;
if (PathExists(history_path))
- *services_supported |= HISTORY;
+ *services_supported |= importer::HISTORY;
- return *services_supported != NONE;
+ return *services_supported != importer::NONE;
}
-void SafariImporter::StartImport(ProfileInfo profile_info,
+void SafariImporter::StartImport(importer::ProfileInfo profile_info,
uint16 services_supported,
ImporterBridge* bridge) {
bridge_ = bridge;
-
// The order here is important!
bridge_->NotifyStarted();
// In keeping with import on other platforms (and for other browsers), we
// don't import the home page (since it may lead to a useless homepage); see
// crbug.com/25603.
- if ((services_supported & HISTORY) && !cancelled()) {
- bridge_->NotifyItemStarted(HISTORY);
+ if ((services_supported & importer::HISTORY) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::HISTORY);
ImportHistory();
- bridge_->NotifyItemEnded(HISTORY);
+ bridge_->NotifyItemEnded(importer::HISTORY);
}
- if ((services_supported & FAVORITES) && !cancelled()) {
- bridge_->NotifyItemStarted(FAVORITES);
+ if ((services_supported & importer::FAVORITES) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::FAVORITES);
ImportBookmarks();
- bridge_->NotifyItemEnded(FAVORITES);
+ bridge_->NotifyItemEnded(importer::FAVORITES);
}
- if ((services_supported & PASSWORDS) && !cancelled()) {
- bridge_->NotifyItemStarted(PASSWORDS);
+ if ((services_supported & importer::PASSWORDS) && !cancelled()) {
+ bridge_->NotifyItemStarted(importer::PASSWORDS);
ImportPasswords();
- bridge_->NotifyItemEnded(PASSWORDS);
+ bridge_->NotifyItemEnded(importer::PASSWORDS);
}
bridge_->NotifyEnded();
}
@@ -110,7 +109,7 @@ void SafariImporter::ImportBookmarks() {
// Write bookmarks into profile.
if (!bookmarks.empty() && !cancelled()) {
const std::wstring& first_folder_name =
- l10n_util::GetString(IDS_BOOKMARK_GROUP_FROM_SAFARI);
+ bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_SAFARI);
int options = 0;
if (import_to_bookmark_bar())
options = ProfileWriter::IMPORT_TO_BOOKMARK_BAR;
@@ -348,7 +347,8 @@ void SafariImporter::ParseHistoryItems(
if (!history_dict)
return;
- NSArray* safari_history_items = [history_dict objectForKey:@"WebHistoryDates"];
+ NSArray* safari_history_items = [history_dict
+ objectForKey:@"WebHistoryDates"];
for (NSDictionary* history_item in safari_history_items) {
using base::SysNSStringToUTF8;
diff --git a/chrome/browser/importer/toolbar_importer.cc b/chrome/browser/importer/toolbar_importer.cc
index 767d608..5b0a93c 100644
--- a/chrome/browser/importer/toolbar_importer.cc
+++ b/chrome/browser/importer/toolbar_importer.cc
@@ -6,12 +6,12 @@
#include <limits>
-#include "app/l10n_util.h"
#include "base/rand_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/importer/importer_bridge.h"
+#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/browser/profile.h"
#include "chrome/common/libxml_utils.h"
#include "chrome/common/net/url_request_context_getter.h"
@@ -82,7 +82,7 @@ const char Toolbar5Importer::kT5FrontEndUrlTemplate[] =
// The constructor should set the initial state to NOT_USED.
Toolbar5Importer::Toolbar5Importer()
: state_(NOT_USED),
- items_to_import_(NONE),
+ items_to_import_(importer::NONE),
token_fetcher_(NULL),
data_fetcher_(NULL) {
}
@@ -95,7 +95,7 @@ Toolbar5Importer::~Toolbar5Importer() {
DCHECK(!data_fetcher_);
}
-void Toolbar5Importer::StartImport(ProfileInfo profile_info,
+void Toolbar5Importer::StartImport(importer::ProfileInfo profile_info,
uint16 items,
ImporterBridge* bridge) {
DCHECK(bridge);
@@ -162,18 +162,18 @@ void Toolbar5Importer::OnURLFetchComplete(
}
void Toolbar5Importer::ContinueImport() {
- DCHECK((items_to_import_ == FAVORITES) ||
- (items_to_import_ == NONE)) <<
+ DCHECK((items_to_import_ == importer::FAVORITES) ||
+ (items_to_import_ == importer::NONE)) <<
"The items requested are not supported";
// The order here is important. Each Begin... will clear the flag
// of its item before its task finishes and re-enters this method.
- if (NONE == items_to_import_) {
+ if (importer::NONE == items_to_import_) {
EndImport();
return;
}
- if ((items_to_import_ & FAVORITES) && !cancelled()) {
- items_to_import_ &= ~FAVORITES;
+ if ((items_to_import_ & importer::FAVORITES) && !cancelled()) {
+ items_to_import_ &= ~importer::FAVORITES;
BeginImportBookmarks();
return;
}
@@ -207,12 +207,12 @@ void Toolbar5Importer::EndImport() {
}
void Toolbar5Importer::BeginImportBookmarks() {
- bridge_->NotifyItemStarted(FAVORITES);
+ bridge_->NotifyItemStarted(importer::FAVORITES);
GetAuthenticationFromServer();
}
void Toolbar5Importer::EndImportBookmarks() {
- bridge_->NotifyItemEnded(FAVORITES);
+ bridge_->NotifyItemEnded(importer::FAVORITES);
ContinueImport();
}
@@ -291,7 +291,9 @@ void Toolbar5Importer::GetBookmarksFromServerDataResponse(
if (reader.Load(response) && !cancelled()) {
// Construct Bookmarks
std::vector<ProfileWriter::BookmarkEntry> bookmarks;
- if (ParseBookmarksFromReader(&reader, &bookmarks))
+ if (ParseBookmarksFromReader(&reader, &bookmarks,
+ WideToUTF16(bridge_->GetLocalizedString(
+ IDS_BOOKMARK_GROUP_FROM_GOOGLE_TOOLBAR))))
AddBookmarksToChrome(bookmarks);
}
EndImportBookmarks();
@@ -319,7 +321,8 @@ bool Toolbar5Importer::ParseAuthenticationTokenResponse(
// Parsing
bool Toolbar5Importer::ParseBookmarksFromReader(
XmlReader* reader,
- std::vector<ProfileWriter::BookmarkEntry>* bookmarks) {
+ std::vector<ProfileWriter::BookmarkEntry>* bookmarks,
+ const string16& bookmark_group_string) {
DCHECK(reader);
DCHECK(bookmarks);
@@ -341,7 +344,8 @@ bool Toolbar5Importer::ParseBookmarksFromReader(
kBookmarksXmlTag)) {
ProfileWriter::BookmarkEntry bookmark_entry;
std::vector<BookmarkFolderType> folders;
- if (ExtractBookmarkInformation(reader, &bookmark_entry, &folders)) {
+ if (ExtractBookmarkInformation(reader, &bookmark_entry, &folders,
+ bookmark_group_string)) {
// For each folder we create a new bookmark entry. Duplicates will
// be detected when we attempt to create the bookmark in the profile.
for (std::vector<BookmarkFolderType>::iterator folder = folders.begin();
@@ -402,7 +406,8 @@ bool Toolbar5Importer::LocateNextTagWithStopByName(XmlReader* reader,
bool Toolbar5Importer::ExtractBookmarkInformation(
XmlReader* reader,
ProfileWriter::BookmarkEntry* bookmark_entry,
- std::vector<BookmarkFolderType>* bookmark_folders) {
+ std::vector<BookmarkFolderType>* bookmark_folders,
+ const string16& bookmark_group_string) {
DCHECK(reader);
DCHECK(bookmark_entry);
DCHECK(bookmark_folders);
@@ -451,7 +456,8 @@ bool Toolbar5Importer::ExtractBookmarkInformation(
return false;
if (!ExtractTimeFromXmlReader(reader, bookmark_entry))
return false;
- if (!ExtractFoldersFromXmlReader(reader, bookmark_folders))
+ if (!ExtractFoldersFromXmlReader(reader, bookmark_folders,
+ bookmark_group_string))
return false;
return true;
@@ -523,7 +529,8 @@ bool Toolbar5Importer::ExtractTimeFromXmlReader(
bool Toolbar5Importer::ExtractFoldersFromXmlReader(
XmlReader* reader,
- std::vector<BookmarkFolderType>* bookmark_folders) {
+ std::vector<BookmarkFolderType>* bookmark_folders,
+ const string16& bookmark_group_string) {
DCHECK(reader);
DCHECK(bookmark_folders);
@@ -550,8 +557,7 @@ bool Toolbar5Importer::ExtractFoldersFromXmlReader(
if (0 == label_vector.size()) {
if (!FirstRun::IsChromeFirstRun()) {
bookmark_folders->resize(1);
- (*bookmark_folders)[0].push_back(
- l10n_util::GetString(IDS_BOOKMARK_GROUP_FROM_GOOGLE_TOOLBAR));
+ (*bookmark_folders)[0].push_back(UTF16ToWide(bookmark_group_string));
}
return true;
}
@@ -563,8 +569,7 @@ bool Toolbar5Importer::ExtractFoldersFromXmlReader(
// If this is the first run then we place favorites with no labels
// in the title bar. Else they are placed in the "Google Toolbar" folder.
if (!FirstRun::IsChromeFirstRun() || !label_vector[index].empty()) {
- (*bookmark_folders)[index].push_back(
- l10n_util::GetString(IDS_BOOKMARK_GROUP_FROM_GOOGLE_TOOLBAR));
+ (*bookmark_folders)[index].push_back(UTF16ToWide(bookmark_group_string));
}
// If the label and is in the form "xxx:yyy:zzz" this was created from an
@@ -584,7 +589,7 @@ void Toolbar5Importer::AddBookmarksToChrome(
const std::vector<ProfileWriter::BookmarkEntry>& bookmarks) {
if (!bookmarks.empty() && !cancelled()) {
const std::wstring& first_folder_name =
- l10n_util::GetString(IDS_BOOKMARK_GROUP_FROM_GOOGLE_TOOLBAR);
+ bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_GOOGLE_TOOLBAR);
int options = ProfileWriter::ADD_IF_UNIQUE |
(import_to_bookmark_bar() ? ProfileWriter::IMPORT_TO_BOOKMARK_BAR : 0);
bridge_->AddBookmarkEntries(bookmarks, first_folder_name, options);
diff --git a/chrome/browser/importer/toolbar_importer.h b/chrome/browser/importer/toolbar_importer.h
index 1f5bb48..0f31832 100644
--- a/chrome/browser/importer/toolbar_importer.h
+++ b/chrome/browser/importer/toolbar_importer.h
@@ -12,6 +12,7 @@
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/string16.h"
#include "chrome/browser/importer/importer.h"
#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/common/net/url_fetcher.h"
@@ -121,7 +122,8 @@ class Toolbar5Importer : public URLFetcher::Delegate, public Importer {
static bool ParseBookmarksFromReader(
XmlReader* reader,
- std::vector<ProfileWriter::BookmarkEntry>* bookmarks);
+ std::vector<ProfileWriter::BookmarkEntry>* bookmarks,
+ const string16& bookmark_group_string);
static bool LocateNextOpenTag(XmlReader* reader);
static bool LocateNextTagByName(XmlReader* reader, const std::string& tag);
@@ -133,7 +135,8 @@ class Toolbar5Importer : public URLFetcher::Delegate, public Importer {
static bool ExtractBookmarkInformation(
XmlReader* reader,
ProfileWriter::BookmarkEntry* bookmark_entry,
- std::vector<BookmarkFolderType>* bookmark_folders);
+ std::vector<BookmarkFolderType>* bookmark_folders,
+ const string16& bookmark_group_string);
static bool ExtractNamedValueFromXmlReader(XmlReader* reader,
const std::string& name,
std::string* buffer);
@@ -145,7 +148,8 @@ class Toolbar5Importer : public URLFetcher::Delegate, public Importer {
ProfileWriter::BookmarkEntry* entry);
static bool ExtractFoldersFromXmlReader(
XmlReader* reader,
- std::vector<BookmarkFolderType>* bookmark_folders);
+ std::vector<BookmarkFolderType>* bookmark_folders,
+ const string16& bookmark_group_string);
// Bookmark creation is done by the method below.
void AddBookmarksToChrome(
diff --git a/chrome/browser/importer/toolbar_importer_unittest.cc b/chrome/browser/importer/toolbar_importer_unittest.cc
index 100e490..0bc6ab5 100644
--- a/chrome/browser/importer/toolbar_importer_unittest.cc
+++ b/chrome/browser/importer/toolbar_importer_unittest.cc
@@ -7,6 +7,7 @@
#include <string>
#include <vector>
+#include "base/string16.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/importer/importer.h"
#include "chrome/browser/importer/toolbar_importer.h"
@@ -25,6 +26,8 @@ static const wchar_t* kOtherTitle = L"MyOtherTitle";
static const char* kOtherUrl = "http://www.google.com/mail";
static const wchar_t* kOtherFolder = L"Mail";
+static const string16 kBookmarkGroupTitle = ASCIIToUTF16("BookmarkGroupTitle");
+
// Since the following is very dense to read I enumerate the test cases here.
// 1. Correct bookmark structure with one label.
// 2. Correct bookmark structure with no labels.
@@ -322,7 +325,8 @@ static const char* kBadBookmarkNoLabels =
bookmarks.clear();
XmlReader reader1;
EXPECT_TRUE(reader1.Load(bookmark_xml));
- EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader1, &bookmarks));
+ EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader1, &bookmarks,
+ kBookmarkGroupTitle));
ASSERT_EQ(1U, bookmarks.size());
EXPECT_FALSE(bookmarks[0].in_toolbar);
@@ -336,7 +340,8 @@ static const char* kBadBookmarkNoLabels =
bookmarks.clear();
XmlReader reader2;
EXPECT_TRUE(reader2.Load(bookmark_xml));
- EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader2, &bookmarks));
+ EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader2, &bookmarks,
+ kBookmarkGroupTitle));
ASSERT_EQ(1U, bookmarks.size());
EXPECT_FALSE(bookmarks[0].in_toolbar);
@@ -349,7 +354,8 @@ static const char* kBadBookmarkNoLabels =
bookmarks.clear();
XmlReader reader3;
EXPECT_TRUE(reader3.Load(bookmark_xml));
- EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader3, &bookmarks));
+ EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader3, &bookmarks,
+ kBookmarkGroupTitle));
ASSERT_EQ(2U, bookmarks.size());
EXPECT_FALSE(bookmarks[0].in_toolbar);
@@ -369,7 +375,8 @@ static const char* kBadBookmarkNoLabels =
bookmarks.clear();
XmlReader reader4;
EXPECT_TRUE(reader4.Load(bookmark_xml));
- EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader4, &bookmarks));
+ EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader4, &bookmarks,
+ kBookmarkGroupTitle));
ASSERT_EQ(1U, bookmarks.size());
EXPECT_FALSE(bookmarks[0].in_toolbar);
@@ -388,7 +395,8 @@ static const char* kBadBookmarkNoLabels =
bookmarks.clear();
XmlReader reader5;
EXPECT_TRUE(reader5.Load(bookmark_xml));
- EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader5, &bookmarks));
+ EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader5, &bookmarks,
+ kBookmarkGroupTitle));
ASSERT_EQ(1U, bookmarks.size());
EXPECT_FALSE(bookmarks[0].in_toolbar);
@@ -402,7 +410,8 @@ static const char* kBadBookmarkNoLabels =
bookmarks.clear();
XmlReader reader6;
EXPECT_TRUE(reader6.Load(bookmark_xml));
- EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader6, &bookmarks));
+ EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader6, &bookmarks,
+ kBookmarkGroupTitle));
ASSERT_EQ(2U, bookmarks.size());
EXPECT_FALSE(bookmarks[0].in_toolbar);
@@ -428,7 +437,7 @@ static const char* kBadBookmarkNoLabels =
XmlReader reader8;
EXPECT_TRUE(reader8.Load(bookmark_xml));
EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader8,
- &bookmarks));
+ &bookmarks, kBookmarkGroupTitle));
// Test case 9 tests when no <bookmark> section is present.
bookmark_xml = kBadBookmarkNoBookmark;
@@ -436,7 +445,7 @@ static const char* kBadBookmarkNoLabels =
XmlReader reader9;
EXPECT_TRUE(reader9.Load(bookmark_xml));
EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader9,
- &bookmarks));
+ &bookmarks, kBookmarkGroupTitle));
// Test case 10 tests when a bookmark has no <title> section.
@@ -445,7 +454,7 @@ static const char* kBadBookmarkNoLabels =
XmlReader reader10;
EXPECT_TRUE(reader10.Load(bookmark_xml));
EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader10,
- &bookmarks));
+ &bookmarks, kBookmarkGroupTitle));
// Test case 11 tests when a bookmark has no <url> section.
bookmark_xml = kBadBookmarkNoUrl;
@@ -453,7 +462,7 @@ static const char* kBadBookmarkNoLabels =
XmlReader reader11;
EXPECT_TRUE(reader11.Load(bookmark_xml));
EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader11,
- &bookmarks));
+ &bookmarks, kBookmarkGroupTitle));
// Test case 12 tests when a bookmark has no <timestamp> section.
bookmark_xml = kBadBookmarkNoTimestamp;
@@ -461,7 +470,7 @@ static const char* kBadBookmarkNoLabels =
XmlReader reader12;
EXPECT_TRUE(reader12.Load(bookmark_xml));
EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader12,
- &bookmarks));
+ &bookmarks, kBookmarkGroupTitle));
// Test case 13 tests when a bookmark has no <labels> section.
bookmark_xml = kBadBookmarkNoLabels;
@@ -469,5 +478,5 @@ static const char* kBadBookmarkNoLabels =
XmlReader reader13;
EXPECT_TRUE(reader13.Load(bookmark_xml));
EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader13,
- &bookmarks));
+ &bookmarks, kBookmarkGroupTitle));
}
diff --git a/chrome/browser/profile_import_process_host.cc b/chrome/browser/profile_import_process_host.cc
new file mode 100644
index 0000000..ffe0395
--- /dev/null
+++ b/chrome/browser/profile_import_process_host.cc
@@ -0,0 +1,169 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/profile_import_process_host.h"
+
+#include "app/l10n_util.h"
+#include "base/command_line.h"
+#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "base/values.h"
+#include "chrome/browser/importer/firefox_importer_utils.h"
+#include "chrome/browser/importer/importer_messages.h"
+#include "chrome/common/chrome_switches.h"
+#include "grit/generated_resources.h"
+#include "ipc/ipc_switches.h"
+
+ProfileImportProcessHost::ProfileImportProcessHost(
+ ResourceDispatcherHost* resource_dispatcher,
+ ImportProcessClient* import_process_client,
+ ChromeThread::ID thread_id)
+ : ChildProcessHost(PROFILE_IMPORT_PROCESS, resource_dispatcher),
+ import_process_client_(import_process_client),
+ thread_id_(thread_id) {
+}
+
+bool ProfileImportProcessHost::StartProfileImportProcess(
+ const importer::ProfileInfo& profile_info, int items,
+ bool import_to_bookmark_bar) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ if (!StartProcess())
+ return false;
+
+ // Dictionary of all localized strings that could be needed by the importer
+ // in the external process.
+ DictionaryValue localized_strings;
+ localized_strings.SetString(
+ IntToWString(IDS_BOOKMARK_GROUP_FROM_FIREFOX),
+ l10n_util::GetString(IDS_BOOKMARK_GROUP_FROM_FIREFOX));
+ localized_strings.SetString(
+ IntToWString(IDS_BOOKMARK_GROUP_FROM_SAFARI),
+ l10n_util::GetString(IDS_BOOKMARK_GROUP_FROM_SAFARI));
+ localized_strings.SetString(
+ IntToWString(IDS_IMPORT_FROM_FIREFOX),
+ l10n_util::GetString(IDS_IMPORT_FROM_FIREFOX));
+ localized_strings.SetString(
+ IntToWString(IDS_IMPORT_FROM_GOOGLE_TOOLBAR),
+ l10n_util::GetString(IDS_IMPORT_FROM_GOOGLE_TOOLBAR));
+ localized_strings.SetString(
+ IntToWString(IDS_IMPORT_FROM_SAFARI),
+ l10n_util::GetString(IDS_IMPORT_FROM_SAFARI));
+
+ Send(new ProfileImportProcessMsg_StartImport(
+ profile_info, items, localized_strings, import_to_bookmark_bar));
+ return true;
+}
+
+bool ProfileImportProcessHost::CancelProfileImportProcess() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ Send(new ProfileImportProcessMsg_CancelImport());
+ return true;
+}
+
+bool ProfileImportProcessHost::ReportImportItemFinished(
+ importer::ImportItem item) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ Send(new ProfileImportProcessMsg_ReportImportItemFinished(item));
+ return true;
+}
+
+FilePath ProfileImportProcessHost::GetProfileImportProcessCmd() {
+ return GetChildPath(true);
+}
+
+bool ProfileImportProcessHost::StartProcess() {
+ set_name(L"profile import process");
+
+ if (!CreateChannel())
+ return false;
+
+ FilePath exe_path = GetProfileImportProcessCmd();
+ if (exe_path.empty()) {
+ NOTREACHED() << "Unable to get profile import process binary name.";
+ return false;
+ }
+
+ CommandLine* cmd_line = new CommandLine(exe_path);
+ cmd_line->AppendSwitchWithValue(switches::kProcessType,
+ switches::kProfileImportProcess);
+ cmd_line->AppendSwitchWithValue(switches::kProcessChannelID,
+ ASCIIToWide(channel_id()));
+
+ SetCrashReporterCommandLine(cmd_line);
+
+ const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
+ if (browser_command_line.HasSwitch(switches::kChromeFrame))
+ cmd_line->AppendSwitch(switches::kChromeFrame);
+
+#if defined(OS_MACOSX)
+ base::environment_vector env;
+ std::string dylib_path = GetFirefoxDylibPath().value();
+ if (!dylib_path.empty())
+ env.push_back(std::make_pair("DYLD_FALLBACK_LIBRARY_PATH", dylib_path));
+
+ Launch(false, env, cmd_line);
+#elif defined(OS_WIN)
+ FilePath no_exposed_directory;
+
+ Launch(no_exposed_directory, cmd_line);
+#else
+ base::environment_vector env;
+
+ Launch(false, env, cmd_line);
+#endif
+
+ return true;
+}
+
+void ProfileImportProcessHost::OnMessageReceived(const IPC::Message& message) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ ChromeThread::PostTask(
+ thread_id_, FROM_HERE,
+ NewRunnableMethod(import_process_client_.get(),
+ &ImportProcessClient::OnMessageReceived,
+ message));
+}
+
+void ProfileImportProcessHost::OnProcessCrashed() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ ChromeThread::PostTask(
+ thread_id_, FROM_HERE,
+ NewRunnableMethod(import_process_client_.get(),
+ &ImportProcessClient::OnProcessCrashed));
+}
+
+void ProfileImportProcessHost::ImportProcessClient::OnMessageReceived(
+ const IPC::Message& message) {
+ IPC_BEGIN_MESSAGE_MAP(ProfileImportProcessHost, message)
+ // Notification messages about the state of the import process.
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Started,
+ ImportProcessClient::OnImportStart)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Finished,
+ ImportProcessClient::OnImportFinished)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_ImportItem_Started,
+ ImportProcessClient::OnImportItemStart)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_ImportItem_Finished,
+ ImportProcessClient::OnImportItemFinished)
+
+ // Data messages containing items to be written to the user profile.
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHistoryImportStart,
+ ImportProcessClient::OnHistoryImportStart)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHistoryImportGroup,
+ ImportProcessClient::OnHistoryImportGroup)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyHomePageImportReady,
+ ImportProcessClient::OnHomePageImportReady)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyBookmarksImportStart,
+ ImportProcessClient::OnBookmarksImportStart)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyBookmarksImportGroup,
+ ImportProcessClient::OnBookmarksImportGroup)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFavIconsImportStart,
+ ImportProcessClient::OnFavIconsImportStart)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFavIconsImportGroup,
+ ImportProcessClient::OnFavIconsImportGroup)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyPasswordFormReady,
+ ImportProcessClient::OnPasswordFormImportReady)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyKeywordsReady,
+ ImportProcessClient::OnKeywordsImportReady)
+ IPC_END_MESSAGE_MAP_EX()
+}
diff --git a/chrome/browser/profile_import_process_host.h b/chrome/browser/profile_import_process_host.h
new file mode 100644
index 0000000..1cb3819
--- /dev/null
+++ b/chrome/browser/profile_import_process_host.h
@@ -0,0 +1,142 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PROFILE_IMPORT_PROCESS_HOST_H_
+#define CHROME_BROWSER_PROFILE_IMPORT_PROCESS_HOST_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "base/task.h"
+#include "base/values.h"
+#include "chrome/browser/child_process_host.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/history/history_types.h"
+#include "chrome/browser/importer/importer_data_types.h"
+#include "chrome/browser/importer/profile_writer.h"
+#include "ipc/ipc_channel.h"
+#include "webkit/glue/password_form.h"
+
+// Browser-side host to a profile import process. This class lives only on
+// the IO thread. It passes messages back to the |thread_id_| thread through
+// a client object.
+class ProfileImportProcessHost : public ChildProcessHost {
+ public:
+
+ // An interface that must be implemented by consumers of the profile import
+ // process in order to get results back from the process host. The
+ // ProfileImportProcessHost calls the client's functions on the thread passed
+ // to it when it's created.
+ class ImportProcessClient :
+ public base::RefCountedThreadSafe<ImportProcessClient> {
+ public:
+ ImportProcessClient() {}
+
+ // These methods are used by the ProfileImportProcessHost to pass messages
+ // received from the external process back to the ImportProcessClient in
+ // ImporterHost.
+ virtual void OnProcessCrashed() {}
+ virtual void OnImportStart() {}
+ virtual void OnImportFinished(bool succeeded, std::string error_msg) {}
+ virtual void OnImportItemStart(int item) {}
+ virtual void OnImportItemFinished(int item) {}
+ virtual void OnImportItemFailed(std::string error_msg) {}
+
+ // These methods pass back data to be written to the user's profile from
+ // the external process to the process host client.
+ virtual void OnHistoryImportStart(size_t total_history_rows_count) {}
+ virtual void OnHistoryImportGroup(
+ const std::vector<history::URLRow> &history_rows_group) {}
+
+ virtual void OnHomePageImportReady(
+ const GURL& home_page) {}
+
+ virtual void OnBookmarksImportStart(
+ const std::wstring first_folder_name,
+ int options, size_t total_bookmarks_count) {}
+ virtual void OnBookmarksImportGroup(
+ const std::vector<ProfileWriter::BookmarkEntry>& bookmarks) {}
+
+ virtual void OnFavIconsImportStart(size_t total_fav_icons_count) {}
+ virtual void OnFavIconsImportGroup(
+ const std::vector<history::ImportedFavIconUsage>& fav_icons_group) {}
+
+ virtual void OnPasswordFormImportReady(
+ const webkit_glue::PasswordForm& form) {}
+
+ virtual void OnKeywordsImportReady(
+ const std::vector<TemplateURL>& template_urls,
+ int default_keyword_index, bool unique_on_host_and_path) {}
+
+ virtual void OnMessageReceived(const IPC::Message& message);
+
+ protected:
+ friend class base::RefCountedThreadSafe<ImportProcessClient>;
+
+ virtual ~ImportProcessClient() {}
+
+ private:
+ friend class ProfileImportProcessHost;
+
+ DISALLOW_COPY_AND_ASSIGN(ImportProcessClient);
+ };
+
+ // |resource_dispatcher| is used in the base ChildProcessHost class to manage
+ // IPC requests.
+ // |import_process_client| implements callbacks which are triggered by
+ // incoming IPC messages. This client creates an interface between IPC
+ // messages received by the ProfileImportProcessHost and the internal
+ // importer_bridge.
+ // |thread_id| gives the thread where the client lives. The
+ // ProfileImportProcessHost spawns tasks on this thread for the client.
+ ProfileImportProcessHost(ResourceDispatcherHost* resource_dispatcher,
+ ImportProcessClient* import_process_client,
+ ChromeThread::ID thread_id);
+
+ // |profile_info|, |items|, and |import_to_bookmark_bar| are all needed by
+ // the external importer process.
+ bool StartProfileImportProcess(const importer::ProfileInfo& profile_info,
+ int items, bool import_to_bookmark_bar);
+
+ // Cancel the external import process.
+ bool CancelProfileImportProcess();
+
+ // Report that an item has been successfully imported. We need to make
+ // sure that all import messages have come across the wire before the
+ // external import process shuts itself down.
+ bool ReportImportItemFinished(importer::ImportItem item);
+
+ protected:
+ // Allow these methods to be overridden for tests.
+ virtual FilePath GetProfileImportProcessCmd();
+
+ private:
+ // Launch the new process.
+ bool StartProcess();
+
+ // Called by the external importer process to send messages back to the
+ // ImportProcessClient.
+ void OnMessageReceived(const IPC::Message& message);
+
+ // Overridden from ChildProcessHost:
+ virtual void OnProcessCrashed();
+ virtual bool CanShutdown() { return true; }
+ virtual URLRequestContext* GetRequestContext(
+ uint32 request_id,
+ const ViewHostMsg_Resource_Request& request_data) {
+ return NULL;
+ }
+
+ // Receives messages to be passed back to the importer host.
+ scoped_refptr<ImportProcessClient> import_process_client_;
+
+ // The thread where the import_process_client_ lives.
+ ChromeThread::ID thread_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProfileImportProcessHost);
+};
+
+#endif // CHROME_BROWSER_PROFILE_IMPORT_PROCESS_HOST_H_
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 8dd729c..0b81f6e 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -25,10 +25,10 @@
'browser',
'debugger',
'chrome_gpu',
+ 'profile_import',
'renderer',
'syncapi',
'utility',
- 'profile_import',
'worker',
'service',
'../printing/printing.gyp:printing',
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 05cb5ae..2f163e8 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -18,6 +18,7 @@
'domui_shared_resources',
'net_internals_resources',
'platform_locale_settings',
+ 'profile_import',
'browser/sync/protocol/sync_proto.gyp:sync_proto_cpp',
'syncapi',
'theme_resources',
@@ -1565,6 +1566,8 @@
'browser/importer/importer_data_types.h',
'browser/importer/importer_list.cc',
'browser/importer/importer_list.h',
+ 'browser/importer/importer_messages.h',
+ 'browser/importer/importer_messages_internal.h',
'browser/importer/mork_reader.cc',
'browser/importer/mork_reader.h',
'browser/importer/nss_decryptor.cc',
@@ -1853,6 +1856,8 @@
'browser/process_singleton_win.cc',
'browser/profile.cc',
'browser/profile.h',
+ 'browser/profile_import_process_host.cc',
+ 'browser/profile_import_process_host.h',
'browser/profile_manager.cc',
'browser/profile_manager.h',
'browser/renderer_host/async_resource_handler.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 7f142de..ab39a51 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -272,6 +272,7 @@
'common',
'chrome_resources',
'chrome_strings',
+ 'profile_import',
'test_support_ui',
'../base/base.gyp:base',
'../net/net.gyp:net',
@@ -496,6 +497,7 @@
'common',
'common_net_test_support',
'debugger',
+ 'profile_import',
'renderer',
'service',
'test_support_unit',
@@ -1260,6 +1262,7 @@
'chrome_resources',
'chrome_strings',
'debugger',
+ 'profile_import',
'renderer',
'test_support_common',
'../app/app.gyp:app_base',
@@ -1871,6 +1874,7 @@
'../testing/gmock.gyp:gmock',
'../testing/gtest.gyp:gtest',
'../third_party/libjingle/libjingle.gyp:libjingle',
+ 'profile_import',
'syncapi',
'test_support_unit',
],
@@ -1937,6 +1941,7 @@
'chrome_resources',
'common',
'debugger',
+ 'profile_import',
'renderer',
'chrome_strings',
'test_support_common',
diff --git a/chrome/profile_import/DEPS b/chrome/profile_import/DEPS
new file mode 100644
index 0000000..4c8adc9
--- /dev/null
+++ b/chrome/profile_import/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "+chrome/browser/history",
+ "+chrome/browser/importer",
+ "+chrome/browser/search_engines",
+ "+webkit/glue"
+]
diff --git a/chrome/profile_import/profile_import_thread.cc b/chrome/profile_import/profile_import_thread.cc
index 6a0211f7..4a7ca13 100644
--- a/chrome/profile_import/profile_import_thread.cc
+++ b/chrome/profile_import/profile_import_thread.cc
@@ -1,19 +1,184 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/profile_import/profile_import_thread.h"
+#include <algorithm>
+
+#include "base/values.h"
+#include "chrome/browser/importer/importer.h"
+#include "chrome/browser/importer/importer_bridge.h"
+#include "chrome/browser/importer/importer_data_types.h"
+#include "chrome/browser/importer/importer_list.h"
+#include "chrome/browser/importer/importer_messages.h"
+#include "chrome/browser/search_engines/template_url.h"
#include "chrome/common/child_process.h"
-ProfileImportThread::ProfileImportThread() {
- ChildProcess::current()->AddRefProcess();
+namespace {
+// Rather than sending all import items over IPC at once we chunk them into
+// separate requests. This avoids the case of a large import causing
+// oversized IPC messages.
+const int kNumBookmarksToSend = 100;
+const int kNumHistoryRowsToSend = 100;
+const int kNumFavIconsToSend = 100;
}
-ProfileImportThread::~ProfileImportThread() {
+ProfileImportThread::ProfileImportThread() {
+ ChildProcess::current()->AddRefProcess(); // Balanced in Cleanup().
}
void ProfileImportThread::OnControlMessageReceived(const IPC::Message& msg) {
- ChildProcess::current()->ReleaseProcess();
+ IPC_BEGIN_MESSAGE_MAP(ProfileImportThread, msg)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessMsg_StartImport,
+ OnImportStart)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessMsg_CancelImport,
+ OnImportCancel)
+ IPC_MESSAGE_HANDLER(ProfileImportProcessMsg_ReportImportItemFinished,
+ OnImportItemFinished)
+ IPC_END_MESSAGE_MAP()
+}
+
+void ProfileImportThread::OnImportStart(
+ const ProfileInfo& profile_info,
+ int items,
+ const DictionaryValue& localized_strings,
+ bool import_to_bookmark_bar) {
+ bridge_ = new ExternalProcessImporterBridge(this, localized_strings);
+ bridge_->AddRef(); // Balanced in Cleanup().
+
+ ImporterList importer_list;
+ importer_ = importer_list.CreateImporterByType(profile_info.browser_type);
+ importer_->AddRef(); // Balanced in Cleanup().
+ importer_->set_import_to_bookmark_bar(import_to_bookmark_bar);
+ items_to_import_ = items;
+
+ if (!importer_) {
+ Send(new ProfileImportProcessHostMsg_Import_Finished(false,
+ "Importer could not be created."));
+ return;
+ }
+
+ // Create worker thread in which importer runs.
+ import_thread_.reset(new base::Thread("import_thread"));
+ base::Thread::Options options;
+ options.message_loop_type = MessageLoop::TYPE_IO;
+ if (!import_thread_->StartWithOptions(options)) {
+ NOTREACHED();
+ Cleanup();
+ }
+ import_thread_->message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(importer_, &Importer::StartImport,
+ profile_info, items, bridge_));
+}
+
+void ProfileImportThread::OnImportCancel() {
+ Cleanup();
+}
+
+void ProfileImportThread::OnImportItemFinished(uint16 item) {
+ items_to_import_ ^= item; // Remove finished item from mask.
+ // If we've finished with all items, notify the browser process.
+ if (items_to_import_ == 0)
+ NotifyEnded();
+}
+
+void ProfileImportThread::NotifyItemStarted(ImportItem item) {
+ Send(new ProfileImportProcessHostMsg_ImportItem_Started(item));
+}
+
+void ProfileImportThread::NotifyItemEnded(ImportItem item) {
+ Send(new ProfileImportProcessHostMsg_ImportItem_Finished(item));
+}
+
+void ProfileImportThread::NotifyStarted() {
+ Send(new ProfileImportProcessHostMsg_Import_Started());
+}
+
+void ProfileImportThread::NotifyEnded() {
+ Send(new ProfileImportProcessHostMsg_Import_Finished(true, ""));
+ Cleanup();
+}
+
+void ProfileImportThread::NotifyHistoryImportReady(
+ const std::vector<history::URLRow> &rows) {
+ Send(new ProfileImportProcessHostMsg_NotifyHistoryImportStart(rows.size()));
+
+ std::vector<history::URLRow>::const_iterator it;
+ for (it = rows.begin(); it < rows.end();
+ it = it + kNumHistoryRowsToSend) {
+ std::vector<history::URLRow> row_group;
+ std::vector<history::URLRow>::const_iterator end_group =
+ it + kNumHistoryRowsToSend < rows.end() ?
+ it + kNumHistoryRowsToSend : rows.end();
+ row_group.assign(it, end_group);
+
+ Send(new ProfileImportProcessHostMsg_NotifyHistoryImportGroup(row_group));
+ }
+}
+
+void ProfileImportThread::NotifyHomePageImportReady(
+ const GURL& home_page) {
NOTIMPLEMENTED();
}
+
+void ProfileImportThread::NotifyBookmarksImportReady(
+ const std::vector<ProfileWriter::BookmarkEntry>& bookmarks,
+ const std::wstring& first_folder_name, int options) {
+ Send(new ProfileImportProcessHostMsg_NotifyBookmarksImportStart(
+ first_folder_name, options, bookmarks.size()));
+
+ std::vector<ProfileWriter::BookmarkEntry>::const_iterator it;
+ for (it = bookmarks.begin(); it < bookmarks.end();
+ it = it + kNumBookmarksToSend) {
+ std::vector<ProfileWriter::BookmarkEntry> bookmark_group;
+ std::vector<ProfileWriter::BookmarkEntry>::const_iterator end_group =
+ it + kNumBookmarksToSend < bookmarks.end() ?
+ it + kNumBookmarksToSend : bookmarks.end();
+ bookmark_group.assign(it, end_group);
+
+ Send(new ProfileImportProcessHostMsg_NotifyBookmarksImportGroup(
+ bookmark_group));
+ }
+}
+
+void ProfileImportThread::NotifyFavIconsImportReady(
+ const std::vector<history::ImportedFavIconUsage>& fav_icons) {
+ Send(new ProfileImportProcessHostMsg_NotifyFavIconsImportStart(
+ fav_icons.size()));
+
+ std::vector<history::ImportedFavIconUsage>::const_iterator it;
+ for (it = fav_icons.begin(); it < fav_icons.end();
+ it = it + kNumFavIconsToSend) {
+ std::vector<history::ImportedFavIconUsage> fav_icons_group;
+ std::vector<history::ImportedFavIconUsage>::const_iterator end_group =
+ std::min(it + kNumFavIconsToSend, fav_icons.end());
+ fav_icons_group.assign(it, end_group);
+
+ Send(new ProfileImportProcessHostMsg_NotifyFavIconsImportGroup(
+ fav_icons_group));
+ }
+}
+
+void ProfileImportThread::NotifyPasswordFormReady(
+ const webkit_glue::PasswordForm& form) {
+ Send(new ProfileImportProcessHostMsg_NotifyPasswordFormReady(form));
+}
+
+void ProfileImportThread::NotifyKeywordsReady(
+ const std::vector<TemplateURL*>& template_urls,
+ int default_keyword_index, bool unique_on_host_and_path) {
+ std::vector<TemplateURL> urls;
+ for (size_t i = 0; i < template_urls.size(); ++i) {
+ urls.push_back(*template_urls[i]);
+ }
+ Send(new ProfileImportProcessHostMsg_NotifyKeywordsReady(urls,
+ default_keyword_index, unique_on_host_and_path));
+}
+
+void ProfileImportThread::Cleanup() {
+ importer_->Cancel();
+ importer_->Release();
+ bridge_->Release();
+ ChildProcess::current()->ReleaseProcess();
+}
diff --git a/chrome/profile_import/profile_import_thread.h b/chrome/profile_import/profile_import_thread.h
index ea2c4b8..67d79d1 100644
--- a/chrome/profile_import/profile_import_thread.h
+++ b/chrome/profile_import/profile_import_thread.h
@@ -1,28 +1,99 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_PROFILE_IMPORT_PROFILE_IMPORT_THREAD_H_
#define CHROME_PROFILE_IMPORT_PROFILE_IMPORT_THREAD_H_
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "base/thread.h"
+#include "chrome/browser/history/history_types.h"
+#include "chrome/browser/importer/importer_data_types.h"
+#include "chrome/browser/importer/profile_writer.h"
#include "chrome/common/child_thread.h"
+#include "webkit/glue/password_form.h"
+
+class DictionaryValue;
+class ExternalProcessImporterBridge;
+class Importer;
+class InProcessImporterBridge;
-// This class represents the background thread where the profile import task
-// runs.
+// This class represents the background thread which communicates with the
+// importer work thread in the importer process.
class ProfileImportThread : public ChildThread {
public:
ProfileImportThread();
- virtual ~ProfileImportThread();
+ virtual ~ProfileImportThread() {}
// Returns the one profile import thread.
static ProfileImportThread* current() {
return static_cast<ProfileImportThread*>(ChildThread::current());
}
+ // Bridging methods, called from importer_bridge tasks posted here.
+ void NotifyItemStarted(importer::ImportItem item);
+ void NotifyItemEnded(importer::ImportItem item);
+ void NotifyStarted();
+ void NotifyEnded();
+
+ // Bridging methods that move data back across the process boundary.
+ void NotifyHistoryImportReady(const std::vector<history::URLRow> &rows);
+ void NotifyHomePageImportReady(const GURL& home_page);
+ void NotifyBookmarksImportReady(
+ const std::vector<ProfileWriter::BookmarkEntry>& bookmarks,
+ const std::wstring& first_folder_name, int options);
+ void NotifyFavIconsImportReady(
+ const std::vector<history::ImportedFavIconUsage>& fav_icons);
+ void NotifyPasswordFormReady(const webkit_glue::PasswordForm& form);
+ void NotifyKeywordsReady(const std::vector<TemplateURL*>& template_urls,
+ int default_keyword_index, bool unique_on_host_and_path);
+
private:
// IPC messages
virtual void OnControlMessageReceived(const IPC::Message& msg);
+ // Creates the importer and launches it in a new thread. Import is run on
+ // a separate thread so that this thread can receive messages from the
+ // main process (especially cancel requests) while the worker thread handles
+ // the actual import.
+ void OnImportStart(
+ const importer::ProfileInfo& profile_info,
+ int items,
+ const DictionaryValue& localized_strings,
+ bool import_to_bookmark_bar);
+
+ // Calls cleanup to stop the import operation.
+ void OnImportCancel();
+
+ // Called from the main process to notify that an item has been received
+ // from the import process.
+ void OnImportItemFinished(uint16 item);
+
+ // Release the process and ourselves.
+ void Cleanup();
+
+ // Thread that importer runs on, while ProfileImportThread handles messages
+ // from the browser process.
+ scoped_ptr<base::Thread> import_thread_;
+
+ // Bridge object is passed to importer, so that it can send IPC calls
+ // directly back to the ProfileImportProcessHost.
+ ExternalProcessImporterBridge* bridge_;
+
+ // importer::ProfileType enum from importer_list, stored in ProfileInfo
+ // struct in importer.
+ int browser_type_;
+
+ // A mask of importer::ImportItems.
+ uint16 items_to_import_;
+
+ // Importer of the appropriate type (Firefox, Safari, IE, etc.)
+ Importer* importer_;
+
DISALLOW_COPY_AND_ASSIGN(ProfileImportThread);
};