Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/download/download_manager_impl.h" | 5 #include "content/browser/download/download_manager_impl.h" |
| 6 | 6 |
| 7 #include <iterator> | 7 #include <iterator> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 #include "content/browser/download/download_stats.h" | 23 #include "content/browser/download/download_stats.h" |
| 24 #include "content/browser/renderer_host/render_view_host_impl.h" | 24 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 25 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" | 25 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" |
| 26 #include "content/browser/web_contents/web_contents_impl.h" | 26 #include "content/browser/web_contents/web_contents_impl.h" |
| 27 #include "content/public/browser/browser_context.h" | 27 #include "content/public/browser/browser_context.h" |
| 28 #include "content/public/browser/browser_thread.h" | 28 #include "content/public/browser/browser_thread.h" |
| 29 #include "content/public/browser/content_browser_client.h" | 29 #include "content/public/browser/content_browser_client.h" |
| 30 #include "content/public/browser/download_interrupt_reasons.h" | 30 #include "content/public/browser/download_interrupt_reasons.h" |
| 31 #include "content/public/browser/download_manager_delegate.h" | 31 #include "content/public/browser/download_manager_delegate.h" |
| 32 #include "content/public/browser/download_persistent_store_info.h" | 32 #include "content/public/browser/download_persistent_store_info.h" |
| 33 #include "content/public/browser/download_url_parameters.h" | |
| 33 #include "content/public/browser/notification_service.h" | 34 #include "content/public/browser/notification_service.h" |
| 34 #include "content/public/browser/notification_types.h" | 35 #include "content/public/browser/notification_types.h" |
| 35 #include "content/public/browser/render_process_host.h" | 36 #include "content/public/browser/render_process_host.h" |
| 36 #include "content/public/browser/web_contents_delegate.h" | 37 #include "content/public/browser/web_contents_delegate.h" |
| 38 #include "net/base/load_flags.h" | |
| 37 #include "net/base/upload_data.h" | 39 #include "net/base/upload_data.h" |
| 38 | 40 |
| 39 // TODO(benjhayden): Change this to DCHECK when we have more debugging | 41 // TODO(benjhayden): Change this to DCHECK when we have more debugging |
| 40 // information from the next dev cycle, before the next stable/beta branch is | 42 // information from the next dev cycle, before the next stable/beta branch is |
| 41 // cut, in order to prevent unnecessary crashes on those channels. If we still | 43 // cut, in order to prevent unnecessary crashes on those channels. If we still |
| 42 // don't have root cause before the dev cycle after the next stable/beta | 44 // don't have root cause before the dev cycle after the next stable/beta |
| 43 // releases, uncomment it out to re-enable debugging checks. Whenever this macro | 45 // releases, uncomment it out to re-enable debugging checks. Whenever this macro |
| 44 // is toggled, the corresponding macro in download_database.cc should also | 46 // is toggled, the corresponding macro in download_database.cc should also |
| 45 // be toggled. When 96627 is fixed, this macro and all its usages can be | 47 // be toggled. When 96627 is fixed, this macro and all its usages can be |
| 46 // deleted or permanently changed to DCHECK as appropriate. | 48 // deleted or permanently changed to DCHECK as appropriate. |
| 47 #define CHECK_96627 CHECK | 49 #define CHECK_96627 CHECK |
| 48 | 50 |
| 49 using content::BrowserThread; | 51 using content::BrowserThread; |
| 50 using content::DownloadId; | 52 using content::DownloadId; |
| 51 using content::DownloadItem; | 53 using content::DownloadItem; |
| 52 using content::DownloadPersistentStoreInfo; | 54 using content::DownloadPersistentStoreInfo; |
| 53 using content::ResourceDispatcherHostImpl; | 55 using content::ResourceDispatcherHostImpl; |
| 54 using content::WebContents; | 56 using content::WebContents; |
| 55 | 57 |
| 56 namespace { | 58 namespace { |
| 57 | 59 |
| 58 // Param structs exist because base::Bind can only handle 6 args. | 60 void BeginDownload(content::DownloadUrlParameters* params) { |
| 59 struct URLParams { | 61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 60 URLParams(const GURL& url, const GURL& referrer, int64 post_id, bool cache) | 62 scoped_ptr<net::URLRequest> request(new net::URLRequest( |
| 61 : url_(url), referrer_(referrer), post_id_(post_id), prefer_cache_(cache) {} | 63 params->url(), params->resource_dispatcher_host())); |
| 62 GURL url_; | 64 request->set_referrer(params->referrer().spec()); |
| 63 GURL referrer_; | 65 request->set_load_flags(request->load_flags() | params->load_flags()); |
| 64 int64 post_id_; | 66 request->set_method(params->method()); |
| 65 bool prefer_cache_; | 67 if (!params->post_body().empty()) |
| 66 }; | 68 request->AppendBytesToUpload(params->post_body().data(), |
| 67 | 69 params->post_body().size()); |
| 68 struct RenderParams { | 70 if (params->post_id() >= 0) { |
| 69 RenderParams(int rpi, int rvi) | |
| 70 : render_process_id_(rpi), render_view_id_(rvi) {} | |
| 71 int render_process_id_; | |
| 72 int render_view_id_; | |
| 73 }; | |
| 74 | |
| 75 void BeginDownload( | |
| 76 const URLParams& url_params, | |
| 77 const content::DownloadSaveInfo& save_info, | |
| 78 ResourceDispatcherHostImpl* resource_dispatcher_host, | |
| 79 const RenderParams& render_params, | |
| 80 content::ResourceContext* context, | |
| 81 const content::DownloadManager::OnStartedCallback& callback) { | |
| 82 scoped_ptr<net::URLRequest> request( | |
| 83 new net::URLRequest(url_params.url_, resource_dispatcher_host)); | |
| 84 request->set_referrer(url_params.referrer_.spec()); | |
| 85 if (url_params.post_id_ >= 0) { | |
| 86 // The POST in this case does not have an actual body, and only works | 71 // The POST in this case does not have an actual body, and only works |
| 87 // when retrieving data from cache. This is done because we don't want | 72 // when retrieving data from cache. This is done because we don't want |
| 88 // to do a re-POST without user consent, and currently don't have a good | 73 // to do a re-POST without user consent, and currently don't have a good |
| 89 // plan on how to display the UI for that. | 74 // plan on how to display the UI for that. |
| 90 DCHECK(url_params.prefer_cache_); | 75 DCHECK(params->prefer_cache()); |
| 91 request->set_method("POST"); | 76 DCHECK(params->method() == "POST"); |
| 92 scoped_refptr<net::UploadData> upload_data = new net::UploadData(); | 77 scoped_refptr<net::UploadData> upload_data = new net::UploadData(); |
| 93 upload_data->set_identifier(url_params.post_id_); | 78 upload_data->set_identifier(params->post_id()); |
| 94 request->set_upload(upload_data); | 79 request->set_upload(upload_data); |
| 95 } | 80 } |
| 96 resource_dispatcher_host->BeginDownload( | 81 for (content::DownloadUrlParameters::RequestHeadersType::const_iterator iter |
| 82 = params->request_headers_begin(); | |
| 83 iter != params->request_headers_end(); | |
| 84 ++iter) { | |
| 85 request->SetExtraRequestHeaderByName( | |
| 86 iter->first, iter->second, false/*overwrite*/); | |
| 87 } | |
| 88 params->resource_dispatcher_host()->BeginDownload( | |
| 97 request.Pass(), | 89 request.Pass(), |
| 98 context, | 90 params->resource_context(), |
| 99 render_params.render_process_id_, | 91 params->render_process_host_id(), |
| 100 render_params.render_view_id_, | 92 params->render_view_host_routing_id(), |
| 101 url_params.prefer_cache_, | 93 params->prefer_cache(), |
| 102 save_info, | 94 params->save_info(), |
| 103 callback); | 95 params->callback()); |
| 104 } | 96 } |
| 105 | 97 |
| 106 class MapValueIteratorAdapter { | 98 class MapValueIteratorAdapter { |
| 107 public: | 99 public: |
| 108 explicit MapValueIteratorAdapter( | 100 explicit MapValueIteratorAdapter( |
| 109 base::hash_map<int64, DownloadItem*>::const_iterator iter) | 101 base::hash_map<int64, DownloadItem*>::const_iterator iter) |
| 110 : iter_(iter) { | 102 : iter_(iter) { |
| 111 } | 103 } |
| 112 ~MapValueIteratorAdapter() {} | 104 ~MapValueIteratorAdapter() {} |
| 113 | 105 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 141 BrowserThread::PostTask( | 133 BrowserThread::PostTask( |
| 142 BrowserThread::FILE, FROM_HERE, | 134 BrowserThread::FILE, FROM_HERE, |
| 143 base::Bind(&EnsureNoPendingDownloadsOnFile, | 135 base::Bind(&EnsureNoPendingDownloadsOnFile, |
| 144 download_file_manager, result)); | 136 download_file_manager, result)); |
| 145 } | 137 } |
| 146 | 138 |
| 147 } // namespace | 139 } // namespace |
| 148 | 140 |
| 149 namespace content { | 141 namespace content { |
| 150 | 142 |
| 143 DownloadUrlParameters::DownloadUrlParameters( | |
|
jam
2012/05/02 20:05:30
the DownloadUrlParameters construtors belong in c
benjhayden
2012/05/02 20:56:46
Done.
| |
| 144 const GURL& url, | |
| 145 int render_process_host_id, | |
| 146 int render_view_host_routing_id, | |
| 147 content::ResourceContext* resource_context, | |
| 148 const content::DownloadSaveInfo& save_info) | |
| 149 : load_flags_(0), | |
| 150 method_("GET"), | |
| 151 post_id_(-1), | |
| 152 prefer_cache_(false), | |
| 153 render_process_host_id_(render_process_host_id), | |
| 154 render_view_host_routing_id_(render_view_host_routing_id), | |
| 155 resource_context_(resource_context), | |
| 156 resource_dispatcher_host_(ResourceDispatcherHostImpl::Get()), | |
| 157 save_info_(save_info), | |
| 158 url_(url) { | |
| 159 DCHECK(resource_dispatcher_host_); | |
| 160 } | |
| 161 | |
| 162 DownloadUrlParameters::~DownloadUrlParameters() { | |
| 163 } | |
| 164 | |
| 165 // static | |
| 166 DownloadUrlParameters* DownloadUrlParameters::FromWebContents( | |
| 167 WebContents* web_contents, | |
| 168 const GURL& url, | |
| 169 const content::DownloadSaveInfo& save_info) { | |
| 170 return new DownloadUrlParameters( | |
| 171 url, | |
| 172 web_contents->GetRenderProcessHost()->GetID(), | |
| 173 web_contents->GetRenderViewHost()->GetRoutingID(), | |
| 174 web_contents->GetBrowserContext()->GetResourceContext(), | |
| 175 save_info); | |
| 176 } | |
| 177 | |
| 178 | |
| 151 // static | 179 // static |
| 152 DownloadManager* DownloadManager::Create( | 180 DownloadManager* DownloadManager::Create( |
| 153 content::DownloadManagerDelegate* delegate, | 181 content::DownloadManagerDelegate* delegate, |
| 154 net::NetLog* net_log) { | 182 net::NetLog* net_log) { |
| 155 return new DownloadManagerImpl(delegate, net_log); | 183 return new DownloadManagerImpl(delegate, net_log); |
| 156 } | 184 } |
| 157 | 185 |
| 158 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { | 186 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { |
| 159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 160 bool result = true; | 188 bool result = true; |
| (...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 843 int DownloadManagerImpl::RemoveDownloads(base::Time remove_begin) { | 871 int DownloadManagerImpl::RemoveDownloads(base::Time remove_begin) { |
| 844 return RemoveDownloadsBetween(remove_begin, base::Time()); | 872 return RemoveDownloadsBetween(remove_begin, base::Time()); |
| 845 } | 873 } |
| 846 | 874 |
| 847 int DownloadManagerImpl::RemoveAllDownloads() { | 875 int DownloadManagerImpl::RemoveAllDownloads() { |
| 848 download_stats::RecordClearAllSize(history_downloads_.size()); | 876 download_stats::RecordClearAllSize(history_downloads_.size()); |
| 849 // The null times make the date range unbounded. | 877 // The null times make the date range unbounded. |
| 850 return RemoveDownloadsBetween(base::Time(), base::Time()); | 878 return RemoveDownloadsBetween(base::Time(), base::Time()); |
| 851 } | 879 } |
| 852 | 880 |
| 853 // Initiate a download of a specific URL. We send the request to the | |
| 854 // ResourceDispatcherHost, and let it send us responses like a regular | |
| 855 // download. | |
| 856 void DownloadManagerImpl::DownloadUrl( | 881 void DownloadManagerImpl::DownloadUrl( |
| 857 const GURL& url, | 882 scoped_ptr<content::DownloadUrlParameters> parameters) { |
| 858 const GURL& referrer, | 883 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
| 859 const std::string& referrer_charset, | 884 &BeginDownload, base::Owned(parameters.release()))); |
| 860 bool prefer_cache, | |
| 861 int64 post_id, | |
| 862 const content::DownloadSaveInfo& save_info, | |
| 863 WebContents* web_contents, | |
| 864 const OnStartedCallback& callback) { | |
| 865 ResourceDispatcherHostImpl* resource_dispatcher_host = | |
| 866 ResourceDispatcherHostImpl::Get(); | |
| 867 DCHECK(resource_dispatcher_host); | |
| 868 | |
| 869 // We send a pointer to content::ResourceContext, instead of the usual | |
| 870 // reference, so that a copy of the object isn't made. | |
| 871 // base::Bind can't handle 7 args, so we use URLParams and RenderParams. | |
| 872 BrowserThread::PostTask( | |
| 873 BrowserThread::IO, FROM_HERE, | |
| 874 base::Bind( | |
| 875 &BeginDownload, | |
| 876 URLParams(url, referrer, post_id, prefer_cache), | |
| 877 save_info, | |
| 878 resource_dispatcher_host, | |
| 879 RenderParams(web_contents->GetRenderProcessHost()->GetID(), | |
| 880 web_contents->GetRenderViewHost()->GetRoutingID()), | |
| 881 web_contents->GetBrowserContext()->GetResourceContext(), | |
| 882 callback)); | |
| 883 } | 885 } |
| 884 | 886 |
| 885 void DownloadManagerImpl::AddObserver(Observer* observer) { | 887 void DownloadManagerImpl::AddObserver(Observer* observer) { |
| 886 observers_.AddObserver(observer); | 888 observers_.AddObserver(observer); |
| 887 // TODO: It is the responsibility of the observers to query the | 889 // TODO: It is the responsibility of the observers to query the |
| 888 // DownloadManager. Remove the following call from here and update all | 890 // DownloadManager. Remove the following call from here and update all |
| 889 // observers. | 891 // observers. |
| 890 observer->ModelChanged(this); | 892 observer->ModelChanged(this); |
| 891 } | 893 } |
| 892 | 894 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1208 if (it->second->IsComplete() && !it->second->GetOpened()) | 1210 if (it->second->IsComplete() && !it->second->GetOpened()) |
| 1209 ++num_unopened; | 1211 ++num_unopened; |
| 1210 } | 1212 } |
| 1211 download_stats::RecordOpensOutstanding(num_unopened); | 1213 download_stats::RecordOpensOutstanding(num_unopened); |
| 1212 } | 1214 } |
| 1213 | 1215 |
| 1214 void DownloadManagerImpl::SetFileManagerForTesting( | 1216 void DownloadManagerImpl::SetFileManagerForTesting( |
| 1215 DownloadFileManager* file_manager) { | 1217 DownloadFileManager* file_manager) { |
| 1216 file_manager_ = file_manager; | 1218 file_manager_ = file_manager; |
| 1217 } | 1219 } |
| OLD | NEW |