• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/importer/importer_host.h"
6 
7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/bookmarks/bookmark_model.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/importer/firefox_profile_lock.h"
11 #include "chrome/browser/importer/importer.h"
12 #include "chrome/browser/importer/importer_lock_dialog.h"
13 #include "chrome/browser/importer/importer_progress_observer.h"
14 #include "chrome/browser/importer/importer_type.h"
15 #include "chrome/browser/importer/in_process_importer_bridge.h"
16 #include "chrome/browser/importer/toolbar_importer_utils.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/search_engines/template_url.h"
19 #include "chrome/browser/search_engines/template_url_model.h"
20 #include "chrome/browser/ui/browser_list.h"
21 #include "content/browser/browser_thread.h"
22 #include "content/common/notification_source.h"
23 #include "grit/generated_resources.h"
24 #include "ui/base/l10n/l10n_util.h"
25 
26 #if defined(OS_WIN)
27 // TODO(port): Port this file.
28 #include "ui/base/message_box_win.h"
29 #endif
30 
ImporterHost()31 ImporterHost::ImporterHost()
32     : profile_(NULL),
33       task_(NULL),
34       importer_(NULL),
35       waiting_for_bookmarkbar_model_(false),
36       installed_bookmark_observer_(false),
37       is_source_readable_(true),
38       headless_(false),
39       parent_window_(NULL),
40       observer_(NULL) {
41 }
42 
ShowWarningDialog()43 void ImporterHost::ShowWarningDialog() {
44   if (headless_)
45     OnImportLockDialogEnd(false);
46   else
47     importer::ShowImportLockDialog(parent_window_, this);
48 }
49 
OnImportLockDialogEnd(bool is_continue)50 void ImporterHost::OnImportLockDialogEnd(bool is_continue) {
51   if (is_continue) {
52     // User chose to continue, then we check the lock again to make
53     // sure that Firefox has been closed. Try to import the settings
54     // if successful. Otherwise, show a warning dialog.
55     firefox_lock_->Lock();
56     if (firefox_lock_->HasAcquired()) {
57       is_source_readable_ = true;
58       InvokeTaskIfDone();
59     } else {
60       ShowWarningDialog();
61     }
62   } else {
63     // User chose to skip the import process. We should delete
64     // the task and notify the ImporterHost to finish.
65     delete task_;
66     task_ = NULL;
67     importer_ = NULL;
68     NotifyImportEnded();
69   }
70 }
71 
SetObserver(importer::ImporterProgressObserver * observer)72 void ImporterHost::SetObserver(importer::ImporterProgressObserver* observer) {
73   observer_ = observer;
74 }
75 
NotifyImportStarted()76 void ImporterHost::NotifyImportStarted() {
77   if (observer_)
78     observer_->ImportStarted();
79 }
80 
NotifyImportItemStarted(importer::ImportItem item)81 void ImporterHost::NotifyImportItemStarted(importer::ImportItem item) {
82   if (observer_)
83     observer_->ImportItemStarted(item);
84 }
85 
NotifyImportItemEnded(importer::ImportItem item)86 void ImporterHost::NotifyImportItemEnded(importer::ImportItem item) {
87   if (observer_)
88     observer_->ImportItemEnded(item);
89 }
90 
NotifyImportEnded()91 void ImporterHost::NotifyImportEnded() {
92   firefox_lock_.reset();  // Release the Firefox profile lock.
93   if (observer_)
94     observer_->ImportEnded();
95   Release();
96 }
97 
StartImportSettings(const importer::SourceProfile & source_profile,Profile * target_profile,uint16 items,ProfileWriter * writer,bool first_run)98 void ImporterHost::StartImportSettings(
99     const importer::SourceProfile& source_profile,
100     Profile* target_profile,
101     uint16 items,
102     ProfileWriter* writer,
103     bool first_run) {
104   // We really only support importing from one host at a time.
105   DCHECK(!profile_);
106 
107   profile_ = target_profile;
108   // Preserves the observer and creates a task, since we do async import so that
109   // it doesn't block the UI. When the import is complete, observer will be
110   // notified.
111   writer_ = writer;
112   importer_ = importer::CreateImporterByType(source_profile.importer_type);
113   // If we fail to create the Importer, exit, as we cannot do anything.
114   if (!importer_) {
115     NotifyImportEnded();
116     return;
117   }
118 
119   importer_->AddRef();
120   importer_->set_import_to_bookmark_bar(ShouldImportToBookmarkBar(first_run));
121   importer_->set_bookmark_bar_disabled(first_run);
122 
123   scoped_refptr<InProcessImporterBridge> bridge(
124       new InProcessImporterBridge(writer_.get(), this));
125   task_ = NewRunnableMethod(
126       importer_, &Importer::StartImport, source_profile, items, bridge);
127 
128   CheckForFirefoxLock(source_profile, items, first_run);
129 
130 #if defined(OS_WIN)
131   // For google toolbar import, we need the user to log in and store their GAIA
132   // credentials.
133   if (source_profile.importer_type == importer::GOOGLE_TOOLBAR5) {
134     if (!toolbar_importer_utils::IsGoogleGAIACookieInstalled()) {
135       ui::MessageBox(
136           NULL,
137           UTF16ToWide(l10n_util::GetStringUTF16(
138               IDS_IMPORTER_GOOGLE_LOGIN_TEXT)).c_str(),
139           L"",
140           MB_OK | MB_TOPMOST);
141 
142       GURL url("https://www.google.com/accounts/ServiceLogin");
143       BrowserList::GetLastActive()->AddSelectedTabWithURL(
144           url, PageTransition::TYPED);
145 
146       MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
147           this, &ImporterHost::OnImportLockDialogEnd, false));
148 
149       is_source_readable_ = false;
150     }
151   }
152 #endif
153 
154   CheckForLoadedModels(items);
155   AddRef();
156   InvokeTaskIfDone();
157 }
158 
Cancel()159 void ImporterHost::Cancel() {
160   if (importer_)
161     importer_->Cancel();
162 }
163 
~ImporterHost()164 ImporterHost::~ImporterHost() {
165   if (NULL != importer_)
166     importer_->Release();
167 
168   if (installed_bookmark_observer_) {
169     DCHECK(profile_);  // Only way for waiting_for_bookmarkbar_model_ to be true
170                        // is if we have a profile.
171     profile_->GetBookmarkModel()->RemoveObserver(this);
172   }
173 }
174 
ShouldImportToBookmarkBar(bool first_run)175 bool ImporterHost::ShouldImportToBookmarkBar(bool first_run) {
176   bool import_to_bookmark_bar = first_run;
177   if (profile_ && profile_->GetBookmarkModel()->IsLoaded()) {
178     import_to_bookmark_bar = (!profile_->GetBookmarkModel()->HasBookmarks());
179   }
180   return import_to_bookmark_bar;
181 }
182 
CheckForFirefoxLock(const importer::SourceProfile & source_profile,uint16 items,bool first_run)183 void ImporterHost::CheckForFirefoxLock(
184     const importer::SourceProfile& source_profile,
185     uint16 items,
186     bool first_run) {
187   if (source_profile.importer_type == importer::FIREFOX2 ||
188       source_profile.importer_type == importer::FIREFOX3) {
189     DCHECK(!firefox_lock_.get());
190     firefox_lock_.reset(new FirefoxProfileLock(source_profile.source_path));
191     if (!firefox_lock_->HasAcquired()) {
192       // If fail to acquire the lock, we set the source unreadable and
193       // show a warning dialog, unless running without UI.
194       is_source_readable_ = false;
195       ShowWarningDialog();
196     }
197   }
198 }
199 
CheckForLoadedModels(uint16 items)200 void ImporterHost::CheckForLoadedModels(uint16 items) {
201   // BookmarkModel should be loaded before adding IE favorites. So we observe
202   // the BookmarkModel if needed, and start the task after it has been loaded.
203   if ((items & importer::FAVORITES) && !writer_->BookmarkModelIsLoaded()) {
204     profile_->GetBookmarkModel()->AddObserver(this);
205     waiting_for_bookmarkbar_model_ = true;
206     installed_bookmark_observer_ = true;
207   }
208 
209   // Observes the TemplateURLModel if needed to import search engines from the
210   // other browser. We also check to see if we're importing bookmarks because
211   // we can import bookmark keywords from Firefox as search engines.
212   if ((items & importer::SEARCH_ENGINES) || (items & importer::FAVORITES)) {
213     if (!writer_->TemplateURLModelIsLoaded()) {
214       TemplateURLModel* model = profile_->GetTemplateURLModel();
215       registrar_.Add(this, NotificationType::TEMPLATE_URL_MODEL_LOADED,
216                      Source<TemplateURLModel>(model));
217       model->Load();
218     }
219   }
220 }
221 
InvokeTaskIfDone()222 void ImporterHost::InvokeTaskIfDone() {
223   if (waiting_for_bookmarkbar_model_ || !registrar_.IsEmpty() ||
224       !is_source_readable_)
225     return;
226   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, task_);
227 }
228 
Loaded(BookmarkModel * model)229 void ImporterHost::Loaded(BookmarkModel* model) {
230   DCHECK(model->IsLoaded());
231   model->RemoveObserver(this);
232   waiting_for_bookmarkbar_model_ = false;
233   installed_bookmark_observer_ = false;
234 
235   importer_->set_import_to_bookmark_bar(!model->HasBookmarks());
236   InvokeTaskIfDone();
237 }
238 
BookmarkModelBeingDeleted(BookmarkModel * model)239 void ImporterHost::BookmarkModelBeingDeleted(BookmarkModel* model) {
240   installed_bookmark_observer_ = false;
241 }
242 
BookmarkModelChanged()243 void ImporterHost::BookmarkModelChanged() {
244 }
245 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)246 void ImporterHost::Observe(NotificationType type,
247                            const NotificationSource& source,
248                            const NotificationDetails& details) {
249   DCHECK(type == NotificationType::TEMPLATE_URL_MODEL_LOADED);
250   registrar_.RemoveAll();
251   InvokeTaskIfDone();
252 }
253