| 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/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/i18n/case_conversion.h" | 13 #include "base/i18n/case_conversion.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
| 16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 17 #include "base/stringprintf.h" | 17 #include "base/stringprintf.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 "base/sys_string_conversions.h" | 20 #include "base/sys_string_conversions.h" |
| 21 #include "build/build_config.h" | 21 #include "build/build_config.h" |
| 22 #include "content/browser/download/byte_stream.h" | 22 #include "content/browser/download/byte_stream.h" |
| 23 #include "content/browser/download/download_create_info.h" | 23 #include "content/browser/download/download_create_info.h" |
| 24 #include "content/browser/download/download_file_manager.h" | 24 #include "content/browser/download/download_file_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/renderer_host/render_view_host_impl.h" | 27 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 28 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" | 28 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" |
| 29 #include "content/browser/web_contents/web_contents_impl.h" | 29 #include "content/browser/web_contents/web_contents_impl.h" |
| 30 #include "content/public/browser/browser_context.h" | 30 #include "content/public/browser/browser_context.h" |
| 31 #include "content/public/browser/browser_thread.h" | 31 #include "content/public/browser/browser_thread.h" |
| 32 #include "content/public/browser/content_browser_client.h" | 32 #include "content/public/browser/content_browser_client.h" |
| 33 #include "content/public/browser/download_interrupt_reasons.h" | 33 #include "content/public/browser/download_interrupt_reasons.h" |
| 34 #include "content/public/browser/download_manager_delegate.h" | 34 #include "content/public/browser/download_manager_delegate.h" |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 | 137 |
| 138 bool operator!=(const MapValueIteratorAdapter& that) const { | 138 bool operator!=(const MapValueIteratorAdapter& that) const { |
| 139 return iter_ != that.iter_; | 139 return iter_ != that.iter_; |
| 140 } | 140 } |
| 141 | 141 |
| 142 private: | 142 private: |
| 143 base::hash_map<int64, DownloadItem*>::const_iterator iter_; | 143 base::hash_map<int64, DownloadItem*>::const_iterator iter_; |
| 144 // Allow copy and assign. | 144 // Allow copy and assign. |
| 145 }; | 145 }; |
| 146 | 146 |
| 147 void EnsureNoPendingDownloadsOnFile(scoped_refptr<DownloadFileManager> dfm, | 147 void EnsureNoPendingDownloadJobsOnFile(bool* result) { |
| 148 bool* result) { | 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 149 if (dfm->NumberOfActiveDownloads()) | 149 *result = (content::DownloadFile::GetNumberOfDownloadFiles() == 0); |
| 150 *result = false; | |
| 151 BrowserThread::PostTask( | 150 BrowserThread::PostTask( |
| 152 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); | 151 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); |
| 153 } | 152 } |
| 154 | 153 |
| 155 void EnsureNoPendingDownloadJobsOnIO(bool* result) { | |
| 156 scoped_refptr<DownloadFileManager> download_file_manager = | |
| 157 ResourceDispatcherHostImpl::Get()->download_file_manager(); | |
| 158 BrowserThread::PostTask( | |
| 159 BrowserThread::FILE, FROM_HERE, | |
| 160 base::Bind(&EnsureNoPendingDownloadsOnFile, | |
| 161 download_file_manager, result)); | |
| 162 } | |
| 163 | |
| 164 class DownloadItemFactoryImpl : public content::DownloadItemFactory { | 154 class DownloadItemFactoryImpl : public content::DownloadItemFactory { |
| 165 public: | 155 public: |
| 166 DownloadItemFactoryImpl() {} | 156 DownloadItemFactoryImpl() {} |
| 167 virtual ~DownloadItemFactoryImpl() {} | 157 virtual ~DownloadItemFactoryImpl() {} |
| 168 | 158 |
| 169 virtual DownloadItemImpl* CreatePersistedItem( | 159 virtual DownloadItemImpl* CreatePersistedItem( |
| 170 DownloadItemImplDelegate* delegate, | 160 DownloadItemImplDelegate* delegate, |
| 171 content::DownloadId download_id, | 161 content::DownloadId download_id, |
| 172 const content::DownloadPersistentStoreInfo& info, | 162 const content::DownloadPersistentStoreInfo& info, |
| 173 const net::BoundNetLog& bound_net_log) OVERRIDE { | 163 const net::BoundNetLog& bound_net_log) OVERRIDE { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 198 }; | 188 }; |
| 199 | 189 |
| 200 } // namespace | 190 } // namespace |
| 201 | 191 |
| 202 namespace content { | 192 namespace content { |
| 203 | 193 |
| 204 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { | 194 bool DownloadManager::EnsureNoPendingDownloadsForTesting() { |
| 205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 206 bool result = true; | 196 bool result = true; |
| 207 BrowserThread::PostTask( | 197 BrowserThread::PostTask( |
| 208 BrowserThread::IO, FROM_HERE, | 198 BrowserThread::FILE, FROM_HERE, |
| 209 base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result)); | 199 base::Bind(&EnsureNoPendingDownloadJobsOnFile, &result)); |
| 210 MessageLoop::current()->Run(); | 200 MessageLoop::current()->Run(); |
| 211 return result; | 201 return result; |
| 212 } | 202 } |
| 213 | 203 |
| 214 } // namespace content | 204 } // namespace content |
| 215 | 205 |
| 216 DownloadManagerImpl::DownloadManagerImpl( | 206 DownloadManagerImpl::DownloadManagerImpl( |
| 217 DownloadFileManager* file_manager, | 207 scoped_ptr<content::DownloadItemFactory> item_factory, |
| 218 scoped_ptr<content::DownloadItemFactory> factory, | |
| 219 net::NetLog* net_log) | 208 net::NetLog* net_log) |
| 220 : factory_(factory.Pass()), | 209 : item_factory_(item_factory.Pass()), |
| 221 history_size_(0), | 210 history_size_(0), |
| 222 shutdown_needed_(false), | 211 shutdown_needed_(false), |
| 223 browser_context_(NULL), | 212 browser_context_(NULL), |
| 224 file_manager_(file_manager), | |
| 225 delegate_(NULL), | 213 delegate_(NULL), |
| 226 net_log_(net_log) { | 214 net_log_(net_log) { |
| 227 DCHECK(file_manager); | 215 if (!item_factory_.get()) |
| 228 if (!factory_.get()) | 216 item_factory_.reset(new DownloadItemFactoryImpl()); |
| 229 factory_.reset(new DownloadItemFactoryImpl()); | 217 file_factory_.reset(new content::DownloadFileFactory()); |
| 230 } | 218 } |
| 231 | 219 |
| 232 DownloadManagerImpl::~DownloadManagerImpl() { | 220 DownloadManagerImpl::~DownloadManagerImpl() { |
| 233 DCHECK(!shutdown_needed_); | 221 DCHECK(!shutdown_needed_); |
| 234 } | 222 } |
| 235 | 223 |
| 236 DownloadId DownloadManagerImpl::GetNextId() { | 224 DownloadId DownloadManagerImpl::GetNextId() { |
| 237 DownloadId id; | 225 DownloadId id; |
| 238 if (delegate_) | 226 if (delegate_) |
| 239 id = delegate_->GetNextId(); | 227 id = delegate_->GetNextId(); |
| 240 if (!id.IsValid()) { | 228 if (!id.IsValid()) { |
| 241 static int next_id; | 229 static int next_id; |
| 242 id = DownloadId(browser_context_, ++next_id); | 230 id = DownloadId(browser_context_, ++next_id); |
| 243 } | 231 } |
| 244 | 232 |
| 245 return id; | 233 return id; |
| 246 } | 234 } |
| 247 | 235 |
| 248 DownloadFileManager* DownloadManagerImpl::GetDownloadFileManager() { | 236 void DownloadManagerImpl::DelegateStart(DownloadItemImpl* item) { |
| 249 return file_manager_; | 237 content::DownloadTargetCallback callback = |
| 238 base::Bind(&DownloadManagerImpl::OnDownloadTargetDetermined, |
| 239 this, item->GetId()); |
| 240 if (!delegate_ || !delegate_->DetermineDownloadTarget(item, callback)) { |
| 241 FilePath target_path = item->GetForcedFilePath(); |
| 242 // TODO(asanka): Determine a useful path if |target_path| is empty. |
| 243 callback.Run(target_path, |
| 244 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 245 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 246 target_path); |
| 247 } |
| 250 } | 248 } |
| 251 | 249 |
| 252 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItemImpl* item) { | 250 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItemImpl* item) { |
| 253 if (!delegate_) | 251 if (!delegate_) |
| 254 return true; | 252 return true; |
| 255 | 253 |
| 256 return delegate_->ShouldOpenDownload(item); | 254 return delegate_->ShouldOpenDownload(item); |
| 257 } | 255 } |
| 258 | 256 |
| 259 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) { | 257 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 275 void DownloadManagerImpl::Shutdown() { | 273 void DownloadManagerImpl::Shutdown() { |
| 276 VLOG(20) << __FUNCTION__ << "()" | 274 VLOG(20) << __FUNCTION__ << "()" |
| 277 << " shutdown_needed_ = " << shutdown_needed_; | 275 << " shutdown_needed_ = " << shutdown_needed_; |
| 278 if (!shutdown_needed_) | 276 if (!shutdown_needed_) |
| 279 return; | 277 return; |
| 280 shutdown_needed_ = false; | 278 shutdown_needed_ = false; |
| 281 | 279 |
| 282 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); | 280 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown(this)); |
| 283 // TODO(benjhayden): Consider clearing observers_. | 281 // TODO(benjhayden): Consider clearing observers_. |
| 284 | 282 |
| 285 DCHECK(file_manager_); | 283 // The DownloadFiles will be canceled and deleted by their DownloadItems. |
| 286 BrowserThread::PostTask( | |
| 287 BrowserThread::FILE, FROM_HERE, | |
| 288 base::Bind(&DownloadFileManager::OnDownloadManagerShutdown, | |
| 289 file_manager_, make_scoped_refptr(this))); | |
| 290 | 284 |
| 291 AssertContainersConsistent(); | 285 AssertContainersConsistent(); |
| 292 | 286 |
| 293 // Go through all downloads in downloads_. Dangerous ones we need to | 287 // Go through all downloads in downloads_. Dangerous ones we need to |
| 294 // remove on disk, and in progress ones we need to cancel. | 288 // remove on disk, and in progress ones we need to cancel. |
| 295 for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) { | 289 for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) { |
| 296 DownloadItemImpl* download = it->second; | 290 DownloadItemImpl* download = it->second; |
| 297 | 291 |
| 298 // Save iterator from potential erases in this set done by called code. | 292 // Save iterator from potential erases in this set done by called code. |
| 299 // Iterators after an erasure point are still valid for lists and | 293 // Iterators after an erasure point are still valid for lists and |
| (...skipping 22 matching lines...) Expand all Loading... |
| 322 // and all in progress downloads have been cancelled. We can now delete | 316 // and all in progress downloads have been cancelled. We can now delete |
| 323 // anything left. | 317 // anything left. |
| 324 | 318 |
| 325 active_downloads_.clear(); | 319 active_downloads_.clear(); |
| 326 STLDeleteValues(&downloads_); | 320 STLDeleteValues(&downloads_); |
| 327 downloads_.clear(); | 321 downloads_.clear(); |
| 328 | 322 |
| 329 // We'll have nothing more to report to the observers after this point. | 323 // We'll have nothing more to report to the observers after this point. |
| 330 observers_.Clear(); | 324 observers_.Clear(); |
| 331 | 325 |
| 332 file_manager_ = NULL; | |
| 333 if (delegate_) | 326 if (delegate_) |
| 334 delegate_->Shutdown(); | 327 delegate_->Shutdown(); |
| 335 delegate_ = NULL; | 328 delegate_ = NULL; |
| 336 } | 329 } |
| 337 | 330 |
| 338 void DownloadManagerImpl::GetTemporaryDownloads( | 331 void DownloadManagerImpl::GetTemporaryDownloads( |
| 339 const FilePath& dir_path, DownloadVector* result) { | 332 const FilePath& dir_path, DownloadVector* result) { |
| 340 DCHECK(result); | 333 DCHECK(result); |
| 341 | 334 |
| 342 for (DownloadMap::iterator it = downloads_.begin(); | 335 for (DownloadMap::iterator it = downloads_.begin(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { | 383 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { |
| 391 DCHECK(browser_context); | 384 DCHECK(browser_context); |
| 392 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; | 385 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; |
| 393 shutdown_needed_ = true; | 386 shutdown_needed_ = true; |
| 394 | 387 |
| 395 browser_context_ = browser_context; | 388 browser_context_ = browser_context; |
| 396 | 389 |
| 397 return true; | 390 return true; |
| 398 } | 391 } |
| 399 | 392 |
| 400 // We have received a message from DownloadFileManager about a new download. | |
| 401 content::DownloadId DownloadManagerImpl::StartDownload( | 393 content::DownloadId DownloadManagerImpl::StartDownload( |
| 402 scoped_ptr<DownloadCreateInfo> info, | 394 scoped_ptr<DownloadCreateInfo> info, |
| 403 scoped_ptr<content::ByteStreamReader> stream) { | 395 scoped_ptr<content::ByteStreamReader> stream) { |
| 404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 405 | 397 |
| 406 // |bound_net_log| will be used for logging both the download item's and | 398 net::BoundNetLog bound_net_log = |
| 407 // the download file's events. | 399 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
| 408 net::BoundNetLog bound_net_log = CreateDownloadItem(info.get()); | |
| 409 | 400 |
| 410 // If info->download_id was unknown on entry to this function, it was | 401 // We create the DownloadItem before the DownloadFile because the |
| 411 // assigned in CreateDownloadItem. | 402 // DownloadItem already needs to handle a state in which there is |
| 412 DownloadId download_id = info->download_id; | 403 // no associated DownloadFile (history downloads, !IN_PROGRESS downloads) |
| 404 DownloadItemImpl* download = |
| 405 CreateDownloadItem(info.get(), bound_net_log); |
| 406 scoped_ptr<content::DownloadFile> download_file( |
| 407 file_factory_->CreateFile( |
| 408 info->save_info, info->url(), info->referrer_url, |
| 409 info->received_bytes, GenerateFileHash(), |
| 410 stream.Pass(), bound_net_log, |
| 411 download->DestinationObserverAsWeakPtr())); |
| 412 download->Start(download_file.Pass()); |
| 413 | 413 |
| 414 DownloadFileManager::CreateDownloadFileCallback callback( | 414 return download->GetGlobalId(); |
| 415 base::Bind(&DownloadManagerImpl::OnDownloadFileCreated, | |
| 416 this, download_id.local())); | |
| 417 | |
| 418 BrowserThread::PostTask( | |
| 419 BrowserThread::FILE, FROM_HERE, | |
| 420 base::Bind(&DownloadFileManager::CreateDownloadFile, | |
| 421 file_manager_, base::Passed(info.Pass()), | |
| 422 base::Passed(stream.Pass()), | |
| 423 make_scoped_refptr(this), | |
| 424 GenerateFileHash(), bound_net_log, | |
| 425 callback)); | |
| 426 | |
| 427 return download_id; | |
| 428 } | |
| 429 | |
| 430 void DownloadManagerImpl::OnDownloadFileCreated( | |
| 431 int32 download_id, content::DownloadInterruptReason reason) { | |
| 432 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) { | |
| 433 OnDownloadInterrupted(download_id, reason); | |
| 434 // TODO(rdsmith): It makes no sense to continue along the | |
| 435 // regular download path after we've gotten an error. But it's | |
| 436 // the way the code has historically worked, and this allows us | |
| 437 // to get the download persisted and observers of the download manager | |
| 438 // notified, so tests work. When we execute all side effects of cancel | |
| 439 // (including queue removal) immedately rather than waiting for | |
| 440 // persistence we should replace this comment with a "return;". | |
| 441 } | |
| 442 | |
| 443 DownloadMap::iterator download_iter = active_downloads_.find(download_id); | |
| 444 if (download_iter == active_downloads_.end()) | |
| 445 return; | |
| 446 | |
| 447 DownloadItemImpl* download = download_iter->second; | |
| 448 content::DownloadTargetCallback callback = | |
| 449 base::Bind(&DownloadManagerImpl::OnDownloadTargetDetermined, | |
| 450 this, download_id); | |
| 451 if (!delegate_ || !delegate_->DetermineDownloadTarget(download, callback)) { | |
| 452 FilePath target_path = download->GetForcedFilePath(); | |
| 453 // TODO(asanka): Determine a useful path if |target_path| is empty. | |
| 454 callback.Run(target_path, | |
| 455 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 456 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 457 target_path); | |
| 458 } | |
| 459 } | 415 } |
| 460 | 416 |
| 461 void DownloadManagerImpl::OnDownloadTargetDetermined( | 417 void DownloadManagerImpl::OnDownloadTargetDetermined( |
| 462 int32 download_id, | 418 int32 download_id, |
| 463 const FilePath& target_path, | 419 const FilePath& target_path, |
| 464 DownloadItem::TargetDisposition disposition, | 420 DownloadItem::TargetDisposition disposition, |
| 465 content::DownloadDangerType danger_type, | 421 content::DownloadDangerType danger_type, |
| 466 const FilePath& intermediate_path) { | 422 const FilePath& intermediate_path) { |
| 467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 468 DownloadMap::iterator download_iter = active_downloads_.find(download_id); | 424 DownloadMap::iterator download_iter = active_downloads_.find(download_id); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { | 468 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { |
| 513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 514 if (ContainsKey(downloads_, download_id)) | 470 if (ContainsKey(downloads_, download_id)) |
| 515 downloads_[download_id]->OnDownloadedFileRemoved(); | 471 downloads_[download_id]->OnDownloadedFileRemoved(); |
| 516 } | 472 } |
| 517 | 473 |
| 518 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { | 474 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { |
| 519 return browser_context_; | 475 return browser_context_; |
| 520 } | 476 } |
| 521 | 477 |
| 522 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem( | 478 DownloadItemImpl* DownloadManagerImpl::CreateDownloadItem( |
| 523 DownloadCreateInfo* info) { | 479 DownloadCreateInfo* info, const net::BoundNetLog& bound_net_log) { |
| 524 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 525 | 481 |
| 526 net::BoundNetLog bound_net_log = | |
| 527 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | |
| 528 if (!info->download_id.IsValid()) | 482 if (!info->download_id.IsValid()) |
| 529 info->download_id = GetNextId(); | 483 info->download_id = GetNextId(); |
| 530 DownloadItemImpl* download = factory_->CreateActiveItem( | 484 DownloadItemImpl* download = item_factory_->CreateActiveItem( |
| 531 this, *info, | 485 this, *info, |
| 532 scoped_ptr<DownloadRequestHandleInterface>( | 486 scoped_ptr<DownloadRequestHandleInterface>( |
| 533 new DownloadRequestHandle(info->request_handle)).Pass(), | 487 new DownloadRequestHandle(info->request_handle)).Pass(), |
| 534 browser_context_->IsOffTheRecord(), bound_net_log); | 488 browser_context_->IsOffTheRecord(), bound_net_log); |
| 535 | 489 |
| 536 DCHECK(!ContainsKey(downloads_, download->GetId())); | 490 DCHECK(!ContainsKey(downloads_, download->GetId())); |
| 537 downloads_[download->GetId()] = download; | 491 downloads_[download->GetId()] = download; |
| 538 DCHECK(!ContainsKey(active_downloads_, download->GetId())); | 492 DCHECK(!ContainsKey(active_downloads_, download->GetId())); |
| 539 active_downloads_[download->GetId()] = download; | 493 active_downloads_[download->GetId()] = download; |
| 540 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 494 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
| 541 | 495 |
| 542 return bound_net_log; | 496 return download; |
| 543 } | 497 } |
| 544 | 498 |
| 545 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( | 499 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( |
| 546 const FilePath& main_file_path, | 500 const FilePath& main_file_path, |
| 547 const GURL& page_url, | 501 const GURL& page_url, |
| 548 bool is_otr, | 502 bool is_otr, |
| 549 const std::string& mime_type, | 503 const std::string& mime_type, |
| 550 DownloadItem::Observer* observer) { | 504 DownloadItem::Observer* observer) { |
| 551 net::BoundNetLog bound_net_log = | 505 net::BoundNetLog bound_net_log = |
| 552 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 506 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
| 553 DownloadItemImpl* download = factory_->CreateSavePageItem( | 507 DownloadItemImpl* download = item_factory_->CreateSavePageItem( |
| 554 this, | 508 this, |
| 555 main_file_path, | 509 main_file_path, |
| 556 page_url, | 510 page_url, |
| 557 is_otr, | 511 is_otr, |
| 558 GetNextId(), | 512 GetNextId(), |
| 559 mime_type, | 513 mime_type, |
| 560 bound_net_log); | 514 bound_net_log); |
| 561 | 515 |
| 562 download->AddObserver(observer); | 516 download->AddObserver(observer); |
| 563 | 517 |
| 564 DCHECK(!ContainsKey(downloads_, download->GetId())); | 518 DCHECK(!ContainsKey(downloads_, download->GetId())); |
| 565 downloads_[download->GetId()] = download; | 519 downloads_[download->GetId()] = download; |
| 566 DCHECK(!SavePageData::Get(download)); | 520 DCHECK(!SavePageData::Get(download)); |
| 567 new SavePageData(download); | 521 new SavePageData(download); |
| 568 DCHECK(SavePageData::Get(download)); | 522 DCHECK(SavePageData::Get(download)); |
| 569 | 523 |
| 570 // TODO(benjhayden): Fire OnDownloadCreated for SavePackage downloads when | 524 // TODO(benjhayden): Fire OnDownloadCreated for SavePackage downloads when |
| 571 // we're comfortable with the user interacting with them. | 525 // we're comfortable with the user interacting with them. |
| 572 // FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 526 // FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
| 573 | 527 |
| 574 // Will notify the observer in the callback. | 528 // Will notify the observer in the callback. |
| 575 if (delegate_) | 529 if (delegate_) |
| 576 delegate_->AddItemToPersistentStore(download); | 530 delegate_->AddItemToPersistentStore(download); |
| 577 | 531 |
| 578 return download; | 532 return download; |
| 579 } | 533 } |
| 580 | 534 |
| 581 void DownloadManagerImpl::UpdateDownload(int32 download_id, | |
| 582 int64 bytes_so_far, | |
| 583 int64 bytes_per_sec, | |
| 584 const std::string& hash_state) { | |
| 585 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 586 DownloadMap::iterator it = active_downloads_.find(download_id); | |
| 587 if (it != active_downloads_.end()) { | |
| 588 DownloadItemImpl* download = it->second; | |
| 589 if (download->IsInProgress()) { | |
| 590 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); | |
| 591 if (delegate_) | |
| 592 delegate_->UpdateItemInPersistentStore(download); | |
| 593 } | |
| 594 } | |
| 595 } | |
| 596 | |
| 597 void DownloadManagerImpl::OnResponseCompleted(int32 download_id, | |
| 598 int64 size, | |
| 599 const std::string& hash) { | |
| 600 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 601 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | |
| 602 << " size = " << size; | |
| 603 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 604 | |
| 605 // If it's not in active_downloads_, that means it was cancelled; just | |
| 606 // ignore the notification. | |
| 607 if (active_downloads_.count(download_id) == 0) | |
| 608 return; | |
| 609 | |
| 610 DownloadItemImpl* download = active_downloads_[download_id]; | |
| 611 download->OnAllDataSaved(size, hash); | |
| 612 MaybeCompleteDownload(download); | |
| 613 } | |
| 614 | |
| 615 void DownloadManagerImpl::AssertStateConsistent( | 535 void DownloadManagerImpl::AssertStateConsistent( |
| 616 DownloadItemImpl* download) const { | 536 DownloadItemImpl* download) const { |
| 617 CHECK(ContainsKey(downloads_, download->GetId())); | 537 CHECK(ContainsKey(downloads_, download->GetId())); |
| 618 | 538 |
| 619 int64 state = download->GetState(); | 539 int64 state = download->GetState(); |
| 620 base::debug::Alias(&state); | 540 base::debug::Alias(&state); |
| 621 if (ContainsKey(active_downloads_, download->GetId())) { | 541 if (ContainsKey(active_downloads_, download->GetId())) { |
| 622 if (download->IsPersisted()) | 542 if (download->IsPersisted()) |
| 623 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); | 543 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); |
| 624 if (DownloadItem::IN_PROGRESS != download->GetState()) | 544 if (DownloadItem::IN_PROGRESS != download->GetState()) |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { | 646 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { |
| 727 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 647 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 728 | 648 |
| 729 VLOG(20) << __FUNCTION__ << "()" | 649 VLOG(20) << __FUNCTION__ << "()" |
| 730 << " download = " << download->DebugString(true); | 650 << " download = " << download->DebugString(true); |
| 731 | 651 |
| 732 RemoveFromActiveList(download); | 652 RemoveFromActiveList(download); |
| 733 // This function is called from the DownloadItem, so DI state | 653 // This function is called from the DownloadItem, so DI state |
| 734 // should already have been updated. | 654 // should already have been updated. |
| 735 AssertStateConsistent(download); | 655 AssertStateConsistent(download); |
| 736 | |
| 737 DCHECK(file_manager_); | |
| 738 download->OffThreadCancel(); | |
| 739 } | |
| 740 | |
| 741 void DownloadManagerImpl::OnDownloadInterrupted( | |
| 742 int32 download_id, | |
| 743 content::DownloadInterruptReason reason) { | |
| 744 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 745 | |
| 746 if (!ContainsKey(active_downloads_, download_id)) | |
| 747 return; | |
| 748 active_downloads_[download_id]->Interrupt(reason); | |
| 749 } | 656 } |
| 750 | 657 |
| 751 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { | 658 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { |
| 752 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 659 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 753 DCHECK(download); | 660 DCHECK(download); |
| 754 | 661 |
| 755 // Clean up will happen when the history system create callback runs if we | 662 // Clean up will happen when the history system create callback runs if we |
| 756 // don't have a valid db_handle yet. | 663 // don't have a valid db_handle yet. |
| 757 if (download->IsPersisted()) { | 664 if (download->IsPersisted()) { |
| 758 active_downloads_.erase(download->GetId()); | 665 active_downloads_.erase(download->GetId()); |
| 759 if (delegate_) | 666 if (delegate_) |
| 760 delegate_->UpdateItemInPersistentStore(download); | 667 delegate_->UpdateItemInPersistentStore(download); |
| 761 } | 668 } |
| 762 } | 669 } |
| 763 | 670 |
| 764 bool DownloadManagerImpl::GenerateFileHash() { | 671 bool DownloadManagerImpl::GenerateFileHash() { |
| 765 return delegate_ && delegate_->GenerateFileHash(); | 672 return delegate_ && delegate_->GenerateFileHash(); |
| 766 } | 673 } |
| 767 | 674 |
| 675 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( |
| 676 scoped_ptr<content::DownloadFileFactory> file_factory) { |
| 677 file_factory_ = file_factory.Pass(); |
| 678 } |
| 679 |
| 680 content::DownloadFileFactory* |
| 681 DownloadManagerImpl::GetDownloadFileFactoryForTesting() { |
| 682 return file_factory_.get(); |
| 683 } |
| 684 |
| 768 int DownloadManagerImpl::RemoveDownloadItems( | 685 int DownloadManagerImpl::RemoveDownloadItems( |
| 769 const DownloadItemImplVector& pending_deletes) { | 686 const DownloadItemImplVector& pending_deletes) { |
| 770 if (pending_deletes.empty()) | 687 if (pending_deletes.empty()) |
| 771 return 0; | 688 return 0; |
| 772 | 689 |
| 773 // Delete from internal maps. | 690 // Delete from internal maps. |
| 774 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); | 691 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); |
| 775 it != pending_deletes.end(); | 692 it != pending_deletes.end(); |
| 776 ++it) { | 693 ++it) { |
| 777 DownloadItemImpl* download = *it; | 694 DownloadItemImpl* download = *it; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). | 782 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). |
| 866 void DownloadManagerImpl::OnPersistentStoreQueryComplete( | 783 void DownloadManagerImpl::OnPersistentStoreQueryComplete( |
| 867 std::vector<DownloadPersistentStoreInfo>* entries) { | 784 std::vector<DownloadPersistentStoreInfo>* entries) { |
| 868 history_size_ = entries->size(); | 785 history_size_ = entries->size(); |
| 869 for (size_t i = 0; i < entries->size(); ++i) { | 786 for (size_t i = 0; i < entries->size(); ++i) { |
| 870 int64 db_handle = entries->at(i).db_handle; | 787 int64 db_handle = entries->at(i).db_handle; |
| 871 base::debug::Alias(&db_handle); | 788 base::debug::Alias(&db_handle); |
| 872 | 789 |
| 873 net::BoundNetLog bound_net_log = | 790 net::BoundNetLog bound_net_log = |
| 874 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 791 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
| 875 DownloadItemImpl* download = factory_->CreatePersistedItem( | 792 DownloadItemImpl* download = item_factory_->CreatePersistedItem( |
| 876 this, GetNextId(), entries->at(i), bound_net_log); | 793 this, GetNextId(), entries->at(i), bound_net_log); |
| 877 DCHECK(!ContainsKey(downloads_, download->GetId())); | 794 DCHECK(!ContainsKey(downloads_, download->GetId())); |
| 878 downloads_[download->GetId()] = download; | 795 downloads_[download->GetId()] = download; |
| 879 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 796 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
| 880 VLOG(20) << __FUNCTION__ << "()" << i << ">" | 797 VLOG(20) << __FUNCTION__ << "()" << i << ">" |
| 881 << " download = " << download->DebugString(true); | 798 << " download = " << download->DebugString(true); |
| 882 } | 799 } |
| 883 NotifyModelChanged(); | 800 NotifyModelChanged(); |
| 884 CheckForHistoryFilesRemoval(); | 801 CheckForHistoryFilesRemoval(); |
| 885 } | 802 } |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 ++num_unopened; | 997 ++num_unopened; |
| 1081 } | 998 } |
| 1082 download_stats::RecordOpensOutstanding(num_unopened); | 999 download_stats::RecordOpensOutstanding(num_unopened); |
| 1083 } | 1000 } |
| 1084 | 1001 |
| 1085 void DownloadManagerImpl::DownloadRenamedToIntermediateName( | 1002 void DownloadManagerImpl::DownloadRenamedToIntermediateName( |
| 1086 DownloadItemImpl* download) { | 1003 DownloadItemImpl* download) { |
| 1087 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1004 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1088 // download->GetFullPath() is only expected to be meaningful after this | 1005 // download->GetFullPath() is only expected to be meaningful after this |
| 1089 // callback is received. Therefore we can now add the download to a persistent | 1006 // callback is received. Therefore we can now add the download to a persistent |
| 1090 // store. If the rename failed, we receive an OnDownloadInterrupted() call | 1007 // store. If the rename failed, we processed an interrupt |
| 1091 // before we receive the DownloadRenamedToIntermediateName() call. | 1008 // before we receive the DownloadRenamedToIntermediateName() call. |
| 1092 if (delegate_) { | 1009 if (delegate_) { |
| 1093 delegate_->AddItemToPersistentStore(download); | 1010 delegate_->AddItemToPersistentStore(download); |
| 1094 } else { | 1011 } else { |
| 1095 OnItemAddedToPersistentStore(download->GetId(), | 1012 OnItemAddedToPersistentStore(download->GetId(), |
| 1096 DownloadItem::kUninitializedHandle); | 1013 DownloadItem::kUninitializedHandle); |
| 1097 } | 1014 } |
| 1098 } | 1015 } |
| 1099 | 1016 |
| 1100 void DownloadManagerImpl::DownloadRenamedToFinalName( | 1017 void DownloadManagerImpl::DownloadRenamedToFinalName( |
| 1101 DownloadItemImpl* download) { | 1018 DownloadItemImpl* download) { |
| 1102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1019 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1103 // If the rename failed, we receive an OnDownloadInterrupted() call before we | 1020 // If the rename failed, we processed an interrupt before we get here. |
| 1104 // receive the DownloadRenamedToFinalName() call. | |
| 1105 if (delegate_) { | 1021 if (delegate_) { |
| 1106 delegate_->UpdatePathForItemInPersistentStore( | 1022 delegate_->UpdatePathForItemInPersistentStore( |
| 1107 download, download->GetFullPath()); | 1023 download, download->GetFullPath()); |
| 1108 } | 1024 } |
| 1109 } | 1025 } |
| OLD | NEW |