diff options
author | ahendrickson@chromium.org <ahendrickson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-17 16:12:58 +0000 |
---|---|---|
committer | ahendrickson@chromium.org <ahendrickson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-17 16:12:58 +0000 |
commit | 5656f8a3758a37f9bc64e395cad7445b0f38f0d2 (patch) | |
tree | cc8295c423a142b49a83793c7e10f7ca706ece49 /content/browser/download | |
parent | ce01428131c7b158090a67e6dce5621ffe9b4b26 (diff) | |
download | chromium_src-5656f8a3758a37f9bc64e395cad7445b0f38f0d2.zip chromium_src-5656f8a3758a37f9bc64e395cad7445b0f38f0d2.tar.gz chromium_src-5656f8a3758a37f9bc64e395cad7445b0f38f0d2.tar.bz2 |
Created a DownloadManager interface, for use in unit tests..
Bug=None
Test=None
Review URL: http://codereview.chromium.org/8351052
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110499 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/download')
-rw-r--r-- | content/browser/download/download_manager.h | 280 | ||||
-rw-r--r-- | content/browser/download/download_manager_impl.cc (renamed from content/browser/download/download_manager.cc) | 210 | ||||
-rwxr-xr-x | content/browser/download/download_manager_impl.h | 248 | ||||
-rwxr-xr-x | content/browser/download/mock_download_manager.cc | 226 | ||||
-rw-r--r-- | content/browser/download/mock_download_manager.h | 87 |
5 files changed, 748 insertions, 303 deletions
diff --git a/content/browser/download/download_manager.h b/content/browser/download/download_manager.h index 3bbd4a7..5522549 100644 --- a/content/browser/download/download_manager.h +++ b/content/browser/download/download_manager.h @@ -28,34 +28,21 @@ #define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ #pragma once -#include <map> -#include <set> #include <string> #include <vector> #include "base/basictypes.h" -#include "base/callback.h" #include "base/file_path.h" #include "base/gtest_prod_util.h" -#include "base/hash_tables.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "base/synchronization/lock.h" #include "base/time.h" #include "content/browser/download/download_id.h" #include "content/browser/download/download_item.h" -#include "content/browser/download/download_status_updater_delegate.h" #include "content/browser/download/interrupt_reasons.h" -#include "content/common/content_export.h" #include "content/public/browser/browser_thread.h" #include "net/base/net_errors.h" class DownloadFileManager; -class DownloadIdFactory; class DownloadRequestHandle; -class DownloadStatusUpdater; class GURL; class TabContents; struct DownloadCreateInfo; @@ -69,15 +56,12 @@ class DownloadManagerDelegate; // Browser's download manager: manages all downloads and destination view. class CONTENT_EXPORT DownloadManager : public base::RefCountedThreadSafe< - DownloadManager, content::BrowserThread::DeleteOnUIThread>, - public DownloadStatusUpdaterDelegate { + DownloadManager, content::BrowserThread::DeleteOnUIThread> { public: - DownloadManager(content::DownloadManagerDelegate* delegate, - DownloadIdFactory* id_factory, - DownloadStatusUpdater* status_updater); + virtual ~DownloadManager() {} // Shutdown the download manager. Must be called before destruction. - void Shutdown(); + virtual void Shutdown() = 0; // Interface to implement for observers that wish to be informed of changes // to the DownloadManager's collection of downloads. @@ -103,323 +87,209 @@ class CONTENT_EXPORT DownloadManager typedef std::vector<DownloadItem*> DownloadVector; // Return all temporary downloads that reside in the specified directory. - void GetTemporaryDownloads(const FilePath& dir_path, DownloadVector* result); + virtual void GetTemporaryDownloads(const FilePath& dir_path, + DownloadVector* result) = 0; // Return all non-temporary downloads in the specified directory that are // are in progress or have completed. - void GetAllDownloads(const FilePath& dir_path, DownloadVector* result); + virtual void GetAllDownloads(const FilePath& dir_path, + DownloadVector* result) = 0; // Returns all non-temporary downloads matching |query|. Empty query matches // everything. - void SearchDownloads(const string16& query, DownloadVector* result); + virtual void SearchDownloads(const string16& query, + DownloadVector* result) = 0; // Returns true if initialized properly. - bool Init(content::BrowserContext* browser_context); + virtual bool Init(content::BrowserContext* browser_context) = 0; // Notifications sent from the download thread to the UI thread - void StartDownload(int32 id); - void UpdateDownload(int32 download_id, int64 size); + virtual void StartDownload(int32 id) = 0; + virtual void UpdateDownload(int32 download_id, int64 size) = 0; // |download_id| is the ID of the download. // |size| is the number of bytes that have been downloaded. // |hash| is sha256 hash for the downloaded file. It is empty when the hash // is not available. - void OnResponseCompleted(int32 download_id, int64 size, - const std::string& hash); + virtual void OnResponseCompleted(int32 download_id, int64 size, + const std::string& hash) = 0; // Offthread target for cancelling a particular download. Will be a no-op // if the download has already been cancelled. - void CancelDownload(int32 download_id); + virtual void CancelDownload(int32 download_id) = 0; // Called when there is an error in the download. // |download_id| is the ID of the download. // |size| is the number of bytes that are currently downloaded. // |reason| is a download interrupt reason code. - void OnDownloadInterrupted(int32 download_id, int64 size, - InterruptReason reason); + virtual void OnDownloadInterrupted(int32 download_id, int64 size, + InterruptReason reason) = 0; // Called from DownloadItem to handle the DownloadManager portion of a // Cancel; should not be called from other locations. - void DownloadCancelledInternal(DownloadItem* download); + virtual void DownloadCancelledInternal(DownloadItem* download) = 0; // Called from a view when a user clicks a UI button or link. - void RemoveDownload(int64 download_handle); + virtual void RemoveDownload(int64 download_handle) = 0; // Determine if the download is ready for completion, i.e. has had // all data saved, and completed the filename determination and // history insertion. - bool IsDownloadReadyForCompletion(DownloadItem* download); + virtual bool IsDownloadReadyForCompletion(DownloadItem* download) = 0; // If all pre-requisites have been met, complete download processing, i.e. // do internal cleanup, file rename, and potentially auto-open. // (Dangerous downloads still may block on user acceptance after this // point.) - void MaybeCompleteDownload(DownloadItem* download); + virtual void MaybeCompleteDownload(DownloadItem* download) = 0; // Called when the download is renamed to its final name. // |uniquifier| is a number used to make unique names for the file. It is // only valid for the DANGEROUS_BUT_VALIDATED state of the download item. - void OnDownloadRenamedToFinalName(int download_id, + virtual void OnDownloadRenamedToFinalName(int download_id, const FilePath& full_path, - int uniquifier); + int uniquifier) = 0; // 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 base::Time remove_begin, - const base::Time remove_end); + virtual int RemoveDownloadsBetween(const base::Time remove_begin, + const base::Time remove_end) = 0; // 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 base::Time remove_begin); + virtual int RemoveDownloads(const base::Time remove_begin) = 0; // Remove all downloads will delete all downloads. The number of downloads // deleted is returned back to the caller. - int RemoveAllDownloads(); + virtual int RemoveAllDownloads() = 0; // Final download manager transition for download: Update the download // history and remove the download from |active_downloads_|. - void DownloadCompleted(int32 download_id); + virtual void DownloadCompleted(int32 download_id) = 0; // Download the object at the URL. Used in cases such as "Save Link As..." - void DownloadUrl(const GURL& url, + virtual void DownloadUrl(const GURL& url, const GURL& referrer, const std::string& referrer_encoding, - TabContents* tab_contents); + TabContents* tab_contents) = 0; // Download the object at the URL and save it to the specified path. The // download is treated as the temporary download and thus will not appear // in the download history. Used in cases such as drag and drop. - void DownloadUrlToFile(const GURL& url, + virtual void DownloadUrlToFile(const GURL& url, const GURL& referrer, const std::string& referrer_encoding, const DownloadSaveInfo& save_info, - TabContents* tab_contents); + TabContents* tab_contents) = 0; // Allow objects to observe the download creation process. - void AddObserver(Observer* observer); + virtual void AddObserver(Observer* observer) = 0; // Remove a download observer from ourself. - void RemoveObserver(Observer* observer); + virtual void RemoveObserver(Observer* observer) = 0; // Called by the embedder, after creating the download manager, to let it know // about downloads from previous runs of the browser. - void OnPersistentStoreQueryComplete( - std::vector<DownloadPersistentStoreInfo>* entries); + virtual void OnPersistentStoreQueryComplete( + std::vector<DownloadPersistentStoreInfo>* entries) = 0; // Called by the embedder, in response to // DownloadManagerDelegate::AddItemToPersistentStore. - void OnItemAddedToPersistentStore(int32 download_id, int64 db_handle); + virtual void OnItemAddedToPersistentStore(int32 download_id, + int64 db_handle) = 0; // Display a new download in the appropriate browser UI. - void ShowDownloadInBrowser(DownloadItem* download); + virtual void ShowDownloadInBrowser(DownloadItem* download) = 0; // The number of in progress (including paused) downloads. - int in_progress_count() const { - return static_cast<int>(in_progress_.size()); - } + virtual int InProgressCount() const = 0; - content::BrowserContext* browser_context() { return browser_context_; } + virtual content::BrowserContext* BrowserContext() = 0; - FilePath last_download_path() { return last_download_path_; } + virtual FilePath LastDownloadPath() = 0; // Creates the download item. Must be called on the UI thread. - void CreateDownloadItem(DownloadCreateInfo* info, - const DownloadRequestHandle& request_handle); + virtual void CreateDownloadItem(DownloadCreateInfo* info, + const DownloadRequestHandle& request_handle) = 0; // Clears the last download path, used to initialize "save as" dialogs. - void ClearLastDownloadPath(); - - // Overridden from DownloadStatusUpdaterDelegate: - virtual bool IsDownloadProgressKnown() const OVERRIDE; - virtual int64 GetInProgressDownloadCount() const OVERRIDE; - virtual int64 GetReceivedDownloadBytes() const OVERRIDE; - virtual int64 GetTotalDownloadBytes() const OVERRIDE; + virtual void ClearLastDownloadPath() = 0; // Called by the delegate after the save as dialog is closed. - void FileSelected(const FilePath& path, void* params); - void FileSelectionCanceled(void* params); + virtual void FileSelected(const FilePath& path, void* params) = 0; + virtual void FileSelectionCanceled(void* params) = 0; // Called by the delegate if it delayed the download in // DownloadManagerDelegate::ShouldStartDownload and now is ready. - void RestartDownload(int32 download_id); + virtual void RestartDownload(int32 download_id) = 0; // Mark the download opened in the persistent store. - void MarkDownloadOpened(DownloadItem* download); + virtual void MarkDownloadOpened(DownloadItem* download) = 0; // Checks whether downloaded files still exist. Updates state of downloads // that refer to removed files. The check runs in the background and may // finish asynchronously after this method returns. - void CheckForHistoryFilesRemoval(); + virtual void CheckForHistoryFilesRemoval() = 0; // Checks whether a downloaded file still exists and updates the file's state // if the file is already removed. The check runs in the background and may // finish asynchronously after this method returns. - void CheckForFileRemoval(DownloadItem* download_item); + virtual void CheckForFileRemoval(DownloadItem* download_item) = 0; // Assert the named download item is on the correct queues // in the DownloadManager. For debugging. - void AssertQueueStateConsistent(DownloadItem* download); + virtual void AssertQueueStateConsistent(DownloadItem* download) = 0; // Get the download item from the history map. Useful after the item has // been removed from the active map, or was retrieved from the history DB. - DownloadItem* GetDownloadItem(int id); + virtual DownloadItem* GetDownloadItem(int id) = 0; // Called when Save Page download starts. Transfers ownership of |download| // to the DownloadManager. - void SavePageDownloadStarted(DownloadItem* download); + virtual void SavePageDownloadStarted(DownloadItem* download) = 0; // Called when Save Page download is done. - void SavePageDownloadFinished(DownloadItem* download); + virtual void SavePageDownloadFinished(DownloadItem* download) = 0; // Get the download item from the active map. Useful when the item is not // yet in the history map. - DownloadItem* GetActiveDownloadItem(int id); + virtual DownloadItem* GetActiveDownloadItem(int id) = 0; - content::DownloadManagerDelegate* delegate() const { return delegate_; } + virtual content::DownloadManagerDelegate* delegate() const = 0; // For testing only. May be called from tests indirectly (through // other for testing only methods). - void SetDownloadManagerDelegate(content::DownloadManagerDelegate* delegate); + virtual void SetDownloadManagerDelegate( + content::DownloadManagerDelegate* delegate) = 0; - DownloadId GetNextId(); + virtual DownloadId GetNextId() = 0; - private: - typedef std::set<DownloadItem*> DownloadSet; - typedef base::hash_map<int64, DownloadItem*> DownloadMap; + protected: + // These functions are here for unit tests. + + // 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. + virtual void ContinueDownloadWithPath(DownloadItem* download, + const FilePath& chosen_file) = 0; + // Retrieves the download from the |download_id|. + // Returns NULL if the download is not active. + virtual DownloadItem* GetActiveDownload(int32 download_id) = 0; + + virtual void SetFileManager(DownloadFileManager* file_manager) = 0; + + private: // For testing. friend class DownloadManagerTest; - friend class DownloadTest; - friend class MockDownloadManager; friend class base::RefCountedThreadSafe< DownloadManager, content::BrowserThread::DeleteOnUIThread>; friend struct content::BrowserThread::DeleteOnThread< content::BrowserThread::UI>; friend class DeleteTask<DownloadManager>; - - virtual ~DownloadManager(); - - // Called on the FILE thread to check the existence of a downloaded file. - void CheckForFileRemovalOnFileThread(int64 db_handle, const FilePath& path); - - // Called on the UI thread if the FILE thread detects the removal of - // the downloaded file. The UI thread updates the state of the file - // and then notifies this update to the file's observer. - void OnFileRemovalDetected(int64 db_handle); - - // 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 ContinueDownloadWithPath(DownloadItem* download, - const FilePath& chosen_file); - - // Retrieves the download from the |download_id|. - // Returns NULL if the download is not active. - DownloadItem* GetActiveDownload(int32 download_id); - - // Removes |download| from the active and in progress maps. - // Called when the download is cancelled or has an error. - // Does nothing if the download is not in the history DB. - void RemoveFromActiveList(DownloadItem* download); - - // Updates the delegate about the overall download progress. - void UpdateDownloadProgress(); - - // Inform observers that the model has changed. - void NotifyModelChanged(); - - // Debugging routine to confirm relationship between below - // containers; no-op if NDEBUG. - void AssertContainersConsistent() const; - - // Add a DownloadItem to history_downloads_. - void AddDownloadItemToHistory(DownloadItem* item, int64 db_handle); - - // Remove from internal maps. - int RemoveDownloadItems(const DownloadVector& pending_deletes); - - // Called when a download entry is committed to the persistent store. - void OnDownloadItemAddedToPersistentStore(int32 download_id, int64 db_handle); - - // Called when Save Page As entry is commited to the persistent store. - void OnSavePageItemAddedToPersistentStore(int32 download_id, int64 db_handle); - - // |downloads_| is the owning set for all downloads known to the - // DownloadManager. This includes downloads started by the user in - // this session, downloads initialized from the history system, and - // "save page as" downloads. All other DownloadItem containers in - // the DownloadManager are maps; they do not own the DownloadItems. - // Note that this is the only place (with any functional implications; - // see save_page_downloads_ below) that "save page as" downloads are - // kept, as the DownloadManager's only job is to hold onto those - // until destruction. - // - // |history_downloads_| is map of all downloads in this browser context. The - // key is the handle returned by the history system, which is unique across - // sessions. - // - // |active_downloads_| is a map of all downloads that are currently being - // processed. The key is the ID assigned by the DownloadFileManager, - // which is unique for the current session. - // - // |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 - // DownloadFileManager, which is unique for the current session. - // - // |save_page_downloads_| (if defined) is a collection of all the - // downloads the "save page as" system has given to us to hold onto - // until we are destroyed. They key is DownloadFileManager, so it is unique - // compared to download item. It is only used for debugging. - // - // When a download is created through a user action, the corresponding - // DownloadItem* is placed in |active_downloads_| and remains there until the - // download is in a terminal state (COMPLETE or CANCELLED). It is also - // 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 |history_downloads_| map. When the - // download reaches a terminal state, it is removed from |in_progress_|. - // Downloads from past sessions read from a persisted state from the - // history system are placed directly into |history_downloads_| since - // they have valid handles in the history system. - - DownloadSet downloads_; - DownloadMap history_downloads_; - DownloadMap in_progress_; - DownloadMap active_downloads_; - DownloadMap save_page_downloads_; - - // 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 browser context. - content::BrowserContext* browser_context_; - - // Non-owning pointer for handling file writing on the download_thread_. - DownloadFileManager* file_manager_; - - // Non-owning pointer for updating the download status. - base::WeakPtr<DownloadStatusUpdater> status_updater_; - - // 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. - FilePath last_download_path_; - - // Allows an embedder to control behavior. Guaranteed to outlive this object. - content::DownloadManagerDelegate* delegate_; - - DownloadIdFactory* id_factory_; - - // TODO(rdsmith): Remove when http://crbug.com/85408 is fixed. - // For debugging only. - int64 largest_db_handle_in_history_; - - DISALLOW_COPY_AND_ASSIGN(DownloadManager); }; #endif // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_H_ diff --git a/content/browser/download/download_manager.cc b/content/browser/download/download_manager_impl.cc index e80113e..62dd7e8 100644 --- a/content/browser/download/download_manager.cc +++ b/content/browser/download/download_manager_impl.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/download/download_manager.h" +#include "content/browser/download/download_manager_impl.h" #include <iterator> @@ -72,35 +72,36 @@ void BeginDownload(const URLParams& url_params, } // namespace -DownloadManager::DownloadManager(content::DownloadManagerDelegate* delegate, - DownloadIdFactory* id_factory, - DownloadStatusUpdater* status_updater) - : shutdown_needed_(false), - browser_context_(NULL), - file_manager_(NULL), - status_updater_((status_updater != NULL) - ? status_updater->AsWeakPtr() - : base::WeakPtr<DownloadStatusUpdater>()), - delegate_(delegate), - id_factory_(id_factory), - largest_db_handle_in_history_(DownloadItem::kUninitializedHandle) { +DownloadManagerImpl::DownloadManagerImpl( + content::DownloadManagerDelegate* delegate, + DownloadIdFactory* id_factory, + DownloadStatusUpdater* status_updater) + : shutdown_needed_(false), + browser_context_(NULL), + file_manager_(NULL), + status_updater_((status_updater != NULL) + ? status_updater->AsWeakPtr() + : base::WeakPtr<DownloadStatusUpdater>()), + delegate_(delegate), + id_factory_(id_factory), + largest_db_handle_in_history_(DownloadItem::kUninitializedHandle) { // NOTE(benjhayden): status_updater may be NULL when using // TestingBrowserProcess. if (status_updater_.get() != NULL) status_updater_->AddDelegate(this); } -DownloadManager::~DownloadManager() { +DownloadManagerImpl::~DownloadManagerImpl() { DCHECK(!shutdown_needed_); if (status_updater_.get() != NULL) status_updater_->RemoveDelegate(this); } -DownloadId DownloadManager::GetNextId() { +DownloadId DownloadManagerImpl::GetNextId() { return id_factory_->GetNextId(); } -void DownloadManager::Shutdown() { +void DownloadManagerImpl::Shutdown() { VLOG(20) << __FUNCTION__ << "()" << " shutdown_needed_ = " << shutdown_needed_; if (!shutdown_needed_) @@ -167,7 +168,7 @@ void DownloadManager::Shutdown() { shutdown_needed_ = false; } -void DownloadManager::GetTemporaryDownloads( +void DownloadManagerImpl::GetTemporaryDownloads( const FilePath& dir_path, DownloadVector* result) { DCHECK(result); @@ -179,7 +180,7 @@ void DownloadManager::GetTemporaryDownloads( } } -void DownloadManager::GetAllDownloads( +void DownloadManagerImpl::GetAllDownloads( const FilePath& dir_path, DownloadVector* result) { DCHECK(result); @@ -191,8 +192,8 @@ void DownloadManager::GetAllDownloads( } } -void DownloadManager::SearchDownloads(const string16& query, - DownloadVector* result) { +void DownloadManagerImpl::SearchDownloads(const string16& query, + DownloadVector* result) { string16 query_lower(base::i18n::ToLower(query)); for (DownloadMap::iterator it = history_downloads_.begin(); @@ -214,7 +215,7 @@ void DownloadManager::SearchDownloads(const string16& query, } // Query the history service for information about all persisted downloads. -bool DownloadManager::Init(content::BrowserContext* browser_context) { +bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { DCHECK(browser_context); DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; shutdown_needed_ = true; @@ -235,14 +236,14 @@ bool DownloadManager::Init(content::BrowserContext* browser_context) { } // We have received a message from DownloadFileManager about a new download. -void DownloadManager::StartDownload(int32 download_id) { +void DownloadManagerImpl::StartDownload(int32 download_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (delegate_->ShouldStartDownload(download_id)) RestartDownload(download_id); } -void DownloadManager::CheckForHistoryFilesRemoval() { +void DownloadManagerImpl::CheckForHistoryFilesRemoval() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); for (DownloadMap::iterator it = history_downloads_.begin(); it != history_downloads_.end(); ++it) { @@ -250,29 +251,31 @@ void DownloadManager::CheckForHistoryFilesRemoval() { } } -void DownloadManager::CheckForFileRemoval(DownloadItem* download_item) { +void DownloadManagerImpl::CheckForFileRemoval(DownloadItem* download_item) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (download_item->IsComplete() && !download_item->file_externally_removed()) { BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, - base::Bind(&DownloadManager::CheckForFileRemovalOnFileThread, + base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread, this, download_item->db_handle(), download_item->GetTargetFilePath())); } } -void DownloadManager::CheckForFileRemovalOnFileThread( +void DownloadManagerImpl::CheckForFileRemovalOnFileThread( int64 db_handle, const FilePath& path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); if (!file_util::PathExists(path)) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&DownloadManager::OnFileRemovalDetected, this, db_handle)); + base::Bind(&DownloadManagerImpl::OnFileRemovalDetected, + this, + db_handle)); } } -void DownloadManager::OnFileRemovalDetected(int64 db_handle) { +void DownloadManagerImpl::OnFileRemovalDetected(int64 db_handle) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DownloadMap::iterator it = history_downloads_.find(db_handle); if (it != history_downloads_.end()) { @@ -281,7 +284,7 @@ void DownloadManager::OnFileRemovalDetected(int64 db_handle) { } } -void DownloadManager::RestartDownload( +void DownloadManagerImpl::RestartDownload( int32 download_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -314,7 +317,15 @@ void DownloadManager::RestartDownload( } } -void DownloadManager::CreateDownloadItem( +content::BrowserContext* DownloadManagerImpl::BrowserContext() { + return browser_context_; +} + +FilePath DownloadManagerImpl::LastDownloadPath() { + return last_download_path_; +} + +void DownloadManagerImpl::CreateDownloadItem( DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -330,8 +341,8 @@ void DownloadManager::CreateDownloadItem( active_downloads_[download_id] = download; } -void DownloadManager::ContinueDownloadWithPath(DownloadItem* download, - const FilePath& chosen_file) { +void DownloadManagerImpl::ContinueDownloadWithPath( + DownloadItem* download, const FilePath& chosen_file) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(download); @@ -367,7 +378,7 @@ void DownloadManager::ContinueDownloadWithPath(DownloadItem* download, delegate_->AddItemToPersistentStore(download); } -void DownloadManager::UpdateDownload(int32 download_id, int64 size) { +void DownloadManagerImpl::UpdateDownload(int32 download_id, int64 size) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DownloadMap::iterator it = active_downloads_.find(download_id); if (it != active_downloads_.end()) { @@ -380,9 +391,9 @@ void DownloadManager::UpdateDownload(int32 download_id, int64 size) { } } -void DownloadManager::OnResponseCompleted(int32 download_id, - int64 size, - const std::string& hash) { +void DownloadManagerImpl::OnResponseCompleted(int32 download_id, + int64 size, + const std::string& hash) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id << " size = " << size; @@ -400,7 +411,7 @@ void DownloadManager::OnResponseCompleted(int32 download_id, MaybeCompleteDownload(download); } -void DownloadManager::AssertQueueStateConsistent(DownloadItem* download) { +void DownloadManagerImpl::AssertQueueStateConsistent(DownloadItem* download) { // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. if (download->state() == DownloadItem::REMOVING) { CHECK(!ContainsKey(downloads_, download)); @@ -437,7 +448,7 @@ void DownloadManager::AssertQueueStateConsistent(DownloadItem* download) { CHECK(ContainsKey(active_downloads_, download->id())); } -bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { +bool DownloadManagerImpl::IsDownloadReadyForCompletion(DownloadItem* download) { // If we don't have all the data, the download is not ready for // completion. if (!download->all_data_saved()) @@ -462,7 +473,7 @@ bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { return true; } -void DownloadManager::MaybeCompleteDownload(DownloadItem* download) { +void DownloadManagerImpl::MaybeCompleteDownload(DownloadItem* download) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); VLOG(20) << __FUNCTION__ << "()" << " download = " << download->DebugString(false); @@ -499,7 +510,7 @@ void DownloadManager::MaybeCompleteDownload(DownloadItem* download) { download->OnDownloadCompleting(file_manager_); } -void DownloadManager::DownloadCompleted(int32 download_id) { +void DownloadManagerImpl::DownloadCompleted(int32 download_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DownloadItem* download = GetDownloadItem(download_id); DCHECK(download); @@ -508,9 +519,10 @@ void DownloadManager::DownloadCompleted(int32 download_id) { AssertQueueStateConsistent(download); } -void DownloadManager::OnDownloadRenamedToFinalName(int download_id, - const FilePath& full_path, - int uniquifier) { +void DownloadManagerImpl::OnDownloadRenamedToFinalName( + int download_id, + const FilePath& full_path, + int uniquifier) { VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id << " full_path = \"" << full_path.value() << "\"" << " uniquifier = " << uniquifier; @@ -536,7 +548,7 @@ void DownloadManager::OnDownloadRenamedToFinalName(int download_id, delegate_->UpdatePathForItemInPersistentStore(item, full_path); } -void DownloadManager::CancelDownload(int32 download_id) { +void DownloadManagerImpl::CancelDownload(int32 download_id) { DownloadItem* download = GetActiveDownload(download_id); // A cancel at the right time could remove the download from the // |active_downloads_| map before we get here. @@ -546,7 +558,7 @@ void DownloadManager::CancelDownload(int32 download_id) { download->Cancel(true); } -void DownloadManager::DownloadCancelledInternal(DownloadItem* download) { +void DownloadManagerImpl::DownloadCancelledInternal(DownloadItem* download) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); VLOG(20) << __FUNCTION__ << "()" @@ -561,9 +573,9 @@ void DownloadManager::DownloadCancelledInternal(DownloadItem* download) { download->OffThreadCancel(file_manager_); } -void DownloadManager::OnDownloadInterrupted(int32 download_id, - int64 size, - InterruptReason reason) { +void DownloadManagerImpl::OnDownloadInterrupted(int32 download_id, + int64 size, + InterruptReason reason) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DownloadItem* download = GetActiveDownload(download_id); @@ -581,7 +593,7 @@ void DownloadManager::OnDownloadInterrupted(int32 download_id, download->OffThreadCancel(file_manager_); } -DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) { +DownloadItem* DownloadManagerImpl::GetActiveDownload(int32 download_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DownloadMap::iterator it = active_downloads_.find(download_id); if (it == active_downloads_.end()) @@ -595,7 +607,7 @@ DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) { return download; } -void DownloadManager::RemoveFromActiveList(DownloadItem* download) { +void DownloadManagerImpl::RemoveFromActiveList(DownloadItem* download) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(download); @@ -609,16 +621,20 @@ void DownloadManager::RemoveFromActiveList(DownloadItem* download) { } } -void DownloadManager::SetDownloadManagerDelegate( +content::DownloadManagerDelegate* DownloadManagerImpl::delegate() const { + return delegate_; +} + +void DownloadManagerImpl::SetDownloadManagerDelegate( content::DownloadManagerDelegate* delegate) { delegate_ = delegate; } -void DownloadManager::UpdateDownloadProgress() { +void DownloadManagerImpl::UpdateDownloadProgress() { delegate_->DownloadProgressUpdated(); } -int DownloadManager::RemoveDownloadItems( +int DownloadManagerImpl::RemoveDownloadItems( const DownloadVector& pending_deletes) { if (pending_deletes.empty()) return 0; @@ -643,7 +659,7 @@ int DownloadManager::RemoveDownloadItems( return num_deleted; } -void DownloadManager::RemoveDownload(int64 download_handle) { +void DownloadManagerImpl::RemoveDownload(int64 download_handle) { DownloadMap::iterator it = history_downloads_.find(download_handle); if (it == history_downloads_.end()) return; @@ -657,8 +673,8 @@ void DownloadManager::RemoveDownload(int64 download_handle) { DCHECK_EQ(1, downloads_count); } -int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, - const base::Time remove_end) { +int DownloadManagerImpl::RemoveDownloadsBetween(const base::Time remove_begin, + const base::Time remove_end) { delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end); // All downloads visible to the user will be in the history, @@ -678,11 +694,11 @@ int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, return RemoveDownloadItems(pending_deletes); } -int DownloadManager::RemoveDownloads(const base::Time remove_begin) { +int DownloadManagerImpl::RemoveDownloads(const base::Time remove_begin) { return RemoveDownloadsBetween(remove_begin, base::Time()); } -int DownloadManager::RemoveAllDownloads() { +int DownloadManagerImpl::RemoveAllDownloads() { download_stats::RecordClearAllSize(history_downloads_.size()); // The null times make the date range unbounded. return RemoveDownloadsBetween(base::Time(), base::Time()); @@ -691,19 +707,19 @@ int DownloadManager::RemoveAllDownloads() { // Initiate a download of a specific URL. We send the request to the // ResourceDispatcherHost, and let it send us responses like a regular // download. -void DownloadManager::DownloadUrl(const GURL& url, - const GURL& referrer, - const std::string& referrer_charset, - TabContents* tab_contents) { +void DownloadManagerImpl::DownloadUrl(const GURL& url, + const GURL& referrer, + const std::string& referrer_charset, + TabContents* tab_contents) { DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(), tab_contents); } -void DownloadManager::DownloadUrlToFile(const GURL& url, - const GURL& referrer, - const std::string& referrer_charset, - const DownloadSaveInfo& save_info, - TabContents* tab_contents) { +void DownloadManagerImpl::DownloadUrlToFile(const GURL& url, + const GURL& referrer, + const std::string& referrer_charset, + const DownloadSaveInfo& save_info, + TabContents* tab_contents) { DCHECK(tab_contents); ResourceDispatcherHost* resource_dispatcher_host = content::GetContentClient()->browser()->GetResourceDispatcherHost(); @@ -719,16 +735,16 @@ void DownloadManager::DownloadUrlToFile(const GURL& url, &tab_contents->browser_context()->GetResourceContext())); } -void DownloadManager::AddObserver(Observer* observer) { +void DownloadManagerImpl::AddObserver(Observer* observer) { observers_.AddObserver(observer); observer->ModelChanged(); } -void DownloadManager::RemoveObserver(Observer* observer) { +void DownloadManagerImpl::RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); } -bool DownloadManager::IsDownloadProgressKnown() const { +bool DownloadManagerImpl::IsDownloadProgressKnown() const { for (DownloadMap::const_iterator i = in_progress_.begin(); i != in_progress_.end(); ++i) { if (i->second->total_bytes() <= 0) @@ -738,11 +754,11 @@ bool DownloadManager::IsDownloadProgressKnown() const { return true; } -int64 DownloadManager::GetInProgressDownloadCount() const { +int64 DownloadManagerImpl::GetInProgressDownloadCount() const { return in_progress_.size(); } -int64 DownloadManager::GetReceivedDownloadBytes() const { +int64 DownloadManagerImpl::GetReceivedDownloadBytes() const { DCHECK(IsDownloadProgressKnown()); int64 received_bytes = 0; for (DownloadMap::const_iterator i = in_progress_.begin(); @@ -752,7 +768,7 @@ int64 DownloadManager::GetReceivedDownloadBytes() const { return received_bytes; } -int64 DownloadManager::GetTotalDownloadBytes() const { +int64 DownloadManagerImpl::GetTotalDownloadBytes() const { DCHECK(IsDownloadProgressKnown()); int64 total_bytes = 0; for (DownloadMap::const_iterator i = in_progress_.begin(); @@ -762,7 +778,7 @@ int64 DownloadManager::GetTotalDownloadBytes() const { return total_bytes; } -void DownloadManager::FileSelected(const FilePath& path, void* params) { +void DownloadManagerImpl::FileSelected(const FilePath& path, void* params) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); int32* id_ptr = reinterpret_cast<int32*>(params); @@ -783,7 +799,7 @@ void DownloadManager::FileSelected(const FilePath& path, void* params) { ContinueDownloadWithPath(download, path); } -void DownloadManager::FileSelectionCanceled(void* params) { +void DownloadManagerImpl::FileSelectionCanceled(void* params) { // The user didn't pick a place to save the file, so need to cancel the // download that's already in progress to the temporary location. DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -811,7 +827,7 @@ void DownloadManager::FileSelectionCanceled(void* params) { // The history service has retrieved all download entries. 'entries' contains // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). -void DownloadManager::OnPersistentStoreQueryComplete( +void DownloadManagerImpl::OnPersistentStoreQueryComplete( std::vector<DownloadPersistentStoreInfo>* entries) { // TODO(rdsmith): Remove this and related logic when // http://crbug.com/85408 is fixed. @@ -833,8 +849,8 @@ void DownloadManager::OnPersistentStoreQueryComplete( CheckForHistoryFilesRemoval(); } -void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, - int64 db_handle) { +void DownloadManagerImpl::AddDownloadItemToHistory(DownloadItem* download, + int64 db_handle) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/85408 @@ -860,8 +876,8 @@ void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, } -void DownloadManager::OnItemAddedToPersistentStore(int32 download_id, - int64 db_handle) { +void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id, + int64 db_handle) { if (save_page_downloads_.count(download_id)) { OnSavePageItemAddedToPersistentStore(download_id, db_handle); } else if (active_downloads_.count(download_id)) { @@ -873,8 +889,8 @@ void DownloadManager::OnItemAddedToPersistentStore(int32 download_id, // Once the new DownloadItem's creation info has been committed to the history // service, we associate the DownloadItem with the db handle, update our // 'history_downloads_' map and inform observers. -void DownloadManager::OnDownloadItemAddedToPersistentStore(int32 download_id, - int64 db_handle) { +void DownloadManagerImpl::OnDownloadItemAddedToPersistentStore( + int32 download_id, int64 db_handle) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DownloadItem* download = GetActiveDownloadItem(download_id); if (!download) @@ -917,7 +933,7 @@ void DownloadManager::OnDownloadItemAddedToPersistentStore(int32 download_id, } } -void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { +void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItem* download) { // The 'contents' may no longer exist if the user closed the tab before we // get this start completion event. TabContents* content = download->GetTabContents(); @@ -931,16 +947,20 @@ void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { content->OnStartDownload(download); } +int DownloadManagerImpl::InProgressCount() const { + return static_cast<int>(in_progress_.size()); +} + // Clears the last download path, used to initialize "save as" dialogs. -void DownloadManager::ClearLastDownloadPath() { +void DownloadManagerImpl::ClearLastDownloadPath() { last_download_path_ = FilePath(); } -void DownloadManager::NotifyModelChanged() { +void DownloadManagerImpl::NotifyModelChanged() { FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); } -DownloadItem* DownloadManager::GetDownloadItem(int download_id) { +DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) { // The |history_downloads_| map is indexed by the download's db_handle, // not its id, so we have to iterate. for (DownloadMap::iterator it = history_downloads_.begin(); @@ -952,7 +972,7 @@ DownloadItem* DownloadManager::GetDownloadItem(int download_id) { return NULL; } -DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) { +DownloadItem* DownloadManagerImpl::GetActiveDownloadItem(int download_id) { DCHECK(ContainsKey(active_downloads_, download_id)); DownloadItem* download = active_downloads_[download_id]; DCHECK(download != NULL); @@ -961,7 +981,7 @@ DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) { // Confirm that everything in all maps is also in |downloads_|, and that // everything in |downloads_| is also in some other map. -void DownloadManager::AssertContainersConsistent() const { +void DownloadManagerImpl::AssertContainersConsistent() const { #if !defined(NDEBUG) // Turn everything into sets. const DownloadMap* input_maps[] = {&active_downloads_, @@ -1004,7 +1024,7 @@ void DownloadManager::AssertContainersConsistent() const { #endif } -void DownloadManager::SavePageDownloadStarted(DownloadItem* download) { +void DownloadManagerImpl::SavePageDownloadStarted(DownloadItem* download) { DCHECK(!ContainsKey(save_page_downloads_, download->id())); downloads_.insert(download); save_page_downloads_[download->id()] = download; @@ -1028,8 +1048,8 @@ void DownloadManager::SavePageDownloadStarted(DownloadItem* download) { // Initiation -> History Callback -> Removal -> Completion), but there's no way // to solve that without canceling on Remove (which would then update the DB). -void DownloadManager::OnSavePageItemAddedToPersistentStore(int32 download_id, - int64 db_handle) { +void DownloadManagerImpl::OnSavePageItemAddedToPersistentStore( + int32 download_id, int64 db_handle) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DownloadMap::const_iterator it = save_page_downloads_.find(download_id); @@ -1056,7 +1076,7 @@ void DownloadManager::OnSavePageItemAddedToPersistentStore(int32 download_id, SavePageDownloadFinished(download); } -void DownloadManager::SavePageDownloadFinished(DownloadItem* download) { +void DownloadManagerImpl::SavePageDownloadFinished(DownloadItem* download) { if (download->db_handle() != DownloadItem::kUninitializedHandle) { delegate_->UpdateItemInPersistentStore(download); DCHECK(ContainsKey(save_page_downloads_, download->id())); @@ -1070,7 +1090,7 @@ void DownloadManager::SavePageDownloadFinished(DownloadItem* download) { } } -void DownloadManager::MarkDownloadOpened(DownloadItem* download) { +void DownloadManagerImpl::MarkDownloadOpened(DownloadItem* download) { delegate_->UpdateItemInPersistentStore(download); int num_unopened = 0; for (DownloadMap::iterator it = history_downloads_.begin(); @@ -1080,3 +1100,7 @@ void DownloadManager::MarkDownloadOpened(DownloadItem* download) { } download_stats::RecordOpensOutstanding(num_unopened); } + +void DownloadManagerImpl::SetFileManager(DownloadFileManager* file_manager) { + file_manager_ = file_manager; +} diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h new file mode 100755 index 0000000..d020c55 --- /dev/null +++ b/content/browser/download/download_manager_impl.h @@ -0,0 +1,248 @@ +// Copyright (c) 2011 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. +// + +#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_IMPL_H_ +#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_IMPL_H_ +#pragma once + +#include "content/browser/download/download_manager.h" + +#include <map> +#include <set> + +#include "base/hash_tables.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/synchronization/lock.h" +#include "content/browser/download/download_status_updater_delegate.h" +#include "content/common/content_export.h" + +class DownloadIdFactory; +class DownloadStatusUpdater; + +class CONTENT_EXPORT DownloadManagerImpl + : public DownloadManager, + public DownloadStatusUpdaterDelegate { + public: + DownloadManagerImpl(content::DownloadManagerDelegate* delegate, + DownloadIdFactory* id_factory, + DownloadStatusUpdater* status_updater); + + // DownloadManager functions. + virtual void Shutdown() OVERRIDE; + virtual void GetTemporaryDownloads(const FilePath& dir_path, + DownloadVector* result) OVERRIDE; + virtual void GetAllDownloads(const FilePath& dir_path, + DownloadVector* result) OVERRIDE; + virtual void SearchDownloads(const string16& query, + DownloadVector* result) OVERRIDE; + virtual bool Init(content::BrowserContext* browser_context) OVERRIDE; + virtual void StartDownload(int32 id) OVERRIDE; + virtual void UpdateDownload(int32 download_id, int64 size) OVERRIDE; + virtual void OnResponseCompleted(int32 download_id, int64 size, + const std::string& hash) OVERRIDE; + virtual void CancelDownload(int32 download_id) OVERRIDE; + virtual void OnDownloadInterrupted(int32 download_id, int64 size, + InterruptReason reason) OVERRIDE; + virtual void DownloadCancelledInternal(DownloadItem* download) OVERRIDE; + virtual void RemoveDownload(int64 download_handle) OVERRIDE; + virtual bool IsDownloadReadyForCompletion(DownloadItem* download) OVERRIDE; + virtual void MaybeCompleteDownload(DownloadItem* download) OVERRIDE; + virtual void OnDownloadRenamedToFinalName(int download_id, + const FilePath& full_path, + int uniquifier) OVERRIDE; + virtual int RemoveDownloadsBetween(const base::Time remove_begin, + const base::Time remove_end) OVERRIDE; + virtual int RemoveDownloads(const base::Time remove_begin) OVERRIDE; + virtual int RemoveAllDownloads() OVERRIDE; + virtual void DownloadCompleted(int32 download_id) OVERRIDE; + virtual void DownloadUrl(const GURL& url, + const GURL& referrer, + const std::string& referrer_encoding, + TabContents* tab_contents) OVERRIDE; + virtual void DownloadUrlToFile(const GURL& url, + const GURL& referrer, + const std::string& referrer_encoding, + const DownloadSaveInfo& save_info, + TabContents* tab_contents) OVERRIDE; + virtual void AddObserver(Observer* observer) OVERRIDE; + virtual void RemoveObserver(Observer* observer) OVERRIDE; + virtual void OnPersistentStoreQueryComplete( + std::vector<DownloadPersistentStoreInfo>* entries) OVERRIDE; + virtual void OnItemAddedToPersistentStore(int32 download_id, + int64 db_handle) OVERRIDE; + virtual void ShowDownloadInBrowser(DownloadItem* download) OVERRIDE; + virtual int InProgressCount() const OVERRIDE; + virtual content::BrowserContext* BrowserContext() OVERRIDE; + virtual FilePath LastDownloadPath() OVERRIDE; + virtual void CreateDownloadItem( + DownloadCreateInfo* info, + const DownloadRequestHandle& request_handle) OVERRIDE; + virtual void ClearLastDownloadPath() OVERRIDE; + virtual void FileSelected(const FilePath& path, void* params) OVERRIDE; + virtual void FileSelectionCanceled(void* params) OVERRIDE; + virtual void RestartDownload(int32 download_id) OVERRIDE; + virtual void MarkDownloadOpened(DownloadItem* download) OVERRIDE; + virtual void CheckForHistoryFilesRemoval() OVERRIDE; + virtual void CheckForFileRemoval(DownloadItem* download_item) OVERRIDE; + virtual void AssertQueueStateConsistent(DownloadItem* download) OVERRIDE; + virtual DownloadItem* GetDownloadItem(int id) OVERRIDE; + virtual void SavePageDownloadStarted(DownloadItem* download) OVERRIDE; + virtual void SavePageDownloadFinished(DownloadItem* download) OVERRIDE; + virtual DownloadItem* GetActiveDownloadItem(int id) OVERRIDE; + virtual content::DownloadManagerDelegate* delegate() const OVERRIDE; + virtual void SetDownloadManagerDelegate( + content::DownloadManagerDelegate* delegate) OVERRIDE; + virtual DownloadId GetNextId() OVERRIDE; + + // Overridden from DownloadStatusUpdaterDelegate: + virtual bool IsDownloadProgressKnown() const OVERRIDE; + virtual int64 GetInProgressDownloadCount() const OVERRIDE; + virtual int64 GetReceivedDownloadBytes() const OVERRIDE; + virtual int64 GetTotalDownloadBytes() const OVERRIDE; + + private: + typedef std::set<DownloadItem*> DownloadSet; + typedef base::hash_map<int64, DownloadItem*> DownloadMap; + + // For testing. + friend class DownloadManagerTest; + friend class DownloadTest; + friend class MockDownloadManager; + + friend class base::RefCountedThreadSafe< + DownloadManagerImpl, content::BrowserThread::DeleteOnUIThread>; + friend struct content::BrowserThread::DeleteOnThread< + content::BrowserThread::UI>; + friend class DeleteTask<DownloadManagerImpl>; + + virtual ~DownloadManagerImpl(); + + // Called on the FILE thread to check the existence of a downloaded file. + void CheckForFileRemovalOnFileThread(int64 db_handle, const FilePath& path); + + // Called on the UI thread if the FILE thread detects the removal of + // the downloaded file. The UI thread updates the state of the file + // and then notifies this update to the file's observer. + void OnFileRemovalDetected(int64 db_handle); + + // 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. + virtual void ContinueDownloadWithPath(DownloadItem* download, + const FilePath& chosen_file) OVERRIDE; + + // Retrieves the download from the |download_id|. + // Returns NULL if the download is not active. + virtual DownloadItem* GetActiveDownload(int32 download_id) OVERRIDE; + + // Removes |download| from the active and in progress maps. + // Called when the download is cancelled or has an error. + // Does nothing if the download is not in the history DB. + void RemoveFromActiveList(DownloadItem* download); + + // Updates the delegate about the overall download progress. + void UpdateDownloadProgress(); + + // Inform observers that the model has changed. + void NotifyModelChanged(); + + // Debugging routine to confirm relationship between below + // containers; no-op if NDEBUG. + void AssertContainersConsistent() const; + + // Add a DownloadItem to history_downloads_. + void AddDownloadItemToHistory(DownloadItem* item, int64 db_handle); + + // Remove from internal maps. + int RemoveDownloadItems(const DownloadVector& pending_deletes); + + // Called when a download entry is committed to the persistent store. + void OnDownloadItemAddedToPersistentStore(int32 download_id, int64 db_handle); + + // Called when Save Page As entry is committed to the persistent store. + void OnSavePageItemAddedToPersistentStore(int32 download_id, int64 db_handle); + + // For unit tests only. + virtual void SetFileManager(DownloadFileManager* file_manager) OVERRIDE; + + // |downloads_| is the owning set for all downloads known to the + // DownloadManager. This includes downloads started by the user in + // this session, downloads initialized from the history system, and + // "save page as" downloads. All other DownloadItem containers in + // the DownloadManager are maps; they do not own the DownloadItems. + // Note that this is the only place (with any functional implications; + // see save_page_downloads_ below) that "save page as" downloads are + // kept, as the DownloadManager's only job is to hold onto those + // until destruction. + // + // |history_downloads_| is map of all downloads in this browser context. The + // key is the handle returned by the history system, which is unique across + // sessions. + // + // |active_downloads_| is a map of all downloads that are currently being + // processed. The key is the ID assigned by the DownloadFileManager, + // which is unique for the current session. + // + // |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 + // DownloadFileManager, which is unique for the current session. + // + // |save_page_downloads_| (if defined) is a collection of all the + // downloads the "save page as" system has given to us to hold onto + // until we are destroyed. They key is DownloadFileManager, so it is unique + // compared to download item. It is only used for debugging. + // + // When a download is created through a user action, the corresponding + // DownloadItem* is placed in |active_downloads_| and remains there until the + // download is in a terminal state (COMPLETE or CANCELLED). It is also + // 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 |history_downloads_| map. When the + // download reaches a terminal state, it is removed from |in_progress_|. + // Downloads from past sessions read from a persisted state from the + // history system are placed directly into |history_downloads_| since + // they have valid handles in the history system. + + DownloadSet downloads_; + DownloadMap history_downloads_; + DownloadMap in_progress_; + DownloadMap active_downloads_; + DownloadMap save_page_downloads_; + + // 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 browser context. + content::BrowserContext* browser_context_; + + // Non-owning pointer for handling file writing on the download_thread_. + DownloadFileManager* file_manager_; + + // Non-owning pointer for updating the download status. + base::WeakPtr<DownloadStatusUpdater> status_updater_; + + // 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. + FilePath last_download_path_; + + // Allows an embedder to control behavior. Guaranteed to outlive this object. + content::DownloadManagerDelegate* delegate_; + + DownloadIdFactory* id_factory_; + + // TODO(rdsmith): Remove when http://crbug.com/85408 is fixed. + // For debugging only. + int64 largest_db_handle_in_history_; + + DISALLOW_COPY_AND_ASSIGN(DownloadManagerImpl); +}; + +#endif // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_IMPL_H_ diff --git a/content/browser/download/mock_download_manager.cc b/content/browser/download/mock_download_manager.cc new file mode 100755 index 0000000..40d7728 --- /dev/null +++ b/content/browser/download/mock_download_manager.cc @@ -0,0 +1,226 @@ +// Copyright (c) 2011 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. + +#include "content/browser/download/mock_download_manager.h" + +#include "content/browser/download/download_create_info.h" + +MockDownloadManager::MockDownloadManager( + content::DownloadManagerDelegate* delegate, + DownloadIdFactory* id_factory, + DownloadStatusUpdater* updater) + : delegate_(delegate), id_factory_(id_factory), updater_(updater), + file_manager_(NULL) { +} + +MockDownloadManager::~MockDownloadManager() { + for (std::map<int32, DownloadItem*>::iterator it = item_map_.begin(); + it != item_map_.end(); + ++it) { + delete it->second; + } + for (std::map<int32, DownloadItem*>::iterator it = inactive_item_map_.begin(); + it != inactive_item_map_.end(); + ++it) { + delete it->second; + } +} + +void MockDownloadManager::Shutdown() { +} + +void MockDownloadManager::GetTemporaryDownloads(const FilePath& dir_path, + DownloadVector* result) { +} + +void MockDownloadManager::GetAllDownloads(const FilePath& dir_path, + DownloadVector* result) { +} + +void MockDownloadManager::SearchDownloads(const string16& query, + DownloadVector* result) { +} + +bool MockDownloadManager::Init(content::BrowserContext* browser_context) { + return true; +} + +void MockDownloadManager::StartDownload(int32 id) { +} + +void MockDownloadManager::UpdateDownload(int32 download_id, int64 size) { +} + +void MockDownloadManager::OnResponseCompleted(int32 download_id, int64 size, + const std::string& hash) { +} + +void MockDownloadManager::CancelDownload(int32 download_id) { +} + +void MockDownloadManager::OnDownloadInterrupted(int32 download_id, int64 size, + InterruptReason reason) { +} + +void MockDownloadManager::DownloadCancelledInternal(DownloadItem* download) { + download->Cancel(true); + item_map_.erase(download->id()); + inactive_item_map_[download->id()] = download; +} + +void MockDownloadManager::RemoveDownload(int64 download_handle) { +} + +bool MockDownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { + return download->all_data_saved(); +} + +void MockDownloadManager::MaybeCompleteDownload(DownloadItem* download) { + if (IsDownloadReadyForCompletion(download)) + download->OnDownloadRenamedToFinalName(download->full_path()); +} + +void MockDownloadManager::OnDownloadRenamedToFinalName( + int download_id, + const FilePath& full_path, + int uniquifier) { +} + +int MockDownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, + const base::Time remove_end) { + return 0; +} + +int MockDownloadManager::RemoveDownloads(const base::Time remove_begin) { + return 0; +} + +int MockDownloadManager::RemoveAllDownloads() { + return 1; +} + +void MockDownloadManager::DownloadCompleted(int32 download_id) { +} + +void MockDownloadManager::DownloadUrl(const GURL& url, + const GURL& referrer, + const std::string& referrer_encoding, + TabContents* tab_contents) { +} + +void MockDownloadManager::DownloadUrlToFile( + const GURL& url, + const GURL& referrer, + const std::string& referrer_encoding, + const DownloadSaveInfo& save_info, + TabContents* tab_contents) { +} + +void MockDownloadManager::AddObserver(Observer* observer) { +} + +void MockDownloadManager::RemoveObserver(Observer* observer) { +} + +void MockDownloadManager::OnPersistentStoreQueryComplete( + std::vector<DownloadPersistentStoreInfo>* entries) { +} + +void MockDownloadManager::OnItemAddedToPersistentStore(int32 download_id, + int64 db_handle) { +} + +void MockDownloadManager::ShowDownloadInBrowser(DownloadItem* download) { +} + +int MockDownloadManager::InProgressCount() const { + return 1; +} + +content::BrowserContext* MockDownloadManager::BrowserContext() { + return NULL; +} + +FilePath MockDownloadManager::LastDownloadPath() { + return FilePath(); +} + +void MockDownloadManager::CreateDownloadItem( + DownloadCreateInfo* info, + const DownloadRequestHandle& request_handle) { + item_map_.insert(std::make_pair( + info->download_id.local(), + new DownloadItem(this, + *info, + new DownloadRequestHandle(request_handle), + false))); +} + +void MockDownloadManager::ClearLastDownloadPath() { +} + +void MockDownloadManager::FileSelected(const FilePath& path, void* params) { +} + +void MockDownloadManager::FileSelectionCanceled(void* params) { +} + +void MockDownloadManager::RestartDownload(int32 download_id) { +} + +void MockDownloadManager::MarkDownloadOpened(DownloadItem* download) { + download->set_open_when_complete(true); +} + +void MockDownloadManager::CheckForHistoryFilesRemoval() { +} + +void MockDownloadManager::CheckForFileRemoval(DownloadItem* download_item) { +} + +void MockDownloadManager::AssertQueueStateConsistent(DownloadItem* download) { +} + +DownloadItem* MockDownloadManager::GetDownloadItem(int id) { + std::map<int32, DownloadItem*>::iterator it = item_map_.find(id); + if (it == item_map_.end()) + return NULL; + return it->second; +} + +void MockDownloadManager::SavePageDownloadStarted(DownloadItem* download) { +} + +void MockDownloadManager::SavePageDownloadFinished(DownloadItem* download) { +} + +DownloadItem* MockDownloadManager::GetActiveDownloadItem(int id) { + return GetDownloadItem(id); +} + +content::DownloadManagerDelegate* MockDownloadManager::delegate() const { + return delegate_; +} + +void MockDownloadManager::SetDownloadManagerDelegate( + content::DownloadManagerDelegate* delegate) { +} + +DownloadId MockDownloadManager::GetNextId() { + return DownloadId(this, 1); +} + +void MockDownloadManager::ContinueDownloadWithPath( + DownloadItem* download, + const FilePath& chosen_file) { + download->Rename(chosen_file); +} + +DownloadItem* MockDownloadManager::GetActiveDownload(int32 download_id) { + return GetDownloadItem(download_id); +} + +void MockDownloadManager::SetFileManager(DownloadFileManager* file_manager) { + file_manager_ = file_manager; +} diff --git a/content/browser/download/mock_download_manager.h b/content/browser/download/mock_download_manager.h index 98f8480..8c8ce14 100644 --- a/content/browser/download/mock_download_manager.h +++ b/content/browser/download/mock_download_manager.h @@ -7,6 +7,8 @@ #pragma once #include "content/browser/download/download_manager.h" +#include "content/browser/download/download_id.h" +#include "content/browser/download/download_id_factory.h" class DownloadStatusUpdater; class DownloadItem; @@ -15,12 +17,87 @@ class MockDownloadManager : public DownloadManager { public: explicit MockDownloadManager(content::DownloadManagerDelegate* delegate, DownloadIdFactory* id_factory, - DownloadStatusUpdater* updater) - : DownloadManager(delegate, id_factory, updater) { - } + DownloadStatusUpdater* updater); + virtual ~MockDownloadManager(); - // Override some functions. - virtual void UpdateHistoryForDownload(DownloadItem*) { } + // DownloadManager: + virtual void Shutdown() OVERRIDE; + virtual void GetTemporaryDownloads(const FilePath& dir_path, + DownloadVector* result) OVERRIDE; + virtual void GetAllDownloads(const FilePath& dir_path, + DownloadVector* result) OVERRIDE; + virtual void SearchDownloads(const string16& query, + DownloadVector* result) OVERRIDE; + virtual bool Init(content::BrowserContext* browser_context) OVERRIDE; + virtual void StartDownload(int32 id) OVERRIDE; + virtual void UpdateDownload(int32 download_id, int64 size) OVERRIDE; + virtual void OnResponseCompleted(int32 download_id, int64 size, + const std::string& hash) OVERRIDE; + virtual void CancelDownload(int32 download_id) OVERRIDE; + virtual void OnDownloadInterrupted(int32 download_id, int64 size, + InterruptReason reason) OVERRIDE; + virtual void DownloadCancelledInternal(DownloadItem* download) OVERRIDE; + virtual void RemoveDownload(int64 download_handle) OVERRIDE; + virtual bool IsDownloadReadyForCompletion(DownloadItem* download) OVERRIDE; + virtual void MaybeCompleteDownload(DownloadItem* download) OVERRIDE; + virtual void OnDownloadRenamedToFinalName(int download_id, + const FilePath& full_path, + int uniquifier) OVERRIDE; + virtual int RemoveDownloadsBetween(const base::Time remove_begin, + const base::Time remove_end) OVERRIDE; + virtual int RemoveDownloads(const base::Time remove_begin) OVERRIDE; + virtual int RemoveAllDownloads() OVERRIDE; + virtual void DownloadCompleted(int32 download_id) OVERRIDE; + virtual void DownloadUrl(const GURL& url, + const GURL& referrer, + const std::string& referrer_encoding, + TabContents* tab_contents) OVERRIDE; + virtual void DownloadUrlToFile(const GURL& url, + const GURL& referrer, + const std::string& referrer_encoding, + const DownloadSaveInfo& save_info, + TabContents* tab_contents) OVERRIDE; + virtual void AddObserver(Observer* observer) OVERRIDE; + virtual void RemoveObserver(Observer* observer) OVERRIDE; + virtual void OnPersistentStoreQueryComplete( + std::vector<DownloadPersistentStoreInfo>* entries) OVERRIDE; + virtual void OnItemAddedToPersistentStore(int32 download_id, + int64 db_handle) OVERRIDE; + virtual void ShowDownloadInBrowser(DownloadItem* download) OVERRIDE; + virtual int InProgressCount() const OVERRIDE; + virtual content::BrowserContext* BrowserContext() OVERRIDE; + virtual FilePath LastDownloadPath() OVERRIDE; + virtual void CreateDownloadItem( + DownloadCreateInfo* info, + const DownloadRequestHandle& request_handle) OVERRIDE; + virtual void ClearLastDownloadPath() OVERRIDE; + virtual void FileSelected(const FilePath& path, void* params) OVERRIDE; + virtual void FileSelectionCanceled(void* params) OVERRIDE; + virtual void RestartDownload(int32 download_id) OVERRIDE; + virtual void MarkDownloadOpened(DownloadItem* download) OVERRIDE; + virtual void CheckForHistoryFilesRemoval() OVERRIDE; + virtual void CheckForFileRemoval(DownloadItem* download_item) OVERRIDE; + virtual void AssertQueueStateConsistent(DownloadItem* download) OVERRIDE; + virtual DownloadItem* GetDownloadItem(int id) OVERRIDE; + virtual void SavePageDownloadStarted(DownloadItem* download) OVERRIDE; + virtual void SavePageDownloadFinished(DownloadItem* download) OVERRIDE; + virtual DownloadItem* GetActiveDownloadItem(int id) OVERRIDE; + virtual content::DownloadManagerDelegate* delegate() const OVERRIDE; + virtual void SetDownloadManagerDelegate( + content::DownloadManagerDelegate* delegate) OVERRIDE; + virtual DownloadId GetNextId() OVERRIDE; + virtual void ContinueDownloadWithPath(DownloadItem* download, + const FilePath& chosen_file) OVERRIDE; + virtual DownloadItem* GetActiveDownload(int32 download_id) OVERRIDE; + virtual void SetFileManager(DownloadFileManager* file_manager) OVERRIDE; + + private: + content::DownloadManagerDelegate* delegate_; + DownloadIdFactory* id_factory_; + DownloadStatusUpdater* updater_; + DownloadFileManager* file_manager_; + std::map<int32, DownloadItem*> item_map_; + std::map<int32, DownloadItem*> inactive_item_map_; }; #endif // CONTENT_BROWSER_DOWNLOAD_MOCK_DOWNLOAD_MANAGER_H_ |