Home | History | Annotate | Download | only in 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.
     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