1// Copyright (c) 2011 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/gtest_prod_util.h"
39#include "base/memory/ref_counted.h"
40#include "base/memory/weak_ptr.h"
41#include "base/observer_list.h"
42#include "base/scoped_ptr.h"
43#include "base/time.h"
44#include "chrome/browser/download/download_status_updater_delegate.h"
45#include "chrome/browser/ui/shell_dialogs.h"
46#include "content/browser/browser_thread.h"
47
48class DownloadFileManager;
49class DownloadHistory;
50class DownloadItem;
51class DownloadPrefs;
52class DownloadStatusUpdater;
53class GURL;
54class Profile;
55class ResourceDispatcherHost;
56class TabContents;
57struct DownloadCreateInfo;
58struct DownloadSaveInfo;
59
60namespace net {
61class URLRequestContextGetter;
62}
63
64// Browser's download manager: manages all downloads and destination view.
65class DownloadManager
66    : public base::RefCountedThreadSafe<DownloadManager,
67                                        BrowserThread::DeleteOnUIThread>,
68      public DownloadStatusUpdaterDelegate,
69      public SelectFileDialog::Listener {
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    // Called immediately after the DownloadManager puts up a select file
89    // dialog.
90    // |id| indicates which download opened the dialog.
91    virtual void SelectFileDialogDisplayed(int32 id) {}
92
93   protected:
94    virtual ~Observer() {}
95  };
96
97  // Return all temporary downloads that reside in the specified directory.
98  void GetTemporaryDownloads(const FilePath& dir_path,
99                             std::vector<DownloadItem*>* result);
100
101  // Return all non-temporary downloads in the specified directory that are
102  // are in progress or have completed.
103  void GetAllDownloads(const FilePath& dir_path,
104                       std::vector<DownloadItem*>* result);
105
106  // Return all non-temporary downloads in the specified directory that are
107  // in-progress (including dangerous downloads waiting for user confirmation).
108  void GetCurrentDownloads(const FilePath& dir_path,
109                           std::vector<DownloadItem*>* result);
110
111  // Returns all non-temporary downloads matching |query|. Empty query matches
112  // everything.
113  void SearchDownloads(const string16& query,
114                       std::vector<DownloadItem*>* result);
115
116  // Returns true if initialized properly.
117  bool Init(Profile* profile);
118
119  // Notifications sent from the download thread to the UI thread
120  void StartDownload(DownloadCreateInfo* info);
121  void UpdateDownload(int32 download_id, int64 size);
122  // |hash| is sha256 hash for the downloaded file. It is empty when the hash
123  // is not available.
124  void OnResponseCompleted(int32 download_id, int64 size, int os_error,
125                           const std::string& hash);
126
127  // Called from a view when a user clicks a UI button or link.
128  void DownloadCancelled(int32 download_id);
129  void PauseDownload(int32 download_id, bool pause);
130  void RemoveDownload(int64 download_handle);
131
132  // Determine if the download is ready for completion, i.e. has had
133  // all data saved, and completed the filename determination and
134  // history insertion.
135  bool IsDownloadReadyForCompletion(DownloadItem* download);
136
137  // If all pre-requisites have been met, complete download processing, i.e.
138  // do internal cleanup, file rename, and potentially auto-open.
139  // (Dangerous downloads still may block on user acceptance after this
140  // point.)
141  void MaybeCompleteDownload(DownloadItem* download);
142
143  // Called when the download is renamed to its final name.
144  // |uniquifier| is a number used to make unique names for the file.  It is
145  // only valid for the DANGEROUS_BUT_VALIDATED state of the download item.
146  void OnDownloadRenamedToFinalName(int download_id,
147                                    const FilePath& full_path,
148                                    int uniquifier);
149
150  // Remove downloads after remove_begin (inclusive) and before remove_end
151  // (exclusive). You may pass in null Time values to do an unbounded delete
152  // in either direction.
153  int RemoveDownloadsBetween(const base::Time remove_begin,
154                             const base::Time remove_end);
155
156  // Remove downloads will delete all downloads that have a timestamp that is
157  // the same or more recent than |remove_begin|. The number of downloads
158  // deleted is returned back to the caller.
159  int RemoveDownloads(const base::Time remove_begin);
160
161  // Remove all downloads will delete all downloads. The number of downloads
162  // deleted is returned back to the caller.
163  int RemoveAllDownloads();
164
165  // Final download manager transition for download: Update the download
166  // history and remove the download from |active_downloads_|.
167  void DownloadCompleted(int32 download_id);
168
169  // Called when a Save Page As download is started. Transfers ownership
170  // of |download_item| to the DownloadManager.
171  void SavePageAsDownloadStarted(DownloadItem* download_item);
172
173  // Download the object at the URL. Used in cases such as "Save Link As..."
174  void DownloadUrl(const GURL& url,
175                   const GURL& referrer,
176                   const std::string& referrer_encoding,
177                   TabContents* tab_contents);
178
179  // Download the object at the URL and save it to the specified path. The
180  // download is treated as the temporary download and thus will not appear
181  // in the download history. Used in cases such as drag and drop.
182  void DownloadUrlToFile(const GURL& url,
183                         const GURL& referrer,
184                         const std::string& referrer_encoding,
185                         const DownloadSaveInfo& save_info,
186                         TabContents* tab_contents);
187
188  // Allow objects to observe the download creation process.
189  void AddObserver(Observer* observer);
190
191  // Remove a download observer from ourself.
192  void RemoveObserver(Observer* observer);
193
194  // Methods called on completion of a query sent to the history system.
195  void OnQueryDownloadEntriesComplete(
196      std::vector<DownloadCreateInfo>* entries);
197  void OnCreateDownloadEntryComplete(
198      DownloadCreateInfo info, int64 db_handle);
199
200  // Display a new download in the appropriate browser UI.
201  void ShowDownloadInBrowser(const DownloadCreateInfo& info,
202                             DownloadItem* download);
203
204  // The number of in progress (including paused) downloads.
205  int in_progress_count() const {
206    return static_cast<int>(in_progress_.size());
207  }
208
209  Profile* profile() { return profile_; }
210
211  DownloadHistory* download_history() { return download_history_.get(); }
212
213  DownloadPrefs* download_prefs() { return download_prefs_.get(); }
214
215  // Creates the download item.  Must be called on the UI thread.
216  void CreateDownloadItem(DownloadCreateInfo* info);
217
218  // Clears the last download path, used to initialize "save as" dialogs.
219  void ClearLastDownloadPath();
220
221  // Tests if a file type should be opened automatically.
222  bool ShouldOpenFileBasedOnExtension(const FilePath& path) const;
223
224  // Overridden from DownloadStatusUpdaterDelegate:
225  virtual bool IsDownloadProgressKnown();
226  virtual int64 GetInProgressDownloadCount();
227  virtual int64 GetReceivedDownloadBytes();
228  virtual int64 GetTotalDownloadBytes();
229
230  // Overridden from SelectFileDialog::Listener:
231  virtual void FileSelected(const FilePath& path, int index, void* params);
232  virtual void FileSelectionCanceled(void* params);
233
234  // Called when the user has validated the download of a dangerous file.
235  void DangerousDownloadValidated(DownloadItem* download);
236
237  // Callback function after url is checked with safebrowsing service.
238  void CheckDownloadUrlDone(DownloadCreateInfo* info, bool is_dangerous_url);
239
240  // Callback function after download file hash is checked with safebrowsing
241  // service.
242  void CheckDownloadHashDone(int32 download_id, bool is_dangerous_hash);
243
244 private:
245  // For testing.
246  friend class DownloadManagerTest;
247  friend class MockDownloadManager;
248
249  // This class is used to let an incognito DownloadManager observe changes to
250  // a normal DownloadManager, to propagate ModelChanged() calls from the parent
251  // DownloadManager to the observers of the incognito DownloadManager.
252  class OtherDownloadManagerObserver : public Observer {
253   public:
254    explicit OtherDownloadManagerObserver(
255        DownloadManager* observing_download_manager);
256    virtual ~OtherDownloadManagerObserver();
257
258    // Observer interface.
259    virtual void ModelChanged();
260    virtual void ManagerGoingDown();
261
262   private:
263    // The incognito download manager.
264    DownloadManager* observing_download_manager_;
265
266    // The original profile's download manager.
267    DownloadManager* observed_download_manager_;
268  };
269
270  friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
271  friend class DeleteTask<DownloadManager>;
272  friend class OtherDownloadManagerObserver;
273
274  ~DownloadManager();
275
276  // Called on the download thread to check whether the suggested file path
277  // exists.  We don't check if the file exists on the UI thread to avoid UI
278  // stalls from interacting with the file system.
279  void CheckIfSuggestedPathExists(DownloadCreateInfo* info,
280                                  const FilePath& default_path);
281
282  // Called on the UI thread once the DownloadManager has determined whether the
283  // suggested file path exists.
284  void OnPathExistenceAvailable(DownloadCreateInfo* info);
285
286  // Called back after a target path for the file to be downloaded to has been
287  // determined, either automatically based on the suggested file name, or by
288  // the user in a Save As dialog box.
289  void AttachDownloadItem(DownloadCreateInfo* info);
290
291  // Download cancel helper function.
292  void DownloadCancelledInternal(int download_id,
293                                 int render_process_id,
294                                 int request_id);
295
296  // All data has been downloaded.
297  // |hash| is sha256 hash for the downloaded file. It is empty when the hash
298  // is not available.
299  void OnAllDataSaved(int32 download_id, int64 size, const std::string& hash);
300
301  // An error occurred in the download.
302  void OnDownloadError(int32 download_id, int64 size, int os_error);
303
304  // Updates the app icon about the overall download progress.
305  void UpdateAppIcon();
306
307  // Makes the ResourceDispatcherHost pause/un-pause a download request.
308  // Called on the IO thread.
309  void PauseDownloadRequest(ResourceDispatcherHost* rdh,
310                            int render_process_id,
311                            int request_id,
312                            bool pause);
313
314  // Inform observers that the model has changed.
315  void NotifyModelChanged();
316
317  DownloadItem* GetDownloadItem(int id);
318
319  // Debugging routine to confirm relationship between below
320  // containers; no-op if NDEBUG.
321  void AssertContainersConsistent() const;
322
323  // |downloads_| is the owning set for all downloads known to the
324  // DownloadManager.  This includes downloads started by the user in
325  // this session, downloads initialized from the history system, and
326  // "save page as" downloads.  All other DownloadItem containers in
327  // the DownloadManager are maps; they do not own the DownloadItems.
328  // Note that this is the only place (with any functional implications;
329  // see save_page_as_downloads_ below) that "save page as" downloads are
330  // kept, as the DownloadManager's only job is to hold onto those
331  // until destruction.
332  //
333  // |history_downloads_| is map of all downloads in this profile. The key
334  // is the handle returned by the history system, which is unique
335  // across sessions.
336  //
337  // |active_downloads_| is a map of all downloads that are currently being
338  // processed. The key is the ID assigned by the ResourceDispatcherHost,
339  // which is unique for the current session.
340  //
341  // |in_progress_| is a map of all downloads that are in progress and that have
342  // not yet received a valid history handle. The key is the ID assigned by the
343  // ResourceDispatcherHost, which is unique for the current session.
344  //
345  // |save_page_as_downloads_| (if defined) is a collection of all the
346  // downloads the "save page as" system has given to us to hold onto
347  // until we are destroyed.  It is only used for debugging.
348  //
349  // When a download is created through a user action, the corresponding
350  // DownloadItem* is placed in |active_downloads_| and remains there until the
351  // download is in a terminal state (COMPLETE or CANCELLED).  It is also
352  // placed in |in_progress_| and remains there until it has received a
353  // valid handle from the history system. Once it has a valid handle, the
354  // DownloadItem* is placed in the |history_downloads_| map.  When the
355  // download reaches a terminal state, it is removed from |in_progress_|.
356  // Downloads from past sessions read from a persisted state from the
357  // history system are placed directly into |history_downloads_| since
358  // they have valid handles in the history system.
359  typedef std::set<DownloadItem*> DownloadSet;
360  typedef base::hash_map<int64, DownloadItem*> DownloadMap;
361
362  DownloadSet downloads_;
363  DownloadMap history_downloads_;
364  DownloadMap in_progress_;
365  DownloadMap active_downloads_;
366#if !defined(NDEBUG)
367  DownloadSet save_page_as_downloads_;
368#endif
369
370  // True if the download manager has been initialized and requires a shutdown.
371  bool shutdown_needed_;
372
373  // Observers that want to be notified of changes to the set of downloads.
374  ObserverList<Observer> observers_;
375
376  // The current active profile.
377  Profile* profile_;
378  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
379
380  scoped_ptr<DownloadHistory> download_history_;
381
382  scoped_ptr<DownloadPrefs> download_prefs_;
383
384  // Non-owning pointer for handling file writing on the download_thread_.
385  DownloadFileManager* file_manager_;
386
387  // Non-owning pointer for updating the download status.
388  base::WeakPtr<DownloadStatusUpdater> status_updater_;
389
390  // The user's last choice for download directory. This is only used when the
391  // user wants us to prompt for a save location for each download.
392  FilePath last_download_path_;
393
394  // The "Save As" dialog box used to ask the user where a file should be
395  // saved.
396  scoped_refptr<SelectFileDialog> select_file_dialog_;
397
398  scoped_ptr<OtherDownloadManagerObserver> other_download_manager_observer_;
399
400  DISALLOW_COPY_AND_ASSIGN(DownloadManager);
401};
402
403#endif  // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_
404