Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / importer / external_process_importer_host.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/importer/external_process_importer_host.h"
6
7 #include "base/bind.h"
8 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/importer/external_process_importer_client.h"
11 #include "chrome/browser/importer/firefox_profile_lock.h"
12 #include "chrome/browser/importer/importer_lock_dialog.h"
13 #include "chrome/browser/importer/importer_progress_observer.h"
14 #include "chrome/browser/importer/in_process_importer_bridge.h"
15 #include "chrome/browser/search_engines/template_url_service.h"
16 #include "chrome/browser/search_engines/template_url_service_factory.h"
17 #include "components/bookmarks/core/browser/bookmark_model.h"
18 #include "content/public/browser/browser_thread.h"
19
20 using content::BrowserThread;
21
22 ExternalProcessImporterHost::ExternalProcessImporterHost()
23     : headless_(false),
24       parent_window_(NULL),
25       observer_(NULL),
26       profile_(NULL),
27       waiting_for_bookmarkbar_model_(false),
28       installed_bookmark_observer_(false),
29       is_source_readable_(true),
30       client_(NULL),
31       items_(0),
32       cancelled_(false),
33       weak_ptr_factory_(this) {
34 }
35
36 void ExternalProcessImporterHost::Cancel() {
37   cancelled_ = true;
38   // There is only a |client_| if the import was started.
39   if (client_)
40     client_->Cancel();
41   NotifyImportEnded();  // Tells the observer that we're done, and deletes us.
42 }
43
44 void ExternalProcessImporterHost::StartImportSettings(
45     const importer::SourceProfile& source_profile,
46     Profile* target_profile,
47     uint16 items,
48     ProfileWriter* writer) {
49   // We really only support importing from one host at a time.
50   DCHECK(!profile_);
51   DCHECK(target_profile);
52
53   profile_ = target_profile;
54   writer_ = writer;
55   source_profile_ = source_profile;
56   items_ = items;
57
58   if (!CheckForFirefoxLock(source_profile)) {
59     Cancel();
60     return;
61   }
62
63   CheckForLoadedModels(items);
64
65   LaunchImportIfReady();
66 }
67
68 void ExternalProcessImporterHost::NotifyImportStarted() {
69   if (observer_)
70     observer_->ImportStarted();
71 }
72
73 void ExternalProcessImporterHost::NotifyImportItemStarted(
74     importer::ImportItem item) {
75   if (observer_)
76     observer_->ImportItemStarted(item);
77 }
78
79 void ExternalProcessImporterHost::NotifyImportItemEnded(
80     importer::ImportItem item) {
81   if (observer_)
82     observer_->ImportItemEnded(item);
83 }
84
85 void ExternalProcessImporterHost::NotifyImportEnded() {
86   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
87   firefox_lock_.reset();
88   if (observer_)
89     observer_->ImportEnded();
90   delete this;
91 }
92
93 ExternalProcessImporterHost::~ExternalProcessImporterHost() {
94   if (installed_bookmark_observer_) {
95     DCHECK(profile_);
96     BookmarkModelFactory::GetForProfile(profile_)->RemoveObserver(this);
97   }
98 }
99
100 void ExternalProcessImporterHost::LaunchImportIfReady() {
101   if (waiting_for_bookmarkbar_model_ || template_service_subscription_.get() ||
102       !is_source_readable_ || cancelled_)
103     return;
104
105   // This is the in-process half of the bridge, which catches data from the IPC
106   // pipe and feeds it to the ProfileWriter. The external process half of the
107   // bridge lives in the external process (see ProfileImportThread).
108   // The ExternalProcessImporterClient created in the next line owns the bridge,
109   // and will delete it.
110   InProcessImporterBridge* bridge =
111       new InProcessImporterBridge(writer_.get(),
112                                   weak_ptr_factory_.GetWeakPtr());
113   client_ = new ExternalProcessImporterClient(
114       weak_ptr_factory_.GetWeakPtr(), source_profile_, items_, bridge);
115   client_->Start();
116 }
117
118 void ExternalProcessImporterHost::BookmarkModelLoaded(BookmarkModel* model,
119                                                       bool ids_reassigned) {
120   DCHECK(model->loaded());
121   model->RemoveObserver(this);
122   waiting_for_bookmarkbar_model_ = false;
123   installed_bookmark_observer_ = false;
124
125   LaunchImportIfReady();
126 }
127
128 void ExternalProcessImporterHost::BookmarkModelBeingDeleted(
129     BookmarkModel* model) {
130   installed_bookmark_observer_ = false;
131 }
132
133 void ExternalProcessImporterHost::BookmarkModelChanged() {
134 }
135
136 void ExternalProcessImporterHost::OnTemplateURLServiceLoaded() {
137   template_service_subscription_.reset();
138   LaunchImportIfReady();
139 }
140
141 void ExternalProcessImporterHost::ShowWarningDialog() {
142   DCHECK(!headless_);
143   importer::ShowImportLockDialog(
144       parent_window_,
145       base::Bind(&ExternalProcessImporterHost::OnImportLockDialogEnd,
146                  weak_ptr_factory_.GetWeakPtr()));
147 }
148
149 void ExternalProcessImporterHost::OnImportLockDialogEnd(bool is_continue) {
150   if (is_continue) {
151     // User chose to continue, then we check the lock again to make
152     // sure that Firefox has been closed. Try to import the settings
153     // if successful. Otherwise, show a warning dialog.
154     firefox_lock_->Lock();
155     if (firefox_lock_->HasAcquired()) {
156       is_source_readable_ = true;
157       LaunchImportIfReady();
158     } else {
159       ShowWarningDialog();
160     }
161   } else {
162     NotifyImportEnded();
163   }
164 }
165
166 bool ExternalProcessImporterHost::CheckForFirefoxLock(
167     const importer::SourceProfile& source_profile) {
168   if (source_profile.importer_type != importer::TYPE_FIREFOX)
169     return true;
170
171   DCHECK(!firefox_lock_.get());
172   firefox_lock_.reset(new FirefoxProfileLock(source_profile.source_path));
173   if (firefox_lock_->HasAcquired())
174     return true;
175
176   // If fail to acquire the lock, we set the source unreadable and
177   // show a warning dialog, unless running without UI (in which case the import
178   // must be aborted).
179   is_source_readable_ = false;
180   if (headless_)
181     return false;
182
183   ShowWarningDialog();
184   return true;
185 }
186
187 void ExternalProcessImporterHost::CheckForLoadedModels(uint16 items) {
188   // A target profile must be loaded by StartImportSettings().
189   DCHECK(profile_);
190
191   // BookmarkModel should be loaded before adding IE favorites. So we observe
192   // the BookmarkModel if needed, and start the task after it has been loaded.
193   if ((items & importer::FAVORITES) && !writer_->BookmarkModelIsLoaded()) {
194     BookmarkModelFactory::GetForProfile(profile_)->AddObserver(this);
195     waiting_for_bookmarkbar_model_ = true;
196     installed_bookmark_observer_ = true;
197   }
198
199   // Observes the TemplateURLService if needed to import search engines from the
200   // other browser. We also check to see if we're importing bookmarks because
201   // we can import bookmark keywords from Firefox as search engines.
202   if ((items & importer::SEARCH_ENGINES) || (items & importer::FAVORITES)) {
203     if (!writer_->TemplateURLServiceIsLoaded()) {
204       TemplateURLService* model =
205           TemplateURLServiceFactory::GetForProfile(profile_);
206       template_service_subscription_ = model->RegisterOnLoadedCallback(
207           base::Bind(&ExternalProcessImporterHost::OnTemplateURLServiceLoaded,
208                      weak_ptr_factory_.GetWeakPtr()));
209       model->Load();
210     }
211   }
212 }