| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2008 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 #ifndef CHROME_BROWSER_IMPORTER_H_ | |
| 6 #define CHROME_BROWSER_IMPORTER_H_ | |
| 7 | |
| 8 #include <set> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/message_loop.h" | |
| 13 #include "base/ref_counted.h" | |
| 14 #include "chrome/browser/bookmarks/bookmark_model.h" | |
| 15 #include "chrome/browser/history/history_types.h" | |
| 16 #include "chrome/browser/ie7_password.h" | |
| 17 #include "chrome/browser/profile.h" | |
| 18 #include "chrome/browser/template_url.h" | |
| 19 #include "chrome/browser/views/importer_lock_view.h" | |
| 20 #include "chrome/common/notification_service.h" | |
| 21 #include "googleurl/src/gurl.h" | |
| 22 #include "webkit/glue/password_form.h" | |
| 23 | |
| 24 // An enumeration of the type of browsers that we support to import | |
| 25 // settings and data from them. | |
| 26 enum ProfileType { | |
| 27 MS_IE = 0, | |
| 28 FIREFOX2, | |
| 29 FIREFOX3 | |
| 30 }; | |
| 31 | |
| 32 // An enumeration of the type of data we want to import. | |
| 33 enum ImportItem { | |
| 34 NONE = 0x0000, | |
| 35 HISTORY = 0x0001, | |
| 36 FAVORITES = 0x0002, | |
| 37 COOKIES = 0x0004, // not supported yet. | |
| 38 PASSWORDS = 0x0008, | |
| 39 SEARCH_ENGINES = 0x0010, | |
| 40 HOME_PAGE = 0x0020, | |
| 41 }; | |
| 42 | |
| 43 typedef struct { | |
| 44 std::wstring description; | |
| 45 ProfileType browser_type; | |
| 46 std::wstring source_path; | |
| 47 std::wstring app_path; | |
| 48 } ProfileInfo; | |
| 49 | |
| 50 class FirefoxProfileLock; | |
| 51 class Importer; | |
| 52 | |
| 53 // ProfileWriter encapsulates profile for writing entries into it. | |
| 54 // This object must be invoked on UI thread. | |
| 55 class ProfileWriter : public base::RefCounted<ProfileWriter> { | |
| 56 public: | |
| 57 explicit ProfileWriter(Profile* profile) : profile_(profile) { } | |
| 58 virtual ~ProfileWriter() { } | |
| 59 | |
| 60 // Methods for monitoring BookmarkModel status. | |
| 61 virtual bool BookmarkModelIsLoaded() const; | |
| 62 virtual void AddBookmarkModelObserver( | |
| 63 BookmarkModelObserver* observer); | |
| 64 | |
| 65 // Methods for monitoring TemplateURLModel status. | |
| 66 virtual bool TemplateURLModelIsLoaded() const; | |
| 67 virtual void AddTemplateURLModelObserver( | |
| 68 NotificationObserver* observer); | |
| 69 | |
| 70 // A bookmark entry. | |
| 71 struct BookmarkEntry { | |
| 72 bool in_toolbar; | |
| 73 GURL url; | |
| 74 std::vector<std::wstring> path; | |
| 75 std::wstring title; | |
| 76 Time creation_time; | |
| 77 | |
| 78 BookmarkEntry() : in_toolbar(false) {} | |
| 79 }; | |
| 80 | |
| 81 // Helper methods for adding data to local stores. | |
| 82 virtual void AddPasswordForm(const PasswordForm& form); | |
| 83 virtual void AddIE7PasswordInfo(const IE7PasswordInfo& info); | |
| 84 virtual void AddHistoryPage(const std::vector<history::URLRow>& page); | |
| 85 virtual void AddHomepage(const GURL& homepage); | |
| 86 virtual void AddBookmarkEntry(const std::vector<BookmarkEntry>& bookmark); | |
| 87 virtual void AddFavicons( | |
| 88 const std::vector<history::ImportedFavIconUsage>& favicons); | |
| 89 // Add the TemplateURLs in |template_urls| to the local store and make the | |
| 90 // TemplateURL at |default_keyword_index| the default keyword (does not set | |
| 91 // a default keyword if it is -1). The local store becomes the owner of the | |
| 92 // TemplateURLs. Some TemplateURLs in |template_urls| may conflict (same | |
| 93 // keyword or same host name in the URL) with existing TemplateURLs in the | |
| 94 // local store, in which case the existing ones takes precedence and the | |
| 95 // duplicate in |template_urls| are deleted. | |
| 96 // If unique_on_host_and_path a TemplateURL is only added if there is not an | |
| 97 // existing TemplateURL that has a replaceable search url with the same | |
| 98 // host+path combination. | |
| 99 virtual void AddKeywords(const std::vector<TemplateURL*>& template_urls, | |
| 100 int default_keyword_index, | |
| 101 bool unique_on_host_and_path); | |
| 102 | |
| 103 // Shows the bookmarks toolbar. | |
| 104 void ShowBookmarkBar(); | |
| 105 | |
| 106 private: | |
| 107 Profile* profile_; | |
| 108 | |
| 109 DISALLOW_EVIL_CONSTRUCTORS(ProfileWriter); | |
| 110 }; | |
| 111 | |
| 112 // This class hosts the importers. It enumerates profiles from other | |
| 113 // browsers dynamically, and controls the process of importing. When | |
| 114 // the import process is done, ImporterHost deletes itself. | |
| 115 class ImporterHost : public base::RefCounted<ImporterHost>, | |
| 116 public BookmarkModelObserver, | |
| 117 public NotificationObserver { | |
| 118 public: | |
| 119 ImporterHost(); | |
| 120 ~ImporterHost(); | |
| 121 | |
| 122 // This constructor only be used by unit-tests, where file thread does not | |
| 123 // exist. | |
| 124 explicit ImporterHost(MessageLoop* file_loop); | |
| 125 | |
| 126 // BookmarkModelObserver methods. | |
| 127 virtual void Loaded(BookmarkModel* model); | |
| 128 virtual void BookmarkNodeMoved(BookmarkModel* model, | |
| 129 BookmarkNode* old_parent, | |
| 130 int old_index, | |
| 131 BookmarkNode* new_parent, | |
| 132 int new_index) {} | |
| 133 virtual void BookmarkNodeAdded(BookmarkModel* model, | |
| 134 BookmarkNode* parent, | |
| 135 int index) {} | |
| 136 virtual void BookmarkNodeRemoved(BookmarkModel* model, | |
| 137 BookmarkNode* parent, | |
| 138 int index) {} | |
| 139 virtual void BookmarkNodeChanged(BookmarkModel* model, | |
| 140 BookmarkNode* node) {} | |
| 141 virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, | |
| 142 BookmarkNode* node) {} | |
| 143 | |
| 144 // NotificationObserver method. Called when TemplateURLModel has been loaded. | |
| 145 void Observe(NotificationType type, | |
| 146 const NotificationSource& source, | |
| 147 const NotificationDetails& details); | |
| 148 | |
| 149 // ShowWarningDialog() asks user to close the application that is owning the | |
| 150 // lock. They can retry or skip the importing process. | |
| 151 void ShowWarningDialog(); | |
| 152 | |
| 153 // OnLockViewEnd() is called when user end the dialog by clicking a push | |
| 154 // button. |is_continue| is true when user clicked the "Continue" button. | |
| 155 void OnLockViewEnd(bool is_continue); | |
| 156 | |
| 157 // Starts the process of importing the settings and data depending | |
| 158 // on what the user selected. | |
| 159 void StartImportSettings(const ProfileInfo& profile_info, | |
| 160 uint16 items, | |
| 161 ProfileWriter* writer, | |
| 162 bool first_run); | |
| 163 | |
| 164 // Cancel | |
| 165 void Cancel(); | |
| 166 | |
| 167 // An interface which an object can implement to be notified of events during | |
| 168 // the import process. | |
| 169 class Observer { | |
| 170 public: | |
| 171 virtual ~Observer() {} | |
| 172 // Invoked when data for the specified item is about to be collected. | |
| 173 virtual void ImportItemStarted(ImportItem item) = 0; | |
| 174 | |
| 175 // Invoked when data for the specified item has been collected from the | |
| 176 // source profile and is now ready for further processing. | |
| 177 virtual void ImportItemEnded(ImportItem item) = 0; | |
| 178 | |
| 179 // Invoked when the import begins. | |
| 180 virtual void ImportStarted() = 0; | |
| 181 | |
| 182 // Invoked when the source profile has been imported. | |
| 183 virtual void ImportEnded() = 0; | |
| 184 }; | |
| 185 void SetObserver(Observer* observer); | |
| 186 | |
| 187 // A series of functions invoked at the start, during and end of the end | |
| 188 // of the import process. The middle functions are notifications that the | |
| 189 // harvesting of a particular source of data (specified by |item|) is under | |
| 190 // way. | |
| 191 void ImportStarted(); | |
| 192 void ImportItemStarted(ImportItem item); | |
| 193 void ImportItemEnded(ImportItem item); | |
| 194 void ImportEnded(); | |
| 195 | |
| 196 Importer* CreateImporterByType(ProfileType type); | |
| 197 | |
| 198 // Returns the number of different browser profiles you can import from. | |
| 199 int GetAvailableProfileCount(); | |
| 200 | |
| 201 // Returns the name of the profile at the 'index' slot. The profiles are | |
| 202 // ordered such that the profile at index 0 is the likely default browser. | |
| 203 std::wstring GetSourceProfileNameAt(int index) const; | |
| 204 | |
| 205 // Returns the ProfileInfo at the specified index. The ProfileInfo should be | |
| 206 // passed to StartImportSettings(). | |
| 207 const ProfileInfo& GetSourceProfileInfoAt(int index) const; | |
| 208 | |
| 209 private: | |
| 210 // If we're not waiting on any model to finish loading, invokes the task_. | |
| 211 void InvokeTaskIfDone(); | |
| 212 | |
| 213 // Detects the installed browsers and their associated profiles, then | |
| 214 // stores their information in a list. It returns the list of description | |
| 215 // of all profiles. | |
| 216 void DetectSourceProfiles(); | |
| 217 | |
| 218 // Helper methods for detecting available profiles. | |
| 219 void DetectIEProfiles(); | |
| 220 void DetectFirefoxProfiles(); | |
| 221 | |
| 222 // The list of profiles with the default one first. | |
| 223 std::vector<ProfileInfo*> source_profiles_; | |
| 224 | |
| 225 Observer* observer_; | |
| 226 scoped_refptr<ProfileWriter> writer_; | |
| 227 | |
| 228 // The task is the process of importing settings from other browsers. | |
| 229 Task* task_; | |
| 230 | |
| 231 // The importer used in the task; | |
| 232 Importer* importer_; | |
| 233 | |
| 234 // The message loop for reading the source profiles. | |
| 235 MessageLoop* file_loop_; | |
| 236 | |
| 237 // True if we're waiting for the model to finish loading. | |
| 238 bool waiting_for_bookmarkbar_model_; | |
| 239 bool waiting_for_template_url_model_; | |
| 240 | |
| 241 // True if source profile is readable. | |
| 242 bool is_source_readable_; | |
| 243 | |
| 244 // Firefox profile lock. | |
| 245 scoped_ptr<FirefoxProfileLock> firefox_lock_; | |
| 246 | |
| 247 DISALLOW_EVIL_CONSTRUCTORS(ImporterHost); | |
| 248 }; | |
| 249 | |
| 250 // The base class of all importers. | |
| 251 class Importer : public base::RefCounted<Importer> { | |
| 252 public: | |
| 253 virtual ~Importer() { } | |
| 254 | |
| 255 // All importers should implement this method by adding their | |
| 256 // import logic. And it will be run in file thread by ImporterHost. | |
| 257 // | |
| 258 // Since we do async import, the importer should invoke | |
| 259 // ImporterHost::Finished() to notify its host that import | |
| 260 // stuff have been finished. | |
| 261 virtual void StartImport(ProfileInfo profile_info, | |
| 262 uint16 items, | |
| 263 ProfileWriter* writer, | |
| 264 ImporterHost* host) = 0; | |
| 265 | |
| 266 // Cancels the import process. | |
| 267 void Cancel() { cancelled_ = true; } | |
| 268 | |
| 269 void set_first_run(bool first_run) { first_run_ = first_run; } | |
| 270 | |
| 271 protected: | |
| 272 Importer() | |
| 273 : main_loop_(MessageLoop::current()), | |
| 274 importer_host_(NULL), | |
| 275 cancelled_(false) {} | |
| 276 | |
| 277 // Notifies the coordinator that the collection of data for the specified | |
| 278 // item has begun. | |
| 279 void NotifyItemStarted(ImportItem item) { | |
| 280 main_loop_->PostTask(FROM_HERE, NewRunnableMethod(importer_host_, | |
| 281 &ImporterHost::ImportItemStarted, item)); | |
| 282 } | |
| 283 | |
| 284 // Notifies the coordinator that the collection of data for the specified | |
| 285 // item has completed. | |
| 286 void NotifyItemEnded(ImportItem item) { | |
| 287 main_loop_->PostTask(FROM_HERE, NewRunnableMethod(importer_host_, | |
| 288 &ImporterHost::ImportItemEnded, item)); | |
| 289 } | |
| 290 | |
| 291 // Notifies the coordinator that the import operation has begun. | |
| 292 void NotifyStarted() { | |
| 293 main_loop_->PostTask(FROM_HERE, NewRunnableMethod(importer_host_, | |
| 294 &ImporterHost::ImportStarted)); | |
| 295 } | |
| 296 | |
| 297 // Notifies the coordinator that the entire import operation has completed. | |
| 298 void NotifyEnded() { | |
| 299 main_loop_->PostTask(FROM_HERE, | |
| 300 NewRunnableMethod(importer_host_, &ImporterHost::ImportEnded)); | |
| 301 } | |
| 302 | |
| 303 // Given raw image data, decodes the icon, re-sampling to the correct size as | |
| 304 // necessary, and re-encodes as PNG data in the given output vector. Returns | |
| 305 // true on success. | |
| 306 static bool ReencodeFavicon(const unsigned char* src_data, size_t src_len, | |
| 307 std::vector<unsigned char>* png_data); | |
| 308 | |
| 309 bool cancelled() const { return cancelled_; } | |
| 310 | |
| 311 bool first_run() const { return first_run_; } | |
| 312 | |
| 313 // The importer should know the main thread so that ProfileWriter | |
| 314 // will be invoked in thread instead. | |
| 315 MessageLoop* main_loop_; | |
| 316 | |
| 317 // The coordinator host for this importer. | |
| 318 ImporterHost* importer_host_; | |
| 319 | |
| 320 private: | |
| 321 // True if the caller cancels the import process. | |
| 322 bool cancelled_; | |
| 323 | |
| 324 // True if the importer is created in the first run UI. | |
| 325 bool first_run_; | |
| 326 | |
| 327 DISALLOW_EVIL_CONSTRUCTORS(Importer); | |
| 328 }; | |
| 329 | |
| 330 // An interface an object that calls StartImportingWithUI can call to be | |
| 331 // notified about the state of the import operation. | |
| 332 class ImportObserver { | |
| 333 public: | |
| 334 virtual ~ImportObserver() {} | |
| 335 // The import operation was canceled by the user. | |
| 336 virtual void ImportCanceled() = 0; | |
| 337 | |
| 338 // The import operation was completed successfully. | |
| 339 virtual void ImportComplete() = 0; | |
| 340 }; | |
| 341 | |
| 342 | |
| 343 // Shows a UI for importing and begins importing the specified items from | |
| 344 // source_profile to target_profile. observer is notified when the process is | |
| 345 // complete, can be NULL. parent is the window to parent the UI to, can be NULL | |
| 346 // if there's nothing to parent to. first_run is true if it's invoked in the | |
| 347 // first run UI. | |
| 348 void StartImportingWithUI(HWND parent_window, | |
| 349 int16 items, | |
| 350 ImporterHost* coordinator, | |
| 351 const ProfileInfo& source_profile, | |
| 352 Profile* target_profile, | |
| 353 ImportObserver* observer, | |
| 354 bool first_run); | |
| 355 | |
| 356 #endif // CHROME_BROWSER_IMPORTER_H__ | |
| 357 | |
| OLD | NEW |