| // Copyright (c) 2011 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/importer/importer_host.h" |
| |
| #include "base/utf_string_conversions.h" |
| #include "chrome/browser/bookmarks/bookmark_model.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/importer/firefox_profile_lock.h" |
| #include "chrome/browser/importer/importer.h" |
| #include "chrome/browser/importer/importer_lock_dialog.h" |
| #include "chrome/browser/importer/importer_progress_observer.h" |
| #include "chrome/browser/importer/importer_type.h" |
| #include "chrome/browser/importer/in_process_importer_bridge.h" |
| #include "chrome/browser/importer/toolbar_importer_utils.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/search_engines/template_url.h" |
| #include "chrome/browser/search_engines/template_url_model.h" |
| #include "chrome/browser/ui/browser_list.h" |
| #include "content/browser/browser_thread.h" |
| #include "content/common/notification_source.h" |
| #include "grit/generated_resources.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| #if defined(OS_WIN) |
| // TODO(port): Port this file. |
| #include "ui/base/message_box_win.h" |
| #endif |
| |
| ImporterHost::ImporterHost() |
| : profile_(NULL), |
| task_(NULL), |
| importer_(NULL), |
| waiting_for_bookmarkbar_model_(false), |
| installed_bookmark_observer_(false), |
| is_source_readable_(true), |
| headless_(false), |
| parent_window_(NULL), |
| observer_(NULL) { |
| } |
| |
| void ImporterHost::ShowWarningDialog() { |
| if (headless_) |
| OnImportLockDialogEnd(false); |
| else |
| importer::ShowImportLockDialog(parent_window_, this); |
| } |
| |
| void ImporterHost::OnImportLockDialogEnd(bool is_continue) { |
| if (is_continue) { |
| // User chose to continue, then we check the lock again to make |
| // sure that Firefox has been closed. Try to import the settings |
| // if successful. Otherwise, show a warning dialog. |
| firefox_lock_->Lock(); |
| if (firefox_lock_->HasAcquired()) { |
| is_source_readable_ = true; |
| InvokeTaskIfDone(); |
| } else { |
| ShowWarningDialog(); |
| } |
| } else { |
| // User chose to skip the import process. We should delete |
| // the task and notify the ImporterHost to finish. |
| delete task_; |
| task_ = NULL; |
| importer_ = NULL; |
| NotifyImportEnded(); |
| } |
| } |
| |
| void ImporterHost::SetObserver(importer::ImporterProgressObserver* observer) { |
| observer_ = observer; |
| } |
| |
| void ImporterHost::NotifyImportStarted() { |
| if (observer_) |
| observer_->ImportStarted(); |
| } |
| |
| void ImporterHost::NotifyImportItemStarted(importer::ImportItem item) { |
| if (observer_) |
| observer_->ImportItemStarted(item); |
| } |
| |
| void ImporterHost::NotifyImportItemEnded(importer::ImportItem item) { |
| if (observer_) |
| observer_->ImportItemEnded(item); |
| } |
| |
| void ImporterHost::NotifyImportEnded() { |
| firefox_lock_.reset(); // Release the Firefox profile lock. |
| if (observer_) |
| observer_->ImportEnded(); |
| Release(); |
| } |
| |
| void ImporterHost::StartImportSettings( |
| const importer::SourceProfile& source_profile, |
| Profile* target_profile, |
| uint16 items, |
| ProfileWriter* writer, |
| bool first_run) { |
| // We really only support importing from one host at a time. |
| DCHECK(!profile_); |
| |
| profile_ = target_profile; |
| // Preserves the observer and creates a task, since we do async import so that |
| // it doesn't block the UI. When the import is complete, observer will be |
| // notified. |
| writer_ = writer; |
| importer_ = importer::CreateImporterByType(source_profile.importer_type); |
| // If we fail to create the Importer, exit, as we cannot do anything. |
| if (!importer_) { |
| NotifyImportEnded(); |
| return; |
| } |
| |
| importer_->AddRef(); |
| importer_->set_import_to_bookmark_bar(ShouldImportToBookmarkBar(first_run)); |
| importer_->set_bookmark_bar_disabled(first_run); |
| |
| scoped_refptr<InProcessImporterBridge> bridge( |
| new InProcessImporterBridge(writer_.get(), this)); |
| task_ = NewRunnableMethod( |
| importer_, &Importer::StartImport, source_profile, items, bridge); |
| |
| CheckForFirefoxLock(source_profile, items, first_run); |
| |
| #if defined(OS_WIN) |
| // For google toolbar import, we need the user to log in and store their GAIA |
| // credentials. |
| if (source_profile.importer_type == importer::GOOGLE_TOOLBAR5) { |
| if (!toolbar_importer_utils::IsGoogleGAIACookieInstalled()) { |
| ui::MessageBox( |
| NULL, |
| UTF16ToWide(l10n_util::GetStringUTF16( |
| IDS_IMPORTER_GOOGLE_LOGIN_TEXT)).c_str(), |
| L"", |
| MB_OK | MB_TOPMOST); |
| |
| GURL url("https://www.google.com/accounts/ServiceLogin"); |
| BrowserList::GetLastActive()->AddSelectedTabWithURL( |
| url, PageTransition::TYPED); |
| |
| MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
| this, &ImporterHost::OnImportLockDialogEnd, false)); |
| |
| is_source_readable_ = false; |
| } |
| } |
| #endif |
| |
| CheckForLoadedModels(items); |
| AddRef(); |
| InvokeTaskIfDone(); |
| } |
| |
| void ImporterHost::Cancel() { |
| if (importer_) |
| importer_->Cancel(); |
| } |
| |
| ImporterHost::~ImporterHost() { |
| if (NULL != importer_) |
| importer_->Release(); |
| |
| if (installed_bookmark_observer_) { |
| DCHECK(profile_); // Only way for waiting_for_bookmarkbar_model_ to be true |
| // is if we have a profile. |
| profile_->GetBookmarkModel()->RemoveObserver(this); |
| } |
| } |
| |
| bool ImporterHost::ShouldImportToBookmarkBar(bool first_run) { |
| bool import_to_bookmark_bar = first_run; |
| if (profile_ && profile_->GetBookmarkModel()->IsLoaded()) { |
| import_to_bookmark_bar = (!profile_->GetBookmarkModel()->HasBookmarks()); |
| } |
| return import_to_bookmark_bar; |
| } |
| |
| void ImporterHost::CheckForFirefoxLock( |
| const importer::SourceProfile& source_profile, |
| uint16 items, |
| bool first_run) { |
| if (source_profile.importer_type == importer::FIREFOX2 || |
| source_profile.importer_type == importer::FIREFOX3) { |
| DCHECK(!firefox_lock_.get()); |
| firefox_lock_.reset(new FirefoxProfileLock(source_profile.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; |
| 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(); |
| } |
| } |
| } |
| |
| void ImporterHost::InvokeTaskIfDone() { |
| if (waiting_for_bookmarkbar_model_ || !registrar_.IsEmpty() || |
| !is_source_readable_) |
| return; |
| BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, task_); |
| } |
| |
| void ImporterHost::Loaded(BookmarkModel* model) { |
| DCHECK(model->IsLoaded()); |
| model->RemoveObserver(this); |
| waiting_for_bookmarkbar_model_ = false; |
| installed_bookmark_observer_ = false; |
| |
| importer_->set_import_to_bookmark_bar(!model->HasBookmarks()); |
| InvokeTaskIfDone(); |
| } |
| |
| void ImporterHost::BookmarkModelBeingDeleted(BookmarkModel* model) { |
| installed_bookmark_observer_ = false; |
| } |
| |
| void ImporterHost::BookmarkModelChanged() { |
| } |
| |
| void ImporterHost::Observe(NotificationType type, |
| const NotificationSource& source, |
| const NotificationDetails& details) { |
| DCHECK(type == NotificationType::TEMPLATE_URL_MODEL_LOADED); |
| registrar_.RemoveAll(); |
| InvokeTaskIfDone(); |
| } |