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