| 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" |
| 11 #include "base/debug/alias.h" | 11 #include "base/debug/alias.h" |
| 12 #include "base/i18n/case_conversion.h" | 12 #include "base/i18n/case_conversion.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
| 15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 17 #include "base/strings/sys_string_conversions.h" | 17 #include "base/strings/sys_string_conversions.h" |
| 18 #include "base/supports_user_data.h" | 18 #include "base/supports_user_data.h" |
| 19 #include "base/synchronization/lock.h" | 19 #include "base/synchronization/lock.h" |
| 20 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 21 #include "content/browser/byte_stream.h" | 21 #include "content/browser/byte_stream.h" |
| 22 #include "content/browser/download/download_create_info.h" | 22 #include "content/browser/download/download_create_info.h" |
| 23 #include "content/browser/download/download_file_factory.h" | 23 #include "content/browser/download/download_file_factory.h" |
| 24 #include "content/browser/download/download_item_factory.h" | 24 #include "content/browser/download/download_item_factory.h" |
| 25 #include "content/browser/download/download_item_impl.h" | 25 #include "content/browser/download/download_item_impl.h" |
| 26 #include "content/browser/download/download_stats.h" | 26 #include "content/browser/download/download_stats.h" |
| 27 #include "content/browser/download/url_downloader.h" |
| 27 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 28 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| 28 #include "content/browser/renderer_host/render_view_host_impl.h" | 29 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 29 #include "content/browser/web_contents/web_contents_impl.h" | 30 #include "content/browser/web_contents/web_contents_impl.h" |
| 30 #include "content/public/browser/browser_context.h" | 31 #include "content/public/browser/browser_context.h" |
| 31 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
| 32 #include "content/public/browser/content_browser_client.h" | 33 #include "content/public/browser/content_browser_client.h" |
| 33 #include "content/public/browser/download_interrupt_reasons.h" | 34 #include "content/public/browser/download_interrupt_reasons.h" |
| 34 #include "content/public/browser/download_manager_delegate.h" | 35 #include "content/public/browser/download_manager_delegate.h" |
| 35 #include "content/public/browser/download_url_parameters.h" | 36 #include "content/public/browser/download_url_parameters.h" |
| 36 #include "content/public/browser/notification_service.h" | 37 #include "content/public/browser/notification_service.h" |
| 37 #include "content/public/browser/notification_types.h" | 38 #include "content/public/browser/notification_types.h" |
| 38 #include "content/public/browser/render_process_host.h" | 39 #include "content/public/browser/render_process_host.h" |
| 39 #include "content/public/browser/resource_context.h" | 40 #include "content/public/browser/resource_context.h" |
| 40 #include "content/public/browser/web_contents_delegate.h" | 41 #include "content/public/browser/web_contents_delegate.h" |
| 41 #include "content/public/common/referrer.h" | 42 #include "content/public/common/referrer.h" |
| 42 #include "net/base/load_flags.h" | 43 #include "net/base/load_flags.h" |
| 43 #include "net/base/upload_bytes_element_reader.h" | 44 #include "net/base/upload_bytes_element_reader.h" |
| 44 #include "net/base/upload_data_stream.h" | 45 #include "net/base/upload_data_stream.h" |
| 45 #include "net/url_request/url_request_context.h" | 46 #include "net/url_request/url_request_context.h" |
| 46 | 47 |
| 47 namespace content { | 48 namespace content { |
| 48 namespace { | 49 namespace { |
| 49 | 50 |
| 50 void BeginDownload(scoped_ptr<DownloadUrlParameters> params, | |
| 51 uint32 download_id) { | |
| 52 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 53 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and | |
| 54 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so | |
| 55 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. | |
| 56 scoped_ptr<net::URLRequest> request( | |
| 57 params->resource_context()->GetRequestContext()->CreateRequest( | |
| 58 params->url(), NULL)); | |
| 59 request->set_load_flags(request->load_flags() | params->load_flags()); | |
| 60 request->set_method(params->method()); | |
| 61 if (!params->post_body().empty()) { | |
| 62 const std::string& body = params->post_body(); | |
| 63 scoped_ptr<net::UploadElementReader> reader( | |
| 64 net::UploadOwnedBytesElementReader::CreateWithString(body)); | |
| 65 request->set_upload(make_scoped_ptr( | |
| 66 net::UploadDataStream::CreateWithReader(reader.Pass(), 0))); | |
| 67 } | |
| 68 if (params->post_id() >= 0) { | |
| 69 // The POST in this case does not have an actual body, and only works | |
| 70 // when retrieving data from cache. This is done because we don't want | |
| 71 // to do a re-POST without user consent, and currently don't have a good | |
| 72 // plan on how to display the UI for that. | |
| 73 DCHECK(params->prefer_cache()); | |
| 74 DCHECK(params->method() == "POST"); | |
| 75 ScopedVector<net::UploadElementReader> element_readers; | |
| 76 request->set_upload(make_scoped_ptr( | |
| 77 new net::UploadDataStream(&element_readers, params->post_id()))); | |
| 78 } | |
| 79 | |
| 80 // If we're not at the beginning of the file, retrieve only the remaining | |
| 81 // portion. | |
| 82 bool has_last_modified = !params->last_modified().empty(); | |
| 83 bool has_etag = !params->etag().empty(); | |
| 84 | |
| 85 // If we've asked for a range, we want to make sure that we only | |
| 86 // get that range if our current copy of the information is good. | |
| 87 // We shouldn't be asked to continue if we don't have a verifier. | |
| 88 DCHECK(params->offset() == 0 || has_etag || has_last_modified); | |
| 89 | |
| 90 if (params->offset() > 0) { | |
| 91 request->SetExtraRequestHeaderByName( | |
| 92 "Range", | |
| 93 base::StringPrintf("bytes=%" PRId64 "-", params->offset()), | |
| 94 true); | |
| 95 | |
| 96 if (has_last_modified) { | |
| 97 request->SetExtraRequestHeaderByName("If-Unmodified-Since", | |
| 98 params->last_modified(), | |
| 99 true); | |
| 100 } | |
| 101 if (has_etag) { | |
| 102 request->SetExtraRequestHeaderByName("If-Match", params->etag(), true); | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 for (DownloadUrlParameters::RequestHeadersType::const_iterator iter | |
| 107 = params->request_headers_begin(); | |
| 108 iter != params->request_headers_end(); | |
| 109 ++iter) { | |
| 110 request->SetExtraRequestHeaderByName( | |
| 111 iter->first, iter->second, false/*overwrite*/); | |
| 112 } | |
| 113 | |
| 114 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo()); | |
| 115 save_info->file_path = params->file_path(); | |
| 116 save_info->suggested_name = params->suggested_name(); | |
| 117 save_info->offset = params->offset(); | |
| 118 save_info->hash_state = params->hash_state(); | |
| 119 save_info->prompt_for_save_location = params->prompt(); | |
| 120 save_info->file_stream = params->GetFileStream(); | |
| 121 | |
| 122 ResourceDispatcherHost::Get()->BeginDownload( | |
| 123 request.Pass(), | |
| 124 params->referrer(), | |
| 125 params->content_initiated(), | |
| 126 params->resource_context(), | |
| 127 params->render_process_host_id(), | |
| 128 params->render_view_host_routing_id(), | |
| 129 params->prefer_cache(), | |
| 130 save_info.Pass(), | |
| 131 download_id, | |
| 132 params->callback()); | |
| 133 } | |
| 134 | |
| 135 class MapValueIteratorAdapter { | 51 class MapValueIteratorAdapter { |
| 136 public: | 52 public: |
| 137 explicit MapValueIteratorAdapter( | 53 explicit MapValueIteratorAdapter( |
| 138 base::hash_map<int64, DownloadItem*>::const_iterator iter) | 54 base::hash_map<int64, DownloadItem*>::const_iterator iter) |
| 139 : iter_(iter) { | 55 : iter_(iter) { |
| 140 } | 56 } |
| 141 ~MapValueIteratorAdapter() {} | 57 ~MapValueIteratorAdapter() {} |
| 142 | 58 |
| 143 DownloadItem* operator*() { return iter_->second; } | 59 DownloadItem* operator*() { return iter_->second; } |
| 144 | 60 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 bound_net_log); | 122 bound_net_log); |
| 207 } | 123 } |
| 208 | 124 |
| 209 virtual DownloadItemImpl* CreateActiveItem( | 125 virtual DownloadItemImpl* CreateActiveItem( |
| 210 DownloadItemImplDelegate* delegate, | 126 DownloadItemImplDelegate* delegate, |
| 211 uint32 download_id, | 127 uint32 download_id, |
| 212 const DownloadCreateInfo& info, | 128 const DownloadCreateInfo& info, |
| 213 const net::BoundNetLog& bound_net_log) OVERRIDE { | 129 const net::BoundNetLog& bound_net_log) OVERRIDE { |
| 214 return new DownloadItemImpl(delegate, download_id, info, bound_net_log); | 130 return new DownloadItemImpl(delegate, download_id, info, bound_net_log); |
| 215 } | 131 } |
| 216 | |
| 217 virtual DownloadItemImpl* CreateSavePageItem( | |
| 218 DownloadItemImplDelegate* delegate, | |
| 219 uint32 download_id, | |
| 220 const base::FilePath& path, | |
| 221 const GURL& url, | |
| 222 const std::string& mime_type, | |
| 223 scoped_ptr<DownloadRequestHandleInterface> request_handle, | |
| 224 const net::BoundNetLog& bound_net_log) OVERRIDE { | |
| 225 return new DownloadItemImpl(delegate, download_id, path, url, | |
| 226 mime_type, request_handle.Pass(), | |
| 227 bound_net_log); | |
| 228 } | |
| 229 }; | 132 }; |
| 230 | 133 |
| 231 } // namespace | 134 } // namespace |
| 232 | 135 |
| 233 DownloadManagerImpl::DownloadManagerImpl( | 136 DownloadManagerImpl::DownloadManagerImpl( |
| 234 net::NetLog* net_log, | 137 net::NetLog* net_log, |
| 235 BrowserContext* browser_context) | 138 BrowserContext* browser_context) |
| 236 : item_factory_(new DownloadItemFactoryImpl()), | 139 : item_factory_(new DownloadItemFactoryImpl()), |
| 237 file_factory_(new DownloadFileFactory()), | 140 file_factory_(new DownloadFileFactory()), |
| 238 history_size_(0), | 141 history_size_(0), |
| 239 shutdown_needed_(true), | 142 shutdown_needed_(true), |
| 240 browser_context_(browser_context), | 143 browser_context_(browser_context), |
| 241 delegate_(NULL), | 144 delegate_(NULL), |
| 242 net_log_(net_log), | 145 net_log_(net_log), |
| 243 weak_factory_(this) { | 146 weak_factory_(this) { |
| 244 DCHECK(browser_context); | 147 DCHECK(browser_context); |
| 245 } | 148 } |
| 246 | 149 |
| 247 DownloadManagerImpl::~DownloadManagerImpl() { | 150 DownloadManagerImpl::~DownloadManagerImpl() { |
| 248 DCHECK(!shutdown_needed_); | 151 DCHECK(!shutdown_needed_); |
| 249 } | 152 } |
| 250 | 153 |
| 251 DownloadItemImpl* DownloadManagerImpl::CreateActiveItem( | 154 DownloadItemImpl* DownloadManagerImpl::CreateActiveItem( |
| 252 uint32 id, const DownloadCreateInfo& info) { | 155 uint32 id, |
| 156 const DownloadCreateInfo& info) { |
| 253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 254 DCHECK(!ContainsKey(downloads_, id)); | 158 DCHECK(!ContainsKey(downloads_, id)); |
| 255 net::BoundNetLog bound_net_log = | 159 net::BoundNetLog bound_net_log = |
| 256 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 160 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
| 257 DownloadItemImpl* download = | 161 DownloadItemImpl* download = |
| 258 item_factory_->CreateActiveItem(this, id, info, bound_net_log); | 162 item_factory_->CreateActiveItem(this, id, info, bound_net_log); |
| 259 downloads_[id] = download; | 163 downloads_[id] = download; |
| 260 return download; | 164 return download; |
| 261 } | 165 } |
| 262 | 166 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 downloads_.clear(); | 253 downloads_.clear(); |
| 350 | 254 |
| 351 // We'll have nothing more to report to the observers after this point. | 255 // We'll have nothing more to report to the observers after this point. |
| 352 observers_.Clear(); | 256 observers_.Clear(); |
| 353 | 257 |
| 354 if (delegate_) | 258 if (delegate_) |
| 355 delegate_->Shutdown(); | 259 delegate_->Shutdown(); |
| 356 delegate_ = NULL; | 260 delegate_ = NULL; |
| 357 } | 261 } |
| 358 | 262 |
| 359 void DownloadManagerImpl::StartDownload( | 263 void DownloadManagerImpl::StartDownloadWithActiveRequest( |
| 360 scoped_ptr<DownloadCreateInfo> info, | 264 scoped_ptr<DownloadRequestHandle> request_handle, |
| 361 scoped_ptr<ByteStreamReader> stream, | 265 scoped_ptr<DownloadCreateInfo> info) { |
| 362 const DownloadUrlParameters::OnStartedCallback& on_started) { | |
| 363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 364 DCHECK(info); | 267 DCHECK(info); |
| 365 uint32 download_id = info->download_id; | 268 GetNextId(base::Bind(&DownloadManagerImpl::StartDownloadWithId, |
| 366 const bool new_download = (download_id == content::DownloadItem::kInvalidId); | 269 weak_factory_.GetWeakPtr(), |
| 367 base::Callback<void(uint32)> got_id(base::Bind( | 270 base::Passed(&request_handle), |
| 368 &DownloadManagerImpl::StartDownloadWithId, | 271 base::Passed(&info))); |
| 369 weak_factory_.GetWeakPtr(), | |
| 370 base::Passed(info.Pass()), | |
| 371 base::Passed(stream.Pass()), | |
| 372 on_started, | |
| 373 new_download)); | |
| 374 if (new_download) { | |
| 375 GetNextId(got_id); | |
| 376 } else { | |
| 377 got_id.Run(download_id); | |
| 378 } | |
| 379 } | 272 } |
| 380 | 273 |
| 381 void DownloadManagerImpl::StartDownloadWithId( | 274 void DownloadManagerImpl::StartDownloadWithId( |
| 275 scoped_ptr<DownloadRequestHandle> request_handle, |
| 382 scoped_ptr<DownloadCreateInfo> info, | 276 scoped_ptr<DownloadCreateInfo> info, |
| 383 scoped_ptr<ByteStreamReader> stream, | |
| 384 const DownloadUrlParameters::OnStartedCallback& on_started, | |
| 385 bool new_download, | |
| 386 uint32 id) { | 277 uint32 id) { |
| 387 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 388 DCHECK_NE(content::DownloadItem::kInvalidId, id); | 279 pending_requests_.push_back(request_handle.release()); |
| 389 DownloadItemImpl* download = NULL; | 280 OnDownloadRequestStarted(id, |
| 390 if (new_download) { | 281 true /* new download */, |
| 391 download = CreateActiveItem(id, *info); | 282 DownloadUrlParameters::OnStartedCallback(), |
| 392 } else { | 283 pending_requests_.back(), |
| 393 DownloadMap::iterator item_iterator = downloads_.find(id); | 284 DOWNLOAD_INTERRUPT_REASON_NONE, |
| 394 // Trying to resume an interrupted download. | 285 info.Pass()); |
| 395 if (item_iterator == downloads_.end() || | 286 } |
| 396 (item_iterator->second->GetState() == DownloadItem::CANCELLED)) { | 287 |
| 397 // If the download is no longer known to the DownloadManager, then it was | 288 DownloadItemImpl* DownloadManagerImpl::UpdateAndGetResumedDownloadItem( |
| 398 // removed after it was resumed. Ignore. If the download is cancelled | 289 uint32 download_id, |
| 399 // while resuming, then also ignore the request. | 290 DownloadRequestHandle* request_handle, |
| 400 info->request_handle.CancelRequest(); | 291 const DownloadCreateInfo& new_create_info) { |
| 401 if (!on_started.is_null()) | 292 DownloadMap::iterator item_iterator = downloads_.find(download_id); |
| 402 on_started.Run(NULL, net::ERR_ABORTED); | 293 // Trying to resume an interrupted download. |
| 403 return; | 294 if (item_iterator == downloads_.end() || |
| 404 } | 295 (item_iterator->second->GetState() == DownloadItem::CANCELLED)) { |
| 405 download = item_iterator->second; | 296 // If the download is no longer known to the DownloadManager, then it was |
| 406 DCHECK_EQ(DownloadItem::INTERRUPTED, download->GetState()); | 297 // removed after it was resumed. Ignore. If the download is cancelled |
| 298 // while resuming, then also ignore the request. |
| 299 request_handle->CancelRequest(); |
| 300 return NULL; |
| 301 } |
| 302 DownloadItemImpl* download = item_iterator->second; |
| 303 DCHECK_EQ(DownloadItem::INTERRUPTED, download->GetState()); |
| 304 download->MergeOriginInfoOnResume(new_create_info); |
| 305 return download; |
| 306 } |
| 307 |
| 308 void DownloadManagerImpl::OnDownloadRequestStarted( |
| 309 uint32 download_id, |
| 310 bool new_download, |
| 311 const DownloadUrlParameters::OnStartedCallback& on_started, |
| 312 DownloadRequestHandle* request_handle, |
| 313 DownloadInterruptReason interrupt_reason, |
| 314 scoped_ptr<DownloadCreateInfo> info) { |
| 315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 316 DCHECK_NE(content::DownloadItem::kInvalidId, download_id); |
| 317 DCHECK(info); |
| 318 ScopedVector<DownloadRequestHandle>::iterator handle_iter = std::find( |
| 319 pending_requests_.begin(), pending_requests_.end(), request_handle); |
| 320 DCHECK(pending_requests_.end() != handle_iter); |
| 321 pending_requests_.weak_erase(handle_iter); |
| 322 scoped_ptr<DownloadRequestHandle> owned_request_handle(request_handle); |
| 323 DownloadItemImpl* download = |
| 324 new_download |
| 325 ? CreateActiveItem(download_id, *info) |
| 326 : UpdateAndGetResumedDownloadItem(download_id, request_handle, *info); |
| 327 if (!download) { |
| 328 if (!on_started.is_null()) |
| 329 on_started.Run(NULL, DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); |
| 330 return; |
| 407 } | 331 } |
| 408 | 332 |
| 409 base::FilePath default_download_directory; | 333 base::FilePath default_download_directory; |
| 410 if (delegate_) { | 334 if (delegate_) { |
| 411 base::FilePath website_save_directory; // Unused | 335 base::FilePath website_save_directory; // Unused |
| 412 bool skip_dir_check = false; // Unused | 336 bool skip_dir_check = false; // Unused |
| 413 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory, | 337 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory, |
| 414 &default_download_directory, &skip_dir_check); | 338 &default_download_directory, &skip_dir_check); |
| 415 } | 339 } |
| 416 | 340 |
| 417 // Create the download file and start the download. | 341 // Create the download file and start the download. |
| 418 scoped_ptr<DownloadFile> download_file( | 342 scoped_ptr<DownloadFile> download_file( |
| 419 file_factory_->CreateFile( | 343 file_factory_->CreateFile(info->save_info.Pass(), |
| 420 info->save_info.Pass(), default_download_directory, | 344 default_download_directory, |
| 421 info->url(), info->referrer_url, | 345 info->url(), |
| 422 delegate_->GenerateFileHash(), | 346 info->referrer_url, |
| 423 stream.Pass(), download->GetBoundNetLog(), | 347 delegate_->GenerateFileHash(), |
| 424 download->DestinationObserverAsWeakPtr())); | 348 info->stream_reader.Pass(), |
| 349 download->GetBoundNetLog(), |
| 350 download->DestinationObserverAsWeakPtr())); |
| 425 | 351 |
| 426 // Attach the client ID identifying the app to the AV system. | 352 // Attach the client ID identifying the app to the AV system. |
| 427 if (download_file.get() && delegate_) { | 353 if (download_file.get() && delegate_) { |
| 428 download_file->SetClientGuid( | 354 download_file->SetClientGuid( |
| 429 delegate_->ApplicationClientIdForFileScanning()); | 355 delegate_->ApplicationClientIdForFileScanning()); |
| 430 } | 356 } |
| 431 | 357 |
| 432 scoped_ptr<DownloadRequestHandleInterface> req_handle( | 358 download->Start(download_file.Pass(), owned_request_handle.Pass()); |
| 433 new DownloadRequestHandle(info->request_handle)); | |
| 434 download->Start(download_file.Pass(), req_handle.Pass()); | |
| 435 | 359 |
| 436 // For interrupted downloads, Start() will transition the state to | 360 // For interrupted downloads, Start() will transition the state to |
| 437 // IN_PROGRESS and consumers will be notified via OnDownloadUpdated(). | 361 // IN_PROGRESS and consumers will be notified via OnDownloadUpdated(). |
| 438 // For new downloads, we notify here, rather than earlier, so that | 362 // For new downloads, we notify here, rather than earlier, so that |
| 439 // the download_file is bound to download and all the usual | 363 // the download_file is bound to download and all the usual |
| 440 // setters (e.g. Cancel) work. | 364 // setters (e.g. Cancel) work. |
| 441 if (new_download) | 365 if (new_download) |
| 442 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 366 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
| 443 | 367 |
| 444 if (!on_started.is_null()) | 368 if (!on_started.is_null()) |
| 445 on_started.Run(download, net::OK); | 369 on_started.Run(download, DOWNLOAD_INTERRUPT_REASON_NONE); |
| 446 } | 370 } |
| 447 | 371 |
| 448 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { | 372 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { |
| 449 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 450 for (DownloadMap::iterator it = downloads_.begin(); | 374 for (DownloadMap::iterator it = downloads_.begin(); |
| 451 it != downloads_.end(); ++it) { | 375 it != downloads_.end(); ++it) { |
| 452 DownloadItemImpl* item = it->second; | 376 DownloadItemImpl* item = it->second; |
| 453 CheckForFileRemoval(item); | 377 CheckForFileRemoval(item); |
| 454 } | 378 } |
| 455 } | 379 } |
| 456 | 380 |
| 457 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { | 381 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { |
| 458 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 459 if ((download_item->GetState() == DownloadItem::COMPLETE) && | 383 if ((download_item->GetState() == DownloadItem::COMPLETE) && |
| 460 !download_item->GetFileExternallyRemoved() && | 384 !download_item->GetFileExternallyRemoved() && |
| 461 delegate_) { | 385 delegate_) { |
| 462 delegate_->CheckForFileExistence( | 386 delegate_->CheckForFileExistence( |
| 463 download_item, | 387 download_item, |
| 464 base::Bind(&DownloadManagerImpl::OnFileExistenceChecked, | 388 base::Bind(&DownloadManagerImpl::OnFileExistenceChecked, |
| 465 weak_factory_.GetWeakPtr(), download_item->GetId())); | 389 weak_factory_.GetWeakPtr(), download_item->GetId())); |
| 466 } | 390 } |
| 467 } | 391 } |
| 468 | 392 |
| 393 void DownloadManagerImpl::DownloadUrlWithId( |
| 394 scoped_ptr<DownloadUrlParameters> params, |
| 395 bool new_download, |
| 396 uint32 download_id) { |
| 397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 398 DCHECK_NE(DownloadItem::kInvalidId, download_id); |
| 399 DownloadUrlParameters::OnStartedCallback on_started_callback = |
| 400 params->callback(); |
| 401 scoped_ptr<DownloadRequestHandle> request_handle( |
| 402 UrlDownloader::CreateDownloadRequest(params.Pass())); |
| 403 pending_requests_.push_back(request_handle.release()); |
| 404 DownloadRequestHandle::RequestStartedCallback started_callback = |
| 405 base::Bind(&DownloadManagerImpl::OnDownloadRequestStarted, |
| 406 weak_factory_.GetWeakPtr(), |
| 407 download_id, |
| 408 new_download, |
| 409 on_started_callback, |
| 410 pending_requests_.back()); |
| 411 pending_requests_.back()->Start(started_callback); |
| 412 } |
| 413 |
| 469 void DownloadManagerImpl::OnFileExistenceChecked(uint32 download_id, | 414 void DownloadManagerImpl::OnFileExistenceChecked(uint32 download_id, |
| 470 bool result) { | 415 bool result) { |
| 471 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 472 if (!result) { // File does not exist. | 417 if (!result) { // File does not exist. |
| 473 if (ContainsKey(downloads_, download_id)) | 418 if (ContainsKey(downloads_, download_id)) |
| 474 downloads_[download_id]->OnDownloadedFileRemoved(); | 419 downloads_[download_id]->OnDownloadedFileRemoved(); |
| 475 } | 420 } |
| 476 } | 421 } |
| 477 | 422 |
| 478 BrowserContext* DownloadManagerImpl::GetBrowserContext() const { | 423 BrowserContext* DownloadManagerImpl::GetBrowserContext() const { |
| 479 return browser_context_; | 424 return browser_context_; |
| 480 } | 425 } |
| 481 | 426 |
| 482 void DownloadManagerImpl::CreateSavePackageDownloadItem( | 427 void DownloadManagerImpl::CreateSavePackageDownloadItem( |
| 483 const base::FilePath& main_file_path, | 428 scoped_ptr<DownloadCreateInfo> create_info, |
| 484 const GURL& page_url, | 429 const DownloadItemImplCreated& download_created_callback) { |
| 485 const std::string& mime_type, | |
| 486 scoped_ptr<DownloadRequestHandleInterface> request_handle, | |
| 487 const DownloadItemImplCreated& item_created) { | |
| 488 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 489 GetNextId(base::Bind( | 431 DCHECK(create_info->is_save_package_download); |
| 490 &DownloadManagerImpl::CreateSavePackageDownloadItemWithId, | 432 |
| 491 weak_factory_.GetWeakPtr(), | 433 GetNextId( |
| 492 main_file_path, | 434 base::Bind(&DownloadManagerImpl::CreateSavePackageDownloadItemWithId, |
| 493 page_url, | 435 weak_factory_.GetWeakPtr(), |
| 494 mime_type, | 436 base::Passed(&create_info), |
| 495 base::Passed(request_handle.Pass()), | 437 download_created_callback)); |
| 496 item_created)); | |
| 497 } | 438 } |
| 498 | 439 |
| 499 void DownloadManagerImpl::CreateSavePackageDownloadItemWithId( | 440 void DownloadManagerImpl::CreateSavePackageDownloadItemWithId( |
| 500 const base::FilePath& main_file_path, | 441 scoped_ptr<DownloadCreateInfo> create_info, |
| 501 const GURL& page_url, | 442 const DownloadItemImplCreated& download_created_callback, |
| 502 const std::string& mime_type, | |
| 503 scoped_ptr<DownloadRequestHandleInterface> request_handle, | |
| 504 const DownloadItemImplCreated& item_created, | |
| 505 uint32 id) { | 443 uint32 id) { |
| 506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 444 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 507 DCHECK_NE(content::DownloadItem::kInvalidId, id); | 445 DownloadItemImpl* item = CreateActiveItem(id, *create_info); |
| 508 DCHECK(!ContainsKey(downloads_, id)); | 446 download_created_callback.Run(item); |
| 509 net::BoundNetLog bound_net_log = | |
| 510 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | |
| 511 DownloadItemImpl* download_item = item_factory_->CreateSavePageItem( | |
| 512 this, | |
| 513 id, | |
| 514 main_file_path, | |
| 515 page_url, | |
| 516 mime_type, | |
| 517 request_handle.Pass(), | |
| 518 bound_net_log); | |
| 519 downloads_[download_item->GetId()] = download_item; | |
| 520 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated( | |
| 521 this, download_item)); | |
| 522 if (!item_created.is_null()) | |
| 523 item_created.Run(download_item); | |
| 524 } | 447 } |
| 525 | 448 |
| 526 void DownloadManagerImpl::OnSavePackageSuccessfullyFinished( | 449 void DownloadManagerImpl::OnSavePackageSuccessfullyFinished( |
| 527 DownloadItem* download_item) { | 450 DownloadItem* download_item) { |
| 528 FOR_EACH_OBSERVER(Observer, observers_, | 451 FOR_EACH_OBSERVER(Observer, observers_, |
| 529 OnSavePackageSuccessfullyFinished(this, download_item)); | 452 OnSavePackageSuccessfullyFinished(this, download_item)); |
| 530 } | 453 } |
| 531 | 454 |
| 532 // Resume a download of a specific URL. We send the request to the | 455 // Resume a download of a specific URL. We send the request to the |
| 533 // ResourceDispatcherHost, and let it send us responses like a regular | 456 // ResourceDispatcherHost, and let it send us responses like a regular |
| 534 // download. | 457 // download. |
| 535 void DownloadManagerImpl::ResumeInterruptedDownload( | 458 void DownloadManagerImpl::ResumeInterruptedDownload( |
| 536 scoped_ptr<content::DownloadUrlParameters> params, | 459 scoped_ptr<content::DownloadUrlParameters> params, |
| 537 uint32 id) { | 460 uint32 id) { |
| 538 RecordDownloadSource(INITIATED_BY_RESUMPTION); | 461 RecordDownloadSource(INITIATED_BY_RESUMPTION); |
| 539 BrowserThread::PostTask( | 462 DownloadUrlWithId(params.Pass(), false /* new_download */, id); |
| 540 BrowserThread::IO, | |
| 541 FROM_HERE, | |
| 542 base::Bind(&BeginDownload, base::Passed(¶ms), id)); | |
| 543 } | 463 } |
| 544 | 464 |
| 545 void DownloadManagerImpl::SetDownloadItemFactoryForTesting( | 465 void DownloadManagerImpl::SetDownloadItemFactoryForTesting( |
| 546 scoped_ptr<DownloadItemFactory> item_factory) { | 466 scoped_ptr<DownloadItemFactory> item_factory) { |
| 547 item_factory_ = item_factory.Pass(); | 467 item_factory_ = item_factory.Pass(); |
| 548 } | 468 } |
| 549 | 469 |
| 550 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( | 470 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( |
| 551 scoped_ptr<DownloadFileFactory> file_factory) { | 471 scoped_ptr<DownloadFileFactory> file_factory) { |
| 552 file_factory_ = file_factory.Pass(); | 472 file_factory_ = file_factory.Pass(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 return num_deleted; | 520 return num_deleted; |
| 601 } | 521 } |
| 602 | 522 |
| 603 void DownloadManagerImpl::DownloadUrl( | 523 void DownloadManagerImpl::DownloadUrl( |
| 604 scoped_ptr<DownloadUrlParameters> params) { | 524 scoped_ptr<DownloadUrlParameters> params) { |
| 605 if (params->post_id() >= 0) { | 525 if (params->post_id() >= 0) { |
| 606 // Check this here so that the traceback is more useful. | 526 // Check this here so that the traceback is more useful. |
| 607 DCHECK(params->prefer_cache()); | 527 DCHECK(params->prefer_cache()); |
| 608 DCHECK(params->method() == "POST"); | 528 DCHECK(params->method() == "POST"); |
| 609 } | 529 } |
| 610 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 530 |
| 611 &BeginDownload, base::Passed(¶ms), | 531 GetNextId(base::Bind(&DownloadManagerImpl::DownloadUrlWithId, |
| 612 content::DownloadItem::kInvalidId)); | 532 weak_factory_.GetWeakPtr(), |
| 533 base::Passed(¶ms), |
| 534 true /* new_download */)); |
| 613 } | 535 } |
| 614 | 536 |
| 615 void DownloadManagerImpl::AddObserver(Observer* observer) { | 537 void DownloadManagerImpl::AddObserver(Observer* observer) { |
| 616 observers_.AddObserver(observer); | 538 observers_.AddObserver(observer); |
| 617 } | 539 } |
| 618 | 540 |
| 619 void DownloadManagerImpl::RemoveObserver(Observer* observer) { | 541 void DownloadManagerImpl::RemoveObserver(Observer* observer) { |
| 620 observers_.RemoveObserver(observer); | 542 observers_.RemoveObserver(observer); |
| 621 } | 543 } |
| 622 | 544 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 if (delegate_) | 620 if (delegate_) |
| 699 delegate_->OpenDownload(download); | 621 delegate_->OpenDownload(download); |
| 700 } | 622 } |
| 701 | 623 |
| 702 void DownloadManagerImpl::ShowDownloadInShell(DownloadItemImpl* download) { | 624 void DownloadManagerImpl::ShowDownloadInShell(DownloadItemImpl* download) { |
| 703 if (delegate_) | 625 if (delegate_) |
| 704 delegate_->ShowDownloadInShell(download); | 626 delegate_->ShowDownloadInShell(download); |
| 705 } | 627 } |
| 706 | 628 |
| 707 } // namespace content | 629 } // namespace content |
| OLD | NEW |