| 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 // The DownloadManager object manages the process of downloading, including |  | 
| 6 // updates to the history system and providing the information for displaying |  | 
| 7 // the downloads view in the Destinations tab. There is one DownloadManager per |  | 
| 8 // active profile in Chrome. |  | 
| 9 // |  | 
| 10 // Each download is represented by a DownloadItem, and all DownloadItems |  | 
| 11 // are owned by the DownloadManager which maintains a global list of all |  | 
| 12 // downloads. DownloadItems are created when a user initiates a download, |  | 
| 13 // and exist for the duration of the browser life time. |  | 
| 14 // |  | 
| 15 // Download observers: |  | 
| 16 // Objects that are interested in notifications about new downloads, or progress |  | 
| 17 // updates for a given download must implement one of the download observer |  | 
| 18 // interfaces: |  | 
| 19 //   DownloadItem::Observer: |  | 
| 20 //     - allows observers to receive notifications about one download from start |  | 
| 21 //       to completion |  | 
| 22 //   DownloadManager::Observer: |  | 
| 23 //     - allows observers, primarily views, to be notified when changes to the |  | 
| 24 //       set of all downloads (such as new downloads, or deletes) occur |  | 
| 25 // Use AddObserver() / RemoveObserver() on the appropriate download object to |  | 
| 26 // receive state updates. |  | 
| 27 // |  | 
| 28 // Download state persistence: |  | 
| 29 // The DownloadManager uses the history service for storing persistent |  | 
| 30 // information about the state of all downloads. The history system maintains a |  | 
| 31 // separate table for this called 'downloads'. At the point that the |  | 
| 32 // DownloadManager is constructed, we query the history service for the state of |  | 
| 33 // all persisted downloads. |  | 
| 34 |  | 
| 35 #ifndef CHROME_BROWSER_DOWNLOAD_MANAGER_H__ |  | 
| 36 #define CHROME_BROWSER_DOWNLOAD_MANAGER_H__ |  | 
| 37 |  | 
| 38 #include <string> |  | 
| 39 #include <map> |  | 
| 40 #include <set> |  | 
| 41 #include <vector> |  | 
| 42 |  | 
| 43 #include "base/basictypes.h" |  | 
| 44 #include "base/hash_tables.h" |  | 
| 45 #include "base/observer_list.h" |  | 
| 46 #include "base/ref_counted.h" |  | 
| 47 #include "chrome/browser/cancelable_request.h" |  | 
| 48 #include "chrome/browser/history/download_types.h" |  | 
| 49 #include "chrome/browser/history/history.h" |  | 
| 50 #include "chrome/browser/shell_dialogs.h" |  | 
| 51 #include "chrome/common/pref_member.h" |  | 
| 52 |  | 
| 53 class DownloadFileManager; |  | 
| 54 class DownloadItem; |  | 
| 55 class DownloadItemView; |  | 
| 56 class DownloadManager; |  | 
| 57 class GURL; |  | 
| 58 class MessageLoop; |  | 
| 59 class PrefService; |  | 
| 60 class Profile; |  | 
| 61 class ResourceDispatcherHost; |  | 
| 62 class URLRequestContext; |  | 
| 63 class WebContents; |  | 
| 64 |  | 
| 65 namespace base { |  | 
| 66 class Thread; |  | 
| 67 } |  | 
| 68 |  | 
| 69 // DownloadItem ---------------------------------------------------------------- |  | 
| 70 |  | 
| 71 // One DownloadItem per download. This is the model class that stores all the |  | 
| 72 // state for a download. Multiple views, such as a tab's download shelf and the |  | 
| 73 // Destination tab's download view, may refer to a given DownloadItem. |  | 
| 74 class DownloadItem { |  | 
| 75  public: |  | 
| 76   enum DownloadState { |  | 
| 77     IN_PROGRESS, |  | 
| 78     COMPLETE, |  | 
| 79     CANCELLED, |  | 
| 80     REMOVING |  | 
| 81   }; |  | 
| 82 |  | 
| 83   // Interface that observers of a particular download must implement in order |  | 
| 84   // to receive updates to the download's status. |  | 
| 85   class Observer { |  | 
| 86    public: |  | 
| 87     virtual void OnDownloadUpdated(DownloadItem* download) = 0; |  | 
| 88   }; |  | 
| 89 |  | 
| 90   // Constructing from persistent store: |  | 
| 91   DownloadItem(const DownloadCreateInfo& info); |  | 
| 92 |  | 
| 93   // Constructing from user action: |  | 
| 94   DownloadItem(int32 download_id, |  | 
| 95                const std::wstring& path, |  | 
| 96                const std::wstring& url, |  | 
| 97                const Time start_time, |  | 
| 98                int64 download_size, |  | 
| 99                int render_process_id, |  | 
| 100                int request_id); |  | 
| 101 |  | 
| 102   ~DownloadItem(); |  | 
| 103 |  | 
| 104   void Init(bool start_timer); |  | 
| 105 |  | 
| 106   // Public API |  | 
| 107 |  | 
| 108   void AddObserver(Observer* observer); |  | 
| 109   void RemoveObserver(Observer* observer); |  | 
| 110 |  | 
| 111   // Notify our observers periodically |  | 
| 112   void UpdateObservers(); |  | 
| 113 |  | 
| 114   // Received a new chunk of data |  | 
| 115   void Update(int64 bytes_so_far); |  | 
| 116 |  | 
| 117   // Cancel the download operation. We need to distinguish between cancels at |  | 
| 118   // exit (DownloadManager destructor) from user interface initiated cancels |  | 
| 119   // because at exit, the history system may not exist, and any updates to it |  | 
| 120   // require AddRef'ing the DownloadManager in the destructor which results in |  | 
| 121   // a DCHECK failure. Set 'update_history' to false when canceling from at |  | 
| 122   // exit to prevent this crash. This may result in a difference between the |  | 
| 123   // downloaded file's size on disk, and what the history system's last record |  | 
| 124   // of it is. At worst, we'll end up re-downloading a small portion of the file |  | 
| 125   // when resuming a download (assuming the server supports byte ranges). |  | 
| 126   void Cancel(bool update_history); |  | 
| 127 |  | 
| 128   // Download operation completed |  | 
| 129   void Finished(int64 size); |  | 
| 130 |  | 
| 131   // The user wants to remove the download from the views and history. This |  | 
| 132   // operation does not delete the file on the disk. |  | 
| 133   void Remove(); |  | 
| 134 |  | 
| 135   // Start/stop sending periodic updates to our observers |  | 
| 136   void StartProgressTimer(); |  | 
| 137   void StopProgressTimer(); |  | 
| 138 |  | 
| 139   // Simple calculation of the amount of time remaining to completion. Fills |  | 
| 140   // |*remaining| with the amount of time remaining if successful. Fails and |  | 
| 141   // returns false if we do not have the number of bytes or the speed so can |  | 
| 142   // not estimate. |  | 
| 143   bool TimeRemaining(TimeDelta* remaining) const; |  | 
| 144 |  | 
| 145   // Simple speed estimate in bytes/s |  | 
| 146   int64 CurrentSpeed() const; |  | 
| 147 |  | 
| 148   // Rough percent complete, -1 means we don't know (since we didn't receive a |  | 
| 149   // total size). |  | 
| 150   int PercentComplete() const; |  | 
| 151 |  | 
| 152   // Update the download's path, the actual file is renamed on the download |  | 
| 153   // thread. |  | 
| 154   void Rename(const std::wstring& full_path); |  | 
| 155 |  | 
| 156   // Allow the user to temporarily pause a download or resume a paused download. |  | 
| 157   void TogglePause(); |  | 
| 158 |  | 
| 159   // Accessors |  | 
| 160   DownloadState state() const { return state_; } |  | 
| 161   std::wstring full_path() const { return full_path_; } |  | 
| 162   std::wstring file_name() const { return file_name_; } |  | 
| 163   std::wstring url() const { return url_; } |  | 
| 164   int64 total_bytes() const { return total_bytes_; } |  | 
| 165   void set_total_bytes(int64 total_bytes) { total_bytes_ = total_bytes; } |  | 
| 166   int64 received_bytes() const { return received_bytes_; } |  | 
| 167   int32 id() const { return id_; } |  | 
| 168   Time start_time() const { return start_time_; } |  | 
| 169   void set_db_handle(int64 handle) { db_handle_ = handle; } |  | 
| 170   int64 db_handle() const { return db_handle_; } |  | 
| 171   DownloadManager* manager() const { return manager_; } |  | 
| 172   void set_manager(DownloadManager* manager) { manager_ = manager; } |  | 
| 173   bool is_paused() const { return is_paused_; } |  | 
| 174   void set_is_paused(bool pause) { is_paused_ = pause; } |  | 
| 175   bool open_when_complete() const { return open_when_complete_; } |  | 
| 176   void set_open_when_complete(bool open) { open_when_complete_ = open; } |  | 
| 177   int render_process_id() const { return render_process_id_; } |  | 
| 178   int request_id() const { return request_id_; } |  | 
| 179 |  | 
| 180  private: |  | 
| 181   // Internal helper for maintaining consistent received and total sizes. |  | 
| 182   void UpdateSize(int64 size); |  | 
| 183 |  | 
| 184   // Request ID assigned by the ResourceDispatcherHost. |  | 
| 185   int32 id_; |  | 
| 186 |  | 
| 187   // Full path to the downloaded file |  | 
| 188   std::wstring full_path_; |  | 
| 189 |  | 
| 190   // Short display version of the file |  | 
| 191   std::wstring file_name_; |  | 
| 192 |  | 
| 193   // The URL from whence we came, for display |  | 
| 194   std::wstring url_; |  | 
| 195 |  | 
| 196   // Total bytes expected |  | 
| 197   int64 total_bytes_; |  | 
| 198 |  | 
| 199   // Current received bytes |  | 
| 200   int64 received_bytes_; |  | 
| 201 |  | 
| 202   // Start time for calculating remaining time |  | 
| 203   uintptr_t start_tick_; |  | 
| 204 |  | 
| 205   // The current state of this download |  | 
| 206   DownloadState state_; |  | 
| 207 |  | 
| 208   // The views of this item in the download shelf and download tab |  | 
| 209   ObserverList<Observer> observers_; |  | 
| 210 |  | 
| 211   // Time the download was started |  | 
| 212   Time start_time_; |  | 
| 213 |  | 
| 214   // Our persistent store handle |  | 
| 215   int64 db_handle_; |  | 
| 216 |  | 
| 217   // Timer for regularly updating our observers |  | 
| 218   base::RepeatingTimer<DownloadItem> update_timer_; |  | 
| 219 |  | 
| 220   // Our owning object |  | 
| 221   DownloadManager* manager_; |  | 
| 222 |  | 
| 223   // In progress downloads may be paused by the user, we note it here |  | 
| 224   bool is_paused_; |  | 
| 225 |  | 
| 226   // A flag for indicating if the download should be opened at completion. |  | 
| 227   bool open_when_complete_; |  | 
| 228 |  | 
| 229   // For canceling or pausing requests. |  | 
| 230   int render_process_id_; |  | 
| 231   int request_id_; |  | 
| 232 |  | 
| 233   DISALLOW_EVIL_CONSTRUCTORS(DownloadItem); |  | 
| 234 }; |  | 
| 235 |  | 
| 236 |  | 
| 237 // DownloadManager ------------------------------------------------------------- |  | 
| 238 |  | 
| 239 // Browser's download manager: manages all downloads and destination view. |  | 
| 240 class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, |  | 
| 241                         public SelectFileDialog::Listener { |  | 
| 242   // For testing. |  | 
| 243   friend class DownloadManagerTest; |  | 
| 244 |  | 
| 245  public: |  | 
| 246   DownloadManager(); |  | 
| 247   ~DownloadManager(); |  | 
| 248 |  | 
| 249   static void RegisterUserPrefs(PrefService* prefs); |  | 
| 250 |  | 
| 251   // Interface to implement for observers that wish to be informed of changes |  | 
| 252   // to the DownloadManager's collection of downloads. |  | 
| 253   class Observer { |  | 
| 254    public: |  | 
| 255     // New or deleted download, observers should query us for the current set |  | 
| 256     // of downloads. |  | 
| 257     virtual void ModelChanged() = 0; |  | 
| 258 |  | 
| 259     // A callback once the DownloadManager has retrieved the requested set of |  | 
| 260     // downloads. The DownloadManagerObserver must copy the vector, but does not |  | 
| 261     // own the individual DownloadItems, when this call is made. |  | 
| 262     virtual void SetDownloads(std::vector<DownloadItem*>& downloads) = 0; |  | 
| 263   }; |  | 
| 264 |  | 
| 265   // Public API |  | 
| 266 |  | 
| 267   // Begin a search for all downloads matching 'search_text'. If 'search_text' |  | 
| 268   // is empty, return all known downloads. The results are returned in the |  | 
| 269   // 'SetDownloads' observer callback. |  | 
| 270   void GetDownloads(Observer* observer, |  | 
| 271                     const std::wstring& search_text); |  | 
| 272 |  | 
| 273   // Returns true if initialized properly. |  | 
| 274   bool Init(Profile* profile); |  | 
| 275 |  | 
| 276   // Schedule a query of the history service to retrieve all downloads. |  | 
| 277   void QueryHistoryForDownloads(); |  | 
| 278 |  | 
| 279   // Notifications sent from the download thread to the UI thread |  | 
| 280   void StartDownload(DownloadCreateInfo* info); |  | 
| 281   void UpdateDownload(int32 download_id, int64 size); |  | 
| 282   void DownloadFinished(int32 download_id, int64 size); |  | 
| 283 |  | 
| 284   // Helper method for cancelling the network request associated with a |  | 
| 285   // download. |  | 
| 286   static void CancelDownloadRequest(int render_process_id, int request_id); |  | 
| 287 |  | 
| 288   // Called from a view when a user clicks a UI button or link. |  | 
| 289   void DownloadCancelled(int32 download_id); |  | 
| 290   void PauseDownload(int32 download_id, bool pause); |  | 
| 291   void RemoveDownload(int64 download_handle); |  | 
| 292 |  | 
| 293   // Remove downloads after remove_begin (inclusive) and before remove_end |  | 
| 294   // (exclusive). You may pass in null Time values to do an unbounded delete |  | 
| 295   // in either direction. |  | 
| 296   int RemoveDownloadsBetween(const Time remove_begin, const Time remove_end); |  | 
| 297 |  | 
| 298   // Remove downloads will delete all downloads that have a timestamp that is |  | 
| 299   // the same or more recent than |remove_begin|. The number of downloads |  | 
| 300   // deleted is returned back to the caller. |  | 
| 301   int RemoveDownloads(const Time remove_begin); |  | 
| 302 |  | 
| 303   // Download the object at the URL. Used in cases such as "Save Link As..." |  | 
| 304   void DownloadUrl(const GURL& url, |  | 
| 305                    const GURL& referrer, |  | 
| 306                    WebContents* web_contents); |  | 
| 307 |  | 
| 308   // Allow objects to observe the download creation process. |  | 
| 309   void AddObserver(Observer* observer); |  | 
| 310 |  | 
| 311   // Remove a download observer from ourself. |  | 
| 312   void RemoveObserver(Observer* observer); |  | 
| 313 |  | 
| 314   // Methods called on completion of a query sent to the history system. |  | 
| 315   void OnQueryDownloadEntriesComplete( |  | 
| 316       std::vector<DownloadCreateInfo>* entries); |  | 
| 317   void OnCreateDownloadEntryComplete(DownloadCreateInfo info, int64 db_handle); |  | 
| 318   void OnSearchComplete(HistoryService::Handle handle, |  | 
| 319                         std::vector<int64>* results); |  | 
| 320 |  | 
| 321   // Show or Open a download via the Windows shell. |  | 
| 322   void ShowDownloadInShell(const DownloadItem* download); |  | 
| 323   void OpenDownloadInShell(const DownloadItem* download, HWND parent_window); |  | 
| 324 |  | 
| 325   // The number of in progress (including paused) downloads. |  | 
| 326   int in_progress_count() const { |  | 
| 327     return static_cast<int>(in_progress_.size()); |  | 
| 328   } |  | 
| 329 |  | 
| 330   std::wstring download_path() { return *download_path_; } |  | 
| 331 |  | 
| 332   // Registers this file extension for automatic opening upon download |  | 
| 333   // completion if 'open' is true, or prevents the extension from automatic |  | 
| 334   // opening if 'open' is false. |  | 
| 335   void OpenFilesOfExtension(const std::wstring& extension, bool open); |  | 
| 336 |  | 
| 337   // Tests if a file type should be opened automatically. |  | 
| 338   bool ShouldOpenFileExtension(const std::wstring& extension); |  | 
| 339 |  | 
| 340   // Tests if we think the server means for this mime_type to be executable. |  | 
| 341   static bool IsExecutableMimeType(const std::string& mime_type); |  | 
| 342 |  | 
| 343   // Tests if a file type is considered executable. |  | 
| 344   bool IsExecutable(const std::wstring& extension); |  | 
| 345 |  | 
| 346   // Resets the automatic open preference. |  | 
| 347   void ResetAutoOpenFiles(); |  | 
| 348 |  | 
| 349   // Returns true if there are automatic handlers registered for any file |  | 
| 350   // types. |  | 
| 351   bool HasAutoOpenFileTypesRegistered() const; |  | 
| 352 |  | 
| 353   // Overridden from SelectFileDialog::Listener: |  | 
| 354   virtual void FileSelected(const std::wstring& path, void* params); |  | 
| 355   virtual void FileSelectionCanceled(void* params); |  | 
| 356 |  | 
| 357  private: |  | 
| 358   // Shutdown the download manager.  This call is needed only after Init. |  | 
| 359   void Shutdown(); |  | 
| 360 |  | 
| 361   // Called on the download thread to check whether the suggested file path |  | 
| 362   // exists.  We don't check if the file exists on the UI thread to avoid UI |  | 
| 363   // stalls from interacting with the file system. |  | 
| 364   void CheckIfSuggestedPathExists(DownloadCreateInfo* info); |  | 
| 365 |  | 
| 366   // Called on the UI thread once the DownloadManager has determined whether the |  | 
| 367   // suggested file path exists. |  | 
| 368   void OnPathExistenceAvailable(DownloadCreateInfo* info); |  | 
| 369 |  | 
| 370   // Called back after a target path for the file to be downloaded to has been |  | 
| 371   // determined, either automatically based on the suggested file name, or by |  | 
| 372   // the user in a Save As dialog box. |  | 
| 373   void ContinueStartDownload(DownloadCreateInfo* info, |  | 
| 374                              const std::wstring& target_path); |  | 
| 375 |  | 
| 376   // Update the history service for a particular download. |  | 
| 377   void UpdateHistoryForDownload(DownloadItem* download); |  | 
| 378   void RemoveDownloadFromHistory(DownloadItem* download); |  | 
| 379   void RemoveDownloadsFromHistoryBetween(const Time remove_begin, |  | 
| 380                                          const Time remove_before); |  | 
| 381 |  | 
| 382   // Inform the notification service of download starts and stops. |  | 
| 383   void NotifyAboutDownloadStart(); |  | 
| 384   void NotifyAboutDownloadStop(); |  | 
| 385 |  | 
| 386   // Create an extension based on the file name and mime type. |  | 
| 387   void GenerateExtension(const std::wstring& file_name, |  | 
| 388                          const std::string& mime_type, |  | 
| 389                          std::wstring* generated_extension); |  | 
| 390 |  | 
| 391   // Create a file name based on the response from the server. |  | 
| 392   void GenerateFilename(DownloadCreateInfo* info, std::wstring* generated_name); |  | 
| 393 |  | 
| 394   // Persist the automatic opening preference. |  | 
| 395   void SaveAutoOpens(); |  | 
| 396 |  | 
| 397   // Runs the network cancel on the IO thread. |  | 
| 398   static void OnCancelDownloadRequest(ResourceDispatcherHost* rdh, |  | 
| 399                                       int render_process_id, |  | 
| 400                                       int request_id); |  | 
| 401 |  | 
| 402   // Runs the pause on the IO thread. |  | 
| 403   static void OnPauseDownloadRequest(ResourceDispatcherHost* rdh, |  | 
| 404                                      int render_process_id, |  | 
| 405                                      int request_id, |  | 
| 406                                      bool pause); |  | 
| 407 |  | 
| 408   // 'downloads_' is map of all downloads in this profile. The key is the handle |  | 
| 409   // returned by the history system, which is unique across sessions. This map |  | 
| 410   // owns all the DownloadItems once they have been created in the history |  | 
| 411   // system. |  | 
| 412   // |  | 
| 413   // 'in_progress_' is a map of all downloads that are in progress and that have |  | 
| 414   // not yet received a valid history handle. The key is the ID assigned by the |  | 
| 415   // ResourceDispatcherHost, which is unique for the current session. This map |  | 
| 416   // does not own the DownloadItems. |  | 
| 417   // |  | 
| 418   // When a download is created through a user action, the corresponding |  | 
| 419   // DownloadItem* is placed in 'in_progress_' and remains there until it has |  | 
| 420   // received a valid handle from the history system. Once it has a valid |  | 
| 421   // handle, the DownloadItem* is placed in the 'downloads_' map. When the |  | 
| 422   // download is complete, it is removed from 'in_progress_'. Downloads from |  | 
| 423   // past sessions read from a persisted state from the history system are |  | 
| 424   // placed directly into 'downloads_' since they have valid handles in the |  | 
| 425   // history system. |  | 
| 426   typedef base::hash_map<int64, DownloadItem*> DownloadMap; |  | 
| 427   DownloadMap downloads_; |  | 
| 428   DownloadMap in_progress_; |  | 
| 429 |  | 
| 430   // True if the download manager has been initialized and requires a shutdown. |  | 
| 431   bool shutdown_needed_; |  | 
| 432 |  | 
| 433   // Observers that want to be notified of changes to the set of downloads. |  | 
| 434   ObserverList<Observer> observers_; |  | 
| 435 |  | 
| 436   // The current active profile. |  | 
| 437   Profile* profile_; |  | 
| 438   scoped_refptr<URLRequestContext> request_context_; |  | 
| 439 |  | 
| 440   // Used for history service request management. |  | 
| 441   CancelableRequestConsumerT<Observer*, 0> cancelable_consumer_; |  | 
| 442 |  | 
| 443   // Non-owning pointer for handling file writing on the download_thread_. |  | 
| 444   DownloadFileManager* file_manager_; |  | 
| 445 |  | 
| 446   // A pointer to the main UI loop. |  | 
| 447   MessageLoop* ui_loop_; |  | 
| 448 |  | 
| 449   // A pointer to the file thread's loop. The file thread lives longer than |  | 
| 450   // the DownloadManager, so this is safe to cache. |  | 
| 451   MessageLoop* file_loop_; |  | 
| 452 |  | 
| 453   // User preferences |  | 
| 454   BooleanPrefMember prompt_for_download_; |  | 
| 455   StringPrefMember download_path_; |  | 
| 456 |  | 
| 457   // The user's last choice for download directory. This is only used when the |  | 
| 458   // user wants us to prompt for a save location for each download. |  | 
| 459   std::wstring last_download_path_; |  | 
| 460 |  | 
| 461   // Set of file extensions to open at download completion. |  | 
| 462   std::set<std::wstring> auto_open_; |  | 
| 463 |  | 
| 464   // Set of file extensions that are executables and shouldn't be auto opened. |  | 
| 465   std::set<std::wstring> exe_types_; |  | 
| 466 |  | 
| 467   // Keep track of downloads that are completed before the user selects the |  | 
| 468   // destination, so that observers are appropriately notified of completion |  | 
| 469   // after this determination is made. |  | 
| 470   // The map is of download_id->remaining size (bytes), both of which are |  | 
| 471   // required when calling DownloadFinished. |  | 
| 472   typedef std::map<int32, int64> PendingFinishedMap; |  | 
| 473   PendingFinishedMap pending_finished_downloads_; |  | 
| 474 |  | 
| 475   // The "Save As" dialog box used to ask the user where a file should be |  | 
| 476   // saved. |  | 
| 477   scoped_refptr<SelectFileDialog> select_file_dialog_; |  | 
| 478 |  | 
| 479   DISALLOW_EVIL_CONSTRUCTORS(DownloadManager); |  | 
| 480 }; |  | 
| 481 |  | 
| 482 |  | 
| 483 #endif  // CHROME_BROWSER_DOWNLOAD_MANAGER_H__ |  | 
| OLD | NEW | 
|---|