• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
48 class DownloadFileManager;
49 class DownloadHistory;
50 class DownloadItem;
51 class DownloadPrefs;
52 class DownloadStatusUpdater;
53 class GURL;
54 class Profile;
55 class ResourceDispatcherHost;
56 class TabContents;
57 struct DownloadCreateInfo;
58 struct DownloadSaveInfo;
59 
60 namespace net {
61 class URLRequestContextGetter;
62 }
63 
64 // Browser's download manager: manages all downloads and destination view.
65 class 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.
ManagerGoingDown()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.
SelectFileDialogDisplayed(int32 id)91     virtual void SelectFileDialogDisplayed(int32 id) {}
92 
93    protected:
~Observer()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.
in_progress_count()205   int in_progress_count() const {
206     return static_cast<int>(in_progress_.size());
207   }
208 
profile()209   Profile* profile() { return profile_; }
210 
download_history()211   DownloadHistory* download_history() { return download_history_.get(); }
212 
download_prefs()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