download_manager.h revision 513209b27ff55e2841eac0e4120199c23acce758
1// Copyright (c) 2010 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// Download observers: 11// Objects that are interested in notifications about new downloads, or progress 12// updates for a given download must implement one of the download observer 13// interfaces: 14// DownloadManager::Observer: 15// - allows observers, primarily views, to be notified when changes to the 16// set of all downloads (such as new downloads, or deletes) occur 17// Use AddObserver() / RemoveObserver() on the appropriate download object to 18// receive state updates. 19// 20// Download state persistence: 21// The DownloadManager uses the history service for storing persistent 22// information about the state of all downloads. The history system maintains a 23// separate table for this called 'downloads'. At the point that the 24// DownloadManager is constructed, we query the history service for the state of 25// all persisted downloads. 26 27#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ 28#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ 29#pragma once 30 31#include <map> 32#include <set> 33#include <string> 34#include <vector> 35 36#include "base/basictypes.h" 37#include "base/file_path.h" 38#include "base/observer_list.h" 39#include "base/ref_counted.h" 40#include "base/scoped_ptr.h" 41#include "base/time.h" 42#include "base/weak_ptr.h" 43#include "chrome/browser/browser_thread.h" 44#include "chrome/browser/download/download_status_updater_delegate.h" 45#include "chrome/browser/shell_dialogs.h" 46 47class DownloadFileManager; 48class DownloadHistory; 49class DownloadItem; 50class DownloadPrefs; 51class DownloadStatusUpdater; 52class GURL; 53class Profile; 54class ResourceDispatcherHost; 55class URLRequestContextGetter; 56class TabContents; 57struct DownloadCreateInfo; 58struct DownloadSaveInfo; 59 60// Browser's download manager: manages all downloads and destination view. 61class DownloadManager 62 : public base::RefCountedThreadSafe<DownloadManager, 63 BrowserThread::DeleteOnUIThread>, 64 public DownloadStatusUpdaterDelegate, 65 public SelectFileDialog::Listener { 66 // For testing. 67 friend class DownloadManagerTest; 68 friend class MockDownloadManager; 69 70 public: 71 explicit DownloadManager(DownloadStatusUpdater* status_updater); 72 73 // Shutdown the download manager. Must be called before destruction. 74 void Shutdown(); 75 76 // Interface to implement for observers that wish to be informed of changes 77 // to the DownloadManager's collection of downloads. 78 class Observer { 79 public: 80 // New or deleted download, observers should query us for the current set 81 // of downloads. 82 virtual void ModelChanged() = 0; 83 84 // Called when the DownloadManager is being destroyed to prevent Observers 85 // from calling back to a stale pointer. 86 virtual void ManagerGoingDown() {} 87 88 protected: 89 virtual ~Observer() {} 90 }; 91 92 // Return all temporary downloads that reside in the specified directory. 93 void GetTemporaryDownloads(const FilePath& dir_path, 94 std::vector<DownloadItem*>* result); 95 96 // Return all non-temporary downloads in the specified directory that are 97 // are in progress or have finished. 98 void GetAllDownloads(const FilePath& dir_path, 99 std::vector<DownloadItem*>* result); 100 101 // Return all non-temporary downloads in the specified directory that are 102 // either in-progress or finished but still waiting for user confirmation. 103 void GetCurrentDownloads(const FilePath& dir_path, 104 std::vector<DownloadItem*>* result); 105 106 // Returns all non-temporary downloads matching |query|. Empty query matches 107 // everything. 108 void SearchDownloads(const string16& query, 109 std::vector<DownloadItem*>* result); 110 111 // Returns true if initialized properly. 112 bool Init(Profile* profile); 113 114 // Notifications sent from the download thread to the UI thread 115 void StartDownload(DownloadCreateInfo* info); 116 void UpdateDownload(int32 download_id, int64 size); 117 void OnAllDataSaved(int32 download_id, int64 size); 118 119 // Called from a view when a user clicks a UI button or link. 120 void DownloadCancelled(int32 download_id); 121 void PauseDownload(int32 download_id, bool pause); 122 void RemoveDownload(int64 download_handle); 123 124 // Called when the download is renamed to its final name. 125 void DownloadRenamedToFinalName(int download_id, const FilePath& full_path); 126 127 // Remove downloads after remove_begin (inclusive) and before remove_end 128 // (exclusive). You may pass in null Time values to do an unbounded delete 129 // in either direction. 130 int RemoveDownloadsBetween(const base::Time remove_begin, 131 const base::Time remove_end); 132 133 // Remove downloads will delete all downloads that have a timestamp that is 134 // the same or more recent than |remove_begin|. The number of downloads 135 // deleted is returned back to the caller. 136 int RemoveDownloads(const base::Time remove_begin); 137 138 // Remove all downloads will delete all downloads. The number of downloads 139 // deleted is returned back to the caller. 140 int RemoveAllDownloads(); 141 142 // Called when a Save Page As download is started. Transfers ownership 143 // of |download_item| to the DownloadManager. 144 void SavePageAsDownloadStarted(DownloadItem* download_item); 145 146 // Download the object at the URL. Used in cases such as "Save Link As..." 147 void DownloadUrl(const GURL& url, 148 const GURL& referrer, 149 const std::string& referrer_encoding, 150 TabContents* tab_contents); 151 152 // Download the object at the URL and save it to the specified path. The 153 // download is treated as the temporary download and thus will not appear 154 // in the download history. Used in cases such as drag and drop. 155 void DownloadUrlToFile(const GURL& url, 156 const GURL& referrer, 157 const std::string& referrer_encoding, 158 const DownloadSaveInfo& save_info, 159 TabContents* tab_contents); 160 161 // Allow objects to observe the download creation process. 162 void AddObserver(Observer* observer); 163 164 // Remove a download observer from ourself. 165 void RemoveObserver(Observer* observer); 166 167 // Methods called on completion of a query sent to the history system. 168 void OnQueryDownloadEntriesComplete( 169 std::vector<DownloadCreateInfo>* entries); 170 void OnCreateDownloadEntryComplete( 171 const DownloadCreateInfo& info, int64 db_handle); 172 173 // Display a new download in the appropriate browser UI. 174 void ShowDownloadInBrowser(const DownloadCreateInfo& info, 175 DownloadItem* download); 176 177 // The number of in progress (including paused) downloads. 178 int in_progress_count() const { 179 return static_cast<int>(in_progress_.size()); 180 } 181 182 Profile* profile() { return profile_; } 183 184 DownloadHistory* download_history() { return download_history_.get(); } 185 186 DownloadPrefs* download_prefs() { return download_prefs_.get(); } 187 188 // Clears the last download path, used to initialize "save as" dialogs. 189 void ClearLastDownloadPath(); 190 191 // Tests if a file type should be opened automatically. 192 bool ShouldOpenFileBasedOnExtension(const FilePath& path) const; 193 194 // Overridden from DownloadStatusUpdaterDelegate: 195 virtual bool IsDownloadProgressKnown(); 196 virtual int64 GetInProgressDownloadCount(); 197 virtual int64 GetReceivedDownloadBytes(); 198 virtual int64 GetTotalDownloadBytes(); 199 200 // Overridden from SelectFileDialog::Listener: 201 virtual void FileSelected(const FilePath& path, int index, void* params); 202 virtual void FileSelectionCanceled(void* params); 203 204 // Called when the user has validated the download of a dangerous file. 205 void DangerousDownloadValidated(DownloadItem* download); 206 207 private: 208 // This class is used to let an incognito DownloadManager observe changes to 209 // a normal DownloadManager, to propagate ModelChanged() calls from the parent 210 // DownloadManager to the observers of the incognito DownloadManager. 211 class OtherDownloadManagerObserver : public Observer { 212 public: 213 explicit OtherDownloadManagerObserver( 214 DownloadManager* observing_download_manager); 215 virtual ~OtherDownloadManagerObserver(); 216 217 // Observer interface. 218 virtual void ModelChanged(); 219 virtual void ManagerGoingDown(); 220 221 private: 222 // The incognito download manager. 223 DownloadManager* observing_download_manager_; 224 225 // The original profile's download manager. 226 DownloadManager* observed_download_manager_; 227 }; 228 229 friend class BrowserThread; 230 friend class DeleteTask<DownloadManager>; 231 friend class OtherDownloadManagerObserver; 232 233 ~DownloadManager(); 234 235 // Called on the download thread to check whether the suggested file path 236 // exists. We don't check if the file exists on the UI thread to avoid UI 237 // stalls from interacting with the file system. 238 void CheckIfSuggestedPathExists(DownloadCreateInfo* info, 239 const FilePath& default_path); 240 241 // Called on the UI thread once the DownloadManager has determined whether the 242 // suggested file path exists. 243 void OnPathExistenceAvailable(DownloadCreateInfo* info); 244 245 // Called back after a target path for the file to be downloaded to has been 246 // determined, either automatically based on the suggested file name, or by 247 // the user in a Save As dialog box. 248 void CreateDownloadItem(DownloadCreateInfo* info, 249 const FilePath& target_path); 250 251 // Download cancel helper function. 252 void DownloadCancelledInternal(int download_id, 253 int render_process_id, 254 int request_id); 255 256 // Performs the last steps required when a download has been completed. 257 // It is necessary to break down the flow when a download is finished as 258 // dangerous downloads are downloaded to temporary files that need to be 259 // renamed on the file thread first. 260 // Invoked on the UI thread. 261 void ContinueDownloadFinished(DownloadItem* download); 262 263 // Renames a finished dangerous download from its temporary file name to its 264 // real file name. 265 // Invoked on the file thread. 266 void ProceedWithFinishedDangerousDownload(int64 download_handle, 267 const FilePath& path, 268 const FilePath& original_name); 269 270 // Invoked on the UI thread when a dangerous downloaded file has been renamed. 271 void DangerousDownloadRenamed(int64 download_handle, 272 bool success, 273 const FilePath& new_path, 274 int new_path_uniquifier); 275 276 // Updates the app icon about the overall download progress. 277 void UpdateAppIcon(); 278 279 // Changes the paths and file name of the specified |download|, propagating 280 // the change to the history system. 281 void RenameDownload(DownloadItem* download, const FilePath& new_path); 282 283 // Makes the ResourceDispatcherHost pause/un-pause a download request. 284 // Called on the IO thread. 285 void PauseDownloadRequest(ResourceDispatcherHost* rdh, 286 int render_process_id, 287 int request_id, 288 bool pause); 289 290 // Inform observers that the model has changed. 291 void NotifyModelChanged(); 292 293 DownloadItem* GetDownloadItem(int id); 294 295 // 'downloads_' is map of all downloads in this profile. The key is the handle 296 // returned by the history system, which is unique across sessions. This map 297 // owns all the DownloadItems once they have been created in the history 298 // system. 299 // 300 // 'in_progress_' is a map of all downloads that are in progress and that have 301 // not yet received a valid history handle. The key is the ID assigned by the 302 // ResourceDispatcherHost, which is unique for the current session. This map 303 // does not own the DownloadItems. 304 // 305 // 'dangerous_finished_' is a map of dangerous download that have finished 306 // but were not yet approved by the user. Similarly to in_progress_, the key 307 // is the ID assigned by the ResourceDispatcherHost and the map does not own 308 // the DownloadItems. It is used on shutdown to delete completed downloads 309 // that have not been approved. 310 // 311 // When a download is created through a user action, the corresponding 312 // DownloadItem* is placed in 'in_progress_' and remains there until it has 313 // received a valid handle from the history system. Once it has a valid 314 // handle, the DownloadItem* is placed in the 'downloads_' map. When the 315 // download is complete, it is removed from 'in_progress_'. Downloads from 316 // past sessions read from a persisted state from the history system are 317 // placed directly into 'downloads_' since they have valid handles in the 318 // history system. 319 typedef base::hash_map<int64, DownloadItem*> DownloadMap; 320 DownloadMap downloads_; 321 DownloadMap in_progress_; 322 DownloadMap dangerous_finished_; 323 324 // Collection of all save-page-as downloads in this profile. 325 // It owns the DownloadItems. 326 std::vector<DownloadItem*> save_page_downloads_; 327 328 // True if the download manager has been initialized and requires a shutdown. 329 bool shutdown_needed_; 330 331 // Observers that want to be notified of changes to the set of downloads. 332 ObserverList<Observer> observers_; 333 334 // The current active profile. 335 Profile* profile_; 336 scoped_refptr<URLRequestContextGetter> request_context_getter_; 337 338 scoped_ptr<DownloadHistory> download_history_; 339 340 scoped_ptr<DownloadPrefs> download_prefs_; 341 342 // Non-owning pointer for handling file writing on the download_thread_. 343 DownloadFileManager* file_manager_; 344 345 // Non-owning pointer for updating the download status. 346 base::WeakPtr<DownloadStatusUpdater> status_updater_; 347 348 // The user's last choice for download directory. This is only used when the 349 // user wants us to prompt for a save location for each download. 350 FilePath last_download_path_; 351 352 // Keep track of downloads that are completed before the user selects the 353 // destination, so that observers are appropriately notified of completion 354 // after this determination is made. 355 // The map is of download_id->remaining size (bytes), both of which are 356 // required when calling DownloadFinished. 357 typedef std::map<int32, int64> PendingFinishedMap; 358 PendingFinishedMap pending_finished_downloads_; 359 360 // The "Save As" dialog box used to ask the user where a file should be 361 // saved. 362 scoped_refptr<SelectFileDialog> select_file_dialog_; 363 364 scoped_ptr<OtherDownloadManagerObserver> other_download_manager_observer_; 365 366 DISALLOW_COPY_AND_ASSIGN(DownloadManager); 367}; 368 369#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ 370