summaryrefslogtreecommitdiffstats
path: root/chrome/browser/download/download_manager.h
diff options
context:
space:
mode:
authorpaulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-13 02:48:59 +0000
committerpaulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-13 02:48:59 +0000
commitcdaa86594dcdd5fc4ccac5dbf63a5e4dbfcdb8ea (patch)
treec9e3f5a89a3d9733ea75b97153ef2be4e8425aa3 /chrome/browser/download/download_manager.h
parent431838df78d6e3cd06794a45cf0243be32149c7c (diff)
downloadchromium_src-cdaa86594dcdd5fc4ccac5dbf63a5e4dbfcdb8ea.zip
chromium_src-cdaa86594dcdd5fc4ccac5dbf63a5e4dbfcdb8ea.tar.gz
chromium_src-cdaa86594dcdd5fc4ccac5dbf63a5e4dbfcdb8ea.tar.bz2
Move the download code to new directories:
browser/download/ browser/views/ Review URL: http://codereview.chromium.org/2826 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2166 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/download/download_manager.h')
-rw-r--r--chrome/browser/download/download_manager.h483
1 files changed, 483 insertions, 0 deletions
diff --git a/chrome/browser/download/download_manager.h b/chrome/browser/download/download_manager.h
new file mode 100644
index 0000000..0ab3dc1
--- /dev/null
+++ b/chrome/browser/download/download_manager.h
@@ -0,0 +1,483 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The DownloadManager object manages the process of downloading, including
+// updates to the history system and providing the information for displaying
+// the downloads view in the Destinations tab. There is one DownloadManager per
+// active profile in Chrome.
+//
+// Each download is represented by a DownloadItem, and all DownloadItems
+// are owned by the DownloadManager which maintains a global list of all
+// downloads. DownloadItems are created when a user initiates a download,
+// and exist for the duration of the browser life time.
+//
+// Download observers:
+// Objects that are interested in notifications about new downloads, or progress
+// updates for a given download must implement one of the download observer
+// interfaces:
+// DownloadItem::Observer:
+// - allows observers to receive notifications about one download from start
+// to completion
+// DownloadManager::Observer:
+// - allows observers, primarily views, to be notified when changes to the
+// set of all downloads (such as new downloads, or deletes) occur
+// Use AddObserver() / RemoveObserver() on the appropriate download object to
+// receive state updates.
+//
+// Download state persistence:
+// The DownloadManager uses the history service for storing persistent
+// information about the state of all downloads. The history system maintains a
+// separate table for this called 'downloads'. At the point that the
+// DownloadManager is constructed, we query the history service for the state of
+// all persisted downloads.
+
+#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H__
+#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H__
+
+#include <string>
+#include <map>
+#include <set>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/hash_tables.h"
+#include "base/observer_list.h"
+#include "base/ref_counted.h"
+#include "chrome/browser/cancelable_request.h"
+#include "chrome/browser/history/download_types.h"
+#include "chrome/browser/history/history.h"
+#include "chrome/browser/shell_dialogs.h"
+#include "chrome/common/pref_member.h"
+
+class DownloadFileManager;
+class DownloadItem;
+class DownloadItemView;
+class DownloadManager;
+class GURL;
+class MessageLoop;
+class PrefService;
+class Profile;
+class ResourceDispatcherHost;
+class URLRequestContext;
+class WebContents;
+
+namespace base {
+class Thread;
+}
+
+// DownloadItem ----------------------------------------------------------------
+
+// One DownloadItem per download. This is the model class that stores all the
+// state for a download. Multiple views, such as a tab's download shelf and the
+// Destination tab's download view, may refer to a given DownloadItem.
+class DownloadItem {
+ public:
+ enum DownloadState {
+ IN_PROGRESS,
+ COMPLETE,
+ CANCELLED,
+ REMOVING
+ };
+
+ // Interface that observers of a particular download must implement in order
+ // to receive updates to the download's status.
+ class Observer {
+ public:
+ virtual void OnDownloadUpdated(DownloadItem* download) = 0;
+ };
+
+ // Constructing from persistent store:
+ DownloadItem(const DownloadCreateInfo& info);
+
+ // Constructing from user action:
+ DownloadItem(int32 download_id,
+ const std::wstring& path,
+ const std::wstring& url,
+ const Time start_time,
+ int64 download_size,
+ int render_process_id,
+ int request_id);
+
+ ~DownloadItem();
+
+ void Init(bool start_timer);
+
+ // Public API
+
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
+ // Notify our observers periodically
+ void UpdateObservers();
+
+ // Received a new chunk of data
+ void Update(int64 bytes_so_far);
+
+ // Cancel the download operation. We need to distinguish between cancels at
+ // exit (DownloadManager destructor) from user interface initiated cancels
+ // because at exit, the history system may not exist, and any updates to it
+ // require AddRef'ing the DownloadManager in the destructor which results in
+ // a DCHECK failure. Set 'update_history' to false when canceling from at
+ // exit to prevent this crash. This may result in a difference between the
+ // downloaded file's size on disk, and what the history system's last record
+ // of it is. At worst, we'll end up re-downloading a small portion of the file
+ // when resuming a download (assuming the server supports byte ranges).
+ void Cancel(bool update_history);
+
+ // Download operation completed
+ void Finished(int64 size);
+
+ // The user wants to remove the download from the views and history. This
+ // operation does not delete the file on the disk.
+ void Remove();
+
+ // Start/stop sending periodic updates to our observers
+ void StartProgressTimer();
+ void StopProgressTimer();
+
+ // Simple calculation of the amount of time remaining to completion. Fills
+ // |*remaining| with the amount of time remaining if successful. Fails and
+ // returns false if we do not have the number of bytes or the speed so can
+ // not estimate.
+ bool TimeRemaining(TimeDelta* remaining) const;
+
+ // Simple speed estimate in bytes/s
+ int64 CurrentSpeed() const;
+
+ // Rough percent complete, -1 means we don't know (since we didn't receive a
+ // total size).
+ int PercentComplete() const;
+
+ // Update the download's path, the actual file is renamed on the download
+ // thread.
+ void Rename(const std::wstring& full_path);
+
+ // Allow the user to temporarily pause a download or resume a paused download.
+ void TogglePause();
+
+ // Accessors
+ DownloadState state() const { return state_; }
+ std::wstring full_path() const { return full_path_; }
+ std::wstring file_name() const { return file_name_; }
+ std::wstring url() const { return url_; }
+ int64 total_bytes() const { return total_bytes_; }
+ void set_total_bytes(int64 total_bytes) { total_bytes_ = total_bytes; }
+ int64 received_bytes() const { return received_bytes_; }
+ int32 id() const { return id_; }
+ Time start_time() const { return start_time_; }
+ void set_db_handle(int64 handle) { db_handle_ = handle; }
+ int64 db_handle() const { return db_handle_; }
+ DownloadManager* manager() const { return manager_; }
+ void set_manager(DownloadManager* manager) { manager_ = manager; }
+ bool is_paused() const { return is_paused_; }
+ void set_is_paused(bool pause) { is_paused_ = pause; }
+ bool open_when_complete() const { return open_when_complete_; }
+ void set_open_when_complete(bool open) { open_when_complete_ = open; }
+ int render_process_id() const { return render_process_id_; }
+ int request_id() const { return request_id_; }
+
+ private:
+ // Internal helper for maintaining consistent received and total sizes.
+ void UpdateSize(int64 size);
+
+ // Request ID assigned by the ResourceDispatcherHost.
+ int32 id_;
+
+ // Full path to the downloaded file
+ std::wstring full_path_;
+
+ // Short display version of the file
+ std::wstring file_name_;
+
+ // The URL from whence we came, for display
+ std::wstring url_;
+
+ // Total bytes expected
+ int64 total_bytes_;
+
+ // Current received bytes
+ int64 received_bytes_;
+
+ // Start time for calculating remaining time
+ uintptr_t start_tick_;
+
+ // The current state of this download
+ DownloadState state_;
+
+ // The views of this item in the download shelf and download tab
+ ObserverList<Observer> observers_;
+
+ // Time the download was started
+ Time start_time_;
+
+ // Our persistent store handle
+ int64 db_handle_;
+
+ // Timer for regularly updating our observers
+ base::RepeatingTimer<DownloadItem> update_timer_;
+
+ // Our owning object
+ DownloadManager* manager_;
+
+ // In progress downloads may be paused by the user, we note it here
+ bool is_paused_;
+
+ // A flag for indicating if the download should be opened at completion.
+ bool open_when_complete_;
+
+ // For canceling or pausing requests.
+ int render_process_id_;
+ int request_id_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DownloadItem);
+};
+
+
+// DownloadManager -------------------------------------------------------------
+
+// Browser's download manager: manages all downloads and destination view.
+class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>,
+ public SelectFileDialog::Listener {
+ // For testing.
+ friend class DownloadManagerTest;
+
+ public:
+ DownloadManager();
+ ~DownloadManager();
+
+ static void RegisterUserPrefs(PrefService* prefs);
+
+ // Interface to implement for observers that wish to be informed of changes
+ // to the DownloadManager's collection of downloads.
+ class Observer {
+ public:
+ // New or deleted download, observers should query us for the current set
+ // of downloads.
+ virtual void ModelChanged() = 0;
+
+ // A callback once the DownloadManager has retrieved the requested set of
+ // downloads. The DownloadManagerObserver must copy the vector, but does not
+ // own the individual DownloadItems, when this call is made.
+ virtual void SetDownloads(std::vector<DownloadItem*>& downloads) = 0;
+ };
+
+ // Public API
+
+ // Begin a search for all downloads matching 'search_text'. If 'search_text'
+ // is empty, return all known downloads. The results are returned in the
+ // 'SetDownloads' observer callback.
+ void GetDownloads(Observer* observer,
+ const std::wstring& search_text);
+
+ // Returns true if initialized properly.
+ bool Init(Profile* profile);
+
+ // Schedule a query of the history service to retrieve all downloads.
+ void QueryHistoryForDownloads();
+
+ // Notifications sent from the download thread to the UI thread
+ void StartDownload(DownloadCreateInfo* info);
+ void UpdateDownload(int32 download_id, int64 size);
+ void DownloadFinished(int32 download_id, int64 size);
+
+ // Helper method for cancelling the network request associated with a
+ // download.
+ static void CancelDownloadRequest(int render_process_id, int request_id);
+
+ // Called from a view when a user clicks a UI button or link.
+ void DownloadCancelled(int32 download_id);
+ void PauseDownload(int32 download_id, bool pause);
+ void RemoveDownload(int64 download_handle);
+
+ // Remove downloads after remove_begin (inclusive) and before remove_end
+ // (exclusive). You may pass in null Time values to do an unbounded delete
+ // in either direction.
+ int RemoveDownloadsBetween(const Time remove_begin, const Time remove_end);
+
+ // Remove downloads will delete all downloads that have a timestamp that is
+ // the same or more recent than |remove_begin|. The number of downloads
+ // deleted is returned back to the caller.
+ int RemoveDownloads(const Time remove_begin);
+
+ // Download the object at the URL. Used in cases such as "Save Link As..."
+ void DownloadUrl(const GURL& url,
+ const GURL& referrer,
+ WebContents* web_contents);
+
+ // Allow objects to observe the download creation process.
+ void AddObserver(Observer* observer);
+
+ // Remove a download observer from ourself.
+ void RemoveObserver(Observer* observer);
+
+ // Methods called on completion of a query sent to the history system.
+ void OnQueryDownloadEntriesComplete(
+ std::vector<DownloadCreateInfo>* entries);
+ void OnCreateDownloadEntryComplete(DownloadCreateInfo info, int64 db_handle);
+ void OnSearchComplete(HistoryService::Handle handle,
+ std::vector<int64>* results);
+
+ // Show or Open a download via the Windows shell.
+ void ShowDownloadInShell(const DownloadItem* download);
+ void OpenDownloadInShell(const DownloadItem* download, HWND parent_window);
+
+ // The number of in progress (including paused) downloads.
+ int in_progress_count() const {
+ return static_cast<int>(in_progress_.size());
+ }
+
+ std::wstring download_path() { return *download_path_; }
+
+ // Registers this file extension for automatic opening upon download
+ // completion if 'open' is true, or prevents the extension from automatic
+ // opening if 'open' is false.
+ void OpenFilesOfExtension(const std::wstring& extension, bool open);
+
+ // Tests if a file type should be opened automatically.
+ bool ShouldOpenFileExtension(const std::wstring& extension);
+
+ // Tests if we think the server means for this mime_type to be executable.
+ static bool IsExecutableMimeType(const std::string& mime_type);
+
+ // Tests if a file type is considered executable.
+ bool IsExecutable(const std::wstring& extension);
+
+ // Resets the automatic open preference.
+ void ResetAutoOpenFiles();
+
+ // Returns true if there are automatic handlers registered for any file
+ // types.
+ bool HasAutoOpenFileTypesRegistered() const;
+
+ // Overridden from SelectFileDialog::Listener:
+ virtual void FileSelected(const std::wstring& path, void* params);
+ virtual void FileSelectionCanceled(void* params);
+
+ private:
+ // Shutdown the download manager. This call is needed only after Init.
+ void Shutdown();
+
+ // Called on the download thread to check whether the suggested file path
+ // exists. We don't check if the file exists on the UI thread to avoid UI
+ // stalls from interacting with the file system.
+ void CheckIfSuggestedPathExists(DownloadCreateInfo* info);
+
+ // Called on the UI thread once the DownloadManager has determined whether the
+ // suggested file path exists.
+ void OnPathExistenceAvailable(DownloadCreateInfo* info);
+
+ // Called back after a target path for the file to be downloaded to has been
+ // determined, either automatically based on the suggested file name, or by
+ // the user in a Save As dialog box.
+ void ContinueStartDownload(DownloadCreateInfo* info,
+ const std::wstring& target_path);
+
+ // Update the history service for a particular download.
+ void UpdateHistoryForDownload(DownloadItem* download);
+ void RemoveDownloadFromHistory(DownloadItem* download);
+ void RemoveDownloadsFromHistoryBetween(const Time remove_begin,
+ const Time remove_before);
+
+ // Inform the notification service of download starts and stops.
+ void NotifyAboutDownloadStart();
+ void NotifyAboutDownloadStop();
+
+ // Create an extension based on the file name and mime type.
+ void GenerateExtension(const std::wstring& file_name,
+ const std::string& mime_type,
+ std::wstring* generated_extension);
+
+ // Create a file name based on the response from the server.
+ void GenerateFilename(DownloadCreateInfo* info, std::wstring* generated_name);
+
+ // Persist the automatic opening preference.
+ void SaveAutoOpens();
+
+ // Runs the network cancel on the IO thread.
+ static void OnCancelDownloadRequest(ResourceDispatcherHost* rdh,
+ int render_process_id,
+ int request_id);
+
+ // Runs the pause on the IO thread.
+ static void OnPauseDownloadRequest(ResourceDispatcherHost* rdh,
+ int render_process_id,
+ int request_id,
+ bool pause);
+
+ // 'downloads_' is map of all downloads in this profile. The key is the handle
+ // returned by the history system, which is unique across sessions. This map
+ // owns all the DownloadItems once they have been created in the history
+ // system.
+ //
+ // 'in_progress_' is a map of all downloads that are in progress and that have
+ // not yet received a valid history handle. The key is the ID assigned by the
+ // ResourceDispatcherHost, which is unique for the current session. This map
+ // does not own the DownloadItems.
+ //
+ // When a download is created through a user action, the corresponding
+ // DownloadItem* is placed in 'in_progress_' and remains there until it has
+ // received a valid handle from the history system. Once it has a valid
+ // handle, the DownloadItem* is placed in the 'downloads_' map. When the
+ // download is complete, it is removed from 'in_progress_'. Downloads from
+ // past sessions read from a persisted state from the history system are
+ // placed directly into 'downloads_' since they have valid handles in the
+ // history system.
+ typedef base::hash_map<int64, DownloadItem*> DownloadMap;
+ DownloadMap downloads_;
+ DownloadMap in_progress_;
+
+ // True if the download manager has been initialized and requires a shutdown.
+ bool shutdown_needed_;
+
+ // Observers that want to be notified of changes to the set of downloads.
+ ObserverList<Observer> observers_;
+
+ // The current active profile.
+ Profile* profile_;
+ scoped_refptr<URLRequestContext> request_context_;
+
+ // Used for history service request management.
+ CancelableRequestConsumerT<Observer*, 0> cancelable_consumer_;
+
+ // Non-owning pointer for handling file writing on the download_thread_.
+ DownloadFileManager* file_manager_;
+
+ // A pointer to the main UI loop.
+ MessageLoop* ui_loop_;
+
+ // A pointer to the file thread's loop. The file thread lives longer than
+ // the DownloadManager, so this is safe to cache.
+ MessageLoop* file_loop_;
+
+ // User preferences
+ BooleanPrefMember prompt_for_download_;
+ StringPrefMember download_path_;
+
+ // The user's last choice for download directory. This is only used when the
+ // user wants us to prompt for a save location for each download.
+ std::wstring last_download_path_;
+
+ // Set of file extensions to open at download completion.
+ std::set<std::wstring> auto_open_;
+
+ // Set of file extensions that are executables and shouldn't be auto opened.
+ std::set<std::wstring> exe_types_;
+
+ // Keep track of downloads that are completed before the user selects the
+ // destination, so that observers are appropriately notified of completion
+ // after this determination is made.
+ // The map is of download_id->remaining size (bytes), both of which are
+ // required when calling DownloadFinished.
+ typedef std::map<int32, int64> PendingFinishedMap;
+ PendingFinishedMap pending_finished_downloads_;
+
+ // The "Save As" dialog box used to ask the user where a file should be
+ // saved.
+ scoped_refptr<SelectFileDialog> select_file_dialog_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DownloadManager);
+};
+
+
+#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H__