diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-29 19:35:51 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-29 19:35:51 +0000 |
commit | 98d6f15ea3252f51d69c4cf4451361d2f14558b1 (patch) | |
tree | 4b32f0bf50c4b823cbc77ed092f7f3e7d0900f70 /content | |
parent | 888c72cb43a2ccba5b806aa83bae4f2c889a3eaf (diff) | |
download | chromium_src-98d6f15ea3252f51d69c4cf4451361d2f14558b1.zip chromium_src-98d6f15ea3252f51d69c4cf4451361d2f14558b1.tar.gz chromium_src-98d6f15ea3252f51d69c4cf4451361d2f14558b1.tar.bz2 |
Add a content_shell specific DownloadManagerDelegate.
Also fix a race condition that existed in resource dispatching but was never tickled by Chrome. The problem is if in BufferedResourceHandler::OnReadCompleted(), CompleteResponseStarted calls the next handler's OnResponseStarted. If that pauses the request, then the next handler's OnReadCompleted() would still get called which is not correct.
BUG=90445
Review URL: http://codereview.chromium.org/8065019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103331 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/renderer_host/buffered_resource_handler.cc | 6 | ||||
-rw-r--r-- | content/content_shell.gypi | 2 | ||||
-rw-r--r-- | content/shell/shell_browser_context.cc | 10 | ||||
-rw-r--r-- | content/shell/shell_browser_context.h | 3 | ||||
-rw-r--r-- | content/shell/shell_browser_main.cc | 4 | ||||
-rw-r--r-- | content/shell/shell_download_manager_delegate.cc | 167 | ||||
-rw-r--r-- | content/shell/shell_download_manager_delegate.h | 75 | ||||
-rw-r--r-- | content/shell/shell_resource_context.cc | 7 | ||||
-rw-r--r-- | content/shell/shell_resource_context.h | 8 |
9 files changed, 273 insertions, 9 deletions
diff --git a/content/browser/renderer_host/buffered_resource_handler.cc b/content/browser/renderer_host/buffered_resource_handler.cc index 0cfbc10..9002bfc 100644 --- a/content/browser/renderer_host/buffered_resource_handler.cc +++ b/content/browser/renderer_host/buffered_resource_handler.cc @@ -145,6 +145,12 @@ bool BufferedResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { // Done buffering, send the pending ResponseStarted event. if (!CompleteResponseStarted(request_id, true)) return false; + + // The next handler might have paused the request in OnResponseStarted. + ResourceDispatcherHostRequestInfo* info = + ResourceDispatcherHost::InfoForRequest(request_); + if (info->pause_count()) + return true; } else if (wait_for_plugins_) { return true; } diff --git a/content/content_shell.gypi b/content/content_shell.gypi index 2314f67..71b1ecf 100644 --- a/content/content_shell.gypi +++ b/content/content_shell.gypi @@ -51,6 +51,8 @@ 'shell/shell_content_renderer_client.h', 'shell/shell_content_utility_client.cc', 'shell/shell_content_utility_client.h', + 'shell/shell_download_manager_delegate.cc', + 'shell/shell_download_manager_delegate.h', 'shell/shell_main.cc', 'shell/shell_resource_context.cc', 'shell/shell_resource_context.h', diff --git a/content/shell/shell_browser_context.cc b/content/shell/shell_browser_context.cc index 33d88f9..11e0475 100644 --- a/content/shell/shell_browser_context.cc +++ b/content/shell/shell_browser_context.cc @@ -12,7 +12,6 @@ #include "content/browser/chrome_blob_storage_context.h" #include "content/browser/download/download_manager.h" #include "content/browser/download/download_status_updater.h" -#include "content/browser/download/mock_download_manager_delegate.h" #include "content/browser/file_system/browser_file_system_helper.h" #include "content/browser/geolocation/geolocation_permission_context.h" #include "content/browser/host_zoom_map.h" @@ -20,6 +19,7 @@ #include "content/browser/ssl/ssl_host_state.h" #include "content/browser/speech/speech_input_preferences.h" #include "content/shell/shell_browser_main.h" +#include "content/shell/shell_download_manager_delegate.h" #include "content/shell/shell_resource_context.h" #include "content/shell/shell_url_request_context_getter.h" #include "webkit/database/database_tracker.h" @@ -121,9 +121,10 @@ DownloadManager* ShellBrowserContext::GetDownloadManager() { if (!download_manager_.get()) { download_status_updater_.reset(new DownloadStatusUpdater()); - download_manager_delegate_.reset(new MockDownloadManagerDelegate()); - download_manager_ = new DownloadManager(download_manager_delegate_.get(), + download_manager_delegate_ = new ShellDownloadManagerDelegate(); + download_manager_ = new DownloadManager(download_manager_delegate_, download_status_updater_.get()); + download_manager_delegate_->SetDownloadManager(download_manager_.get()); download_manager_->Init(this); } return download_manager_.get(); @@ -158,7 +159,8 @@ const ResourceContext& ShellBrowserContext::GetResourceContext() { if (!resource_context_.get()) { resource_context_.reset(new ShellResourceContext( static_cast<ShellURLRequestContextGetter*>(GetRequestContext()), - GetBlobStorageContext())); + GetBlobStorageContext(), + GetDownloadManager()->GetNextIdThunk())); } return *resource_context_.get(); } diff --git a/content/shell/shell_browser_context.h b/content/shell/shell_browser_context.h index 7de6528..fc9f26e 100644 --- a/content/shell/shell_browser_context.h +++ b/content/shell/shell_browser_context.h @@ -23,6 +23,7 @@ namespace content { class ResourceContext; class ShellBrowserMainParts; +class ShellDownloadManagerDelegate; class ShellBrowserContext : public BrowserContext { public: @@ -59,7 +60,7 @@ class ShellBrowserContext : public BrowserContext { scoped_ptr<ResourceContext> resource_context_; scoped_ptr<SSLHostState> ssl_host_state_; scoped_ptr<DownloadStatusUpdater> download_status_updater_; - scoped_ptr<DownloadManagerDelegate> download_manager_delegate_; + scoped_refptr<ShellDownloadManagerDelegate> download_manager_delegate_; scoped_refptr<DownloadManager> download_manager_; scoped_refptr<net::URLRequestContextGetter> url_request_getter_; scoped_refptr<HostZoomMap> host_zoom_map_; diff --git a/content/shell/shell_browser_main.cc b/content/shell/shell_browser_main.cc index 73176a8..8ac87d3 100644 --- a/content/shell/shell_browser_main.cc +++ b/content/shell/shell_browser_main.cc @@ -8,6 +8,8 @@ #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" #include "content/browser/browser_process_sub_thread.h" +#include "content/browser/download/download_file_manager.h" +#include "content/browser/download/save_file_manager.h" #include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/common/page_transition_types.h" #include "content/shell/shell.h" @@ -35,6 +37,8 @@ ShellBrowserMainParts::~ShellBrowserMainParts() { browser_context_.reset(); + resource_dispatcher_host_->download_file_manager()->Shutdown(); + resource_dispatcher_host_->save_file_manager()->Shutdown(); resource_dispatcher_host_->Shutdown(); io_thread_.reset(); cache_thread_.reset(); diff --git a/content/shell/shell_download_manager_delegate.cc b/content/shell/shell_download_manager_delegate.cc new file mode 100644 index 0000000..47b3c80 --- /dev/null +++ b/content/shell/shell_download_manager_delegate.cc @@ -0,0 +1,167 @@ +// 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/shell/shell_download_manager_delegate.h" + +#include "base/bind.h" +#include "base/file_util.h" +#include "base/utf_string_conversions.h" +#include "content/browser/browser_context.h" +#include "content/browser/browser_thread.h" +#include "content/browser/download/download_manager.h" +#include "content/browser/download/download_state_info.h" +#include "net/base/net_util.h" + +namespace content { + +ShellDownloadManagerDelegate::ShellDownloadManagerDelegate() + : download_manager_(NULL) { +} + +ShellDownloadManagerDelegate::~ShellDownloadManagerDelegate(){ +} + + +void ShellDownloadManagerDelegate::SetDownloadManager( + DownloadManager* download_manager) { + download_manager_ = download_manager; +} + +void ShellDownloadManagerDelegate::Shutdown() { +} + +bool ShellDownloadManagerDelegate::ShouldStartDownload(int32 download_id) { + DownloadItem* download = + download_manager_->GetActiveDownloadItem(download_id); + DownloadStateInfo state = download->state_info(); + + if (!state.force_file_name.empty()) + return true; + + FilePath generated_name = net::GenerateFileName( + download->GetURL(), + download->content_disposition(), + download->referrer_charset(), + download->suggested_filename(), + download->mime_type(), + string16(UTF8ToUTF16("download"))); + + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + base::Bind( + &ShellDownloadManagerDelegate::GenerateFilename, + this, download_id, state, generated_name)); + return false; +} + +void ShellDownloadManagerDelegate::GenerateFilename( + int32 download_id, + DownloadStateInfo state, + const FilePath& generated_name) { + if (state.suggested_path.empty()) { + state.suggested_path = download_manager_->browser_context()->GetPath(). + Append(FILE_PATH_LITERAL("Downloads")); + if (!file_util::PathExists(state.suggested_path)) + file_util::CreateDirectory(state.suggested_path); + } + + state.suggested_path = state.suggested_path.Append(generated_name); + + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind( + &ShellDownloadManagerDelegate::RestartDownload, + this, download_id, state)); +} + +void ShellDownloadManagerDelegate::RestartDownload( + int32 download_id, + DownloadStateInfo state) { + DownloadItem* download = + download_manager_->GetActiveDownloadItem(download_id); + if (!download) + return; + download->SetFileCheckResults(state); + download_manager_->RestartDownload(download_id); +} + +void ShellDownloadManagerDelegate::ChooseDownloadPath( + TabContents* tab_contents, + const FilePath& suggested_path, + void* data) { +} + +bool ShellDownloadManagerDelegate::OverrideIntermediatePath( + DownloadItem* item, + FilePath* intermediate_path) { + return false; +} + +TabContents* ShellDownloadManagerDelegate:: + GetAlternativeTabContentsToNotifyForDownload() { + return NULL; +} + +bool ShellDownloadManagerDelegate::ShouldOpenFileBasedOnExtension( + const FilePath& path) { + return false; +} + +bool ShellDownloadManagerDelegate::ShouldOpenDownload(DownloadItem* item) { + return true; +} + +bool ShellDownloadManagerDelegate::ShouldCompleteDownload(DownloadItem* item) { + return true; +} + +bool ShellDownloadManagerDelegate::GenerateFileHash() { + return false; +} + +void ShellDownloadManagerDelegate::OnResponseCompleted( + DownloadItem* item, + const std::string& hash) { +} + +void ShellDownloadManagerDelegate::AddItemToPersistentStore( + DownloadItem* item) { +} + +void ShellDownloadManagerDelegate::UpdateItemInPersistentStore( + DownloadItem* item) { +} + +void ShellDownloadManagerDelegate::UpdatePathForItemInPersistentStore( + DownloadItem* item, + const FilePath& new_path) { +} + +void ShellDownloadManagerDelegate::RemoveItemFromPersistentStore( + DownloadItem* item) { +} + +void ShellDownloadManagerDelegate::RemoveItemsFromPersistentStoreBetween( + const base::Time remove_begin, + const base::Time remove_end) { +} + +void ShellDownloadManagerDelegate::GetSaveDir( + TabContents* tab_contents, + FilePath* website_save_dir, + FilePath* download_save_dir) { +} + +void ShellDownloadManagerDelegate::ChooseSavePath( + const base::WeakPtr<SavePackage>& save_package, + const FilePath& suggested_path, + bool can_save_as_complete) { +} + +void ShellDownloadManagerDelegate::DownloadProgressUpdated() { +} + +} // namespace content diff --git a/content/shell/shell_download_manager_delegate.h b/content/shell/shell_download_manager_delegate.h new file mode 100644 index 0000000..56baf55 --- /dev/null +++ b/content/shell/shell_download_manager_delegate.h @@ -0,0 +1,75 @@ +// 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_SHELL_SHELL_DOWNLOAD_MANAGER_DELEGATE_H_ +#define CONTENT_SHELL_SHELL_DOWNLOAD_MANAGER_DELEGATE_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "content/browser/download/download_manager_delegate.h" + +class DownloadManager; +struct DownloadStateInfo; + +namespace content { + +class ShellDownloadManagerDelegate + : public DownloadManagerDelegate, + public base::RefCountedThreadSafe<ShellDownloadManagerDelegate> { + public: + ShellDownloadManagerDelegate(); + + void SetDownloadManager(DownloadManager* download_manager); + + virtual void Shutdown() OVERRIDE; + virtual bool ShouldStartDownload(int32 download_id) OVERRIDE; + virtual void ChooseDownloadPath(TabContents* tab_contents, + const FilePath& suggested_path, + void* data) OVERRIDE; + virtual bool OverrideIntermediatePath(DownloadItem* item, + FilePath* intermediate_path) OVERRIDE; + virtual TabContents* GetAlternativeTabContentsToNotifyForDownload() OVERRIDE; + virtual bool ShouldOpenFileBasedOnExtension(const FilePath& path) OVERRIDE; + virtual bool ShouldOpenDownload(DownloadItem* item) OVERRIDE; + virtual bool ShouldCompleteDownload(DownloadItem* item) OVERRIDE; + virtual bool GenerateFileHash() OVERRIDE; + virtual void OnResponseCompleted(DownloadItem* item, + const std::string& hash) OVERRIDE; + virtual void AddItemToPersistentStore(DownloadItem* item) OVERRIDE; + virtual void UpdateItemInPersistentStore(DownloadItem* item) OVERRIDE; + virtual void UpdatePathForItemInPersistentStore( + DownloadItem* item, + const FilePath& new_path) OVERRIDE; + virtual void RemoveItemFromPersistentStore(DownloadItem* item) OVERRIDE; + virtual void RemoveItemsFromPersistentStoreBetween( + const base::Time remove_begin, + const base::Time remove_end) OVERRIDE; + virtual void GetSaveDir(TabContents* tab_contents, + FilePath* website_save_dir, + FilePath* download_save_dir) OVERRIDE; + virtual void ChooseSavePath(const base::WeakPtr<SavePackage>& save_package, + const FilePath& suggested_path, + bool can_save_as_complete) OVERRIDE; + virtual void DownloadProgressUpdated() OVERRIDE; + + private: + friend class base::RefCountedThreadSafe<ShellDownloadManagerDelegate>; + + virtual ~ShellDownloadManagerDelegate(); + + void GenerateFilename(int32 download_id, + DownloadStateInfo state, + const FilePath& generated_name); + void RestartDownload(int32 download_id, + DownloadStateInfo state); + + DownloadManager* download_manager_; + + DISALLOW_COPY_AND_ASSIGN(ShellDownloadManagerDelegate); +}; + +} // namespace content + +#endif // CONTENT_SHELL_SHELL_DOWNLOAD_MANAGER_DELEGATE_H_ diff --git a/content/shell/shell_resource_context.cc b/content/shell/shell_resource_context.cc index fa725cf..5058992 100644 --- a/content/shell/shell_resource_context.cc +++ b/content/shell/shell_resource_context.cc @@ -11,9 +11,11 @@ namespace content { ShellResourceContext::ShellResourceContext( ShellURLRequestContextGetter* getter, - ChromeBlobStorageContext* blob_storage_context) + ChromeBlobStorageContext* blob_storage_context, + DownloadManager::GetNextIdThunkType next_download_id_thunk) : getter_(getter), - blob_storage_context_(blob_storage_context) { + blob_storage_context_(blob_storage_context), + next_download_id_thunk_(next_download_id_thunk) { } ShellResourceContext::~ShellResourceContext() { @@ -27,6 +29,7 @@ void ShellResourceContext::InitializeInternal() { set_request_context(getter_->GetURLRequestContext()); set_host_resolver(getter_->host_resolver()); set_blob_storage_context(blob_storage_context_); + set_next_download_id_thunk(next_download_id_thunk_); } } // namespace content diff --git a/content/shell/shell_resource_context.h b/content/shell/shell_resource_context.h index a05eb40..bafb05b 100644 --- a/content/shell/shell_resource_context.h +++ b/content/shell/shell_resource_context.h @@ -8,6 +8,7 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" +#include "content/browser/download/download_manager.h" #include "content/browser/resource_context.h" class ChromeBlobStorageContext; @@ -18,8 +19,10 @@ class ShellURLRequestContextGetter; class ShellResourceContext : public content::ResourceContext { public: - ShellResourceContext(ShellURLRequestContextGetter* getter, - ChromeBlobStorageContext* blob_storage_context); + ShellResourceContext( + ShellURLRequestContextGetter* getter, + ChromeBlobStorageContext* blob_storage_context, + DownloadManager::GetNextIdThunkType next_download_id_thunk); virtual ~ShellResourceContext(); private: @@ -29,6 +32,7 @@ class ShellResourceContext : public content::ResourceContext { scoped_refptr<ShellURLRequestContextGetter> getter_; scoped_refptr<ChromeBlobStorageContext> blob_storage_context_; + DownloadManager::GetNextIdThunkType next_download_id_thunk_; DISALLOW_COPY_AND_ASSIGN(ShellResourceContext); }; |