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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 using content::BrowserThread; | 45 using content::BrowserThread; |
46 using content::DownloadId; | 46 using content::DownloadId; |
47 using content::DownloadItem; | 47 using content::DownloadItem; |
48 using content::DownloadPersistentStoreInfo; | 48 using content::DownloadPersistentStoreInfo; |
49 using content::ResourceDispatcherHostImpl; | 49 using content::ResourceDispatcherHostImpl; |
50 using content::WebContents; | 50 using content::WebContents; |
51 | 51 |
52 namespace { | 52 namespace { |
53 | 53 |
54 // This is just used to remember which DownloadItems come from SavePage. | 54 // This is just used to remember which DownloadItems come from SavePage. |
55 class SavePageExternalData : public DownloadItem::ExternalData { | 55 class SavePageData : public base::SupportsUserData::Data { |
56 public: | 56 public: |
57 // A spoonful of syntactic sugar. | 57 // A spoonful of syntactic sugar. |
58 static bool Get(DownloadItem* item) { | 58 static bool Get(DownloadItem* item) { |
59 return item->GetExternalData(kKey) != NULL; | 59 return item->GetUserData(kKey) != NULL; |
60 } | 60 } |
61 | 61 |
62 explicit SavePageExternalData(DownloadItem* item) { | 62 explicit SavePageData(DownloadItem* item) { |
63 item->SetExternalData(kKey, this); | 63 item->SetUserData(kKey, this); |
64 } | 64 } |
65 | 65 |
66 virtual ~SavePageExternalData() {} | 66 virtual ~SavePageData() {} |
67 | 67 |
68 private: | 68 private: |
69 static const char kKey[]; | 69 static const char kKey[]; |
70 | 70 |
71 DISALLOW_COPY_AND_ASSIGN(SavePageExternalData); | 71 DISALLOW_COPY_AND_ASSIGN(SavePageData); |
72 }; | 72 }; |
73 | 73 |
74 const char SavePageExternalData::kKey[] = "DownloadItem SavePageExternalData"; | 74 const char SavePageData::kKey[] = "DownloadItem SavePageData"; |
75 | 75 |
76 void BeginDownload(content::DownloadUrlParameters* params) { | 76 void BeginDownload(content::DownloadUrlParameters* params) { |
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
78 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and | 78 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and |
79 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so | 79 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so |
80 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. | 80 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. |
81 scoped_ptr<net::URLRequest> request(new net::URLRequest( | 81 scoped_ptr<net::URLRequest> request(new net::URLRequest( |
82 params->url(), | 82 params->url(), |
83 NULL, | 83 NULL, |
84 params->resource_context()->GetRequestContext())); | 84 params->resource_context()->GetRequestContext())); |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 // from the disk. This may or may not result in it being | 305 // from the disk. This may or may not result in it being |
306 // removed from the DownloadManager queues and deleted | 306 // removed from the DownloadManager queues and deleted |
307 // (specifically, DownloadManager::DownloadRemoved only | 307 // (specifically, DownloadManager::DownloadRemoved only |
308 // removes and deletes it if it's known to the history service) | 308 // removes and deletes it if it's known to the history service) |
309 // so the only thing we know after calling this function is that | 309 // so the only thing we know after calling this function is that |
310 // the download was deleted if-and-only-if it was removed | 310 // the download was deleted if-and-only-if it was removed |
311 // from all queues. | 311 // from all queues. |
312 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN); | 312 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN); |
313 } else if (download->IsPartialDownload()) { | 313 } else if (download->IsPartialDownload()) { |
314 download->Cancel(false); | 314 download->Cancel(false); |
315 if (delegate_) | |
316 delegate_->UpdateItemInPersistentStore(download); | |
317 } | 315 } |
318 } | 316 } |
319 | 317 |
320 // At this point, all dangerous downloads have had their files removed | 318 // At this point, all dangerous downloads have had their files removed |
321 // and all in progress downloads have been cancelled. We can now delete | 319 // and all in progress downloads have been cancelled. We can now delete |
322 // anything left. | 320 // anything left. |
323 | 321 |
324 // Copy downloads_ to separate container so as not to set off checks | |
325 // in DownloadItem destruction. | |
326 DownloadMap downloads_to_delete; | |
327 downloads_to_delete.swap(downloads_); | |
328 | |
329 active_downloads_.clear(); | 322 active_downloads_.clear(); |
330 STLDeleteValues(&downloads_to_delete); | 323 STLDeleteValues(&downloads_); |
| 324 downloads_.clear(); |
331 | 325 |
332 // We'll have nothing more to report to the observers after this point. | 326 // We'll have nothing more to report to the observers after this point. |
333 observers_.Clear(); | 327 observers_.Clear(); |
334 | 328 |
335 file_manager_ = NULL; | 329 file_manager_ = NULL; |
336 if (delegate_) | 330 if (delegate_) |
337 delegate_->Shutdown(); | 331 delegate_->Shutdown(); |
338 delegate_ = NULL; | 332 delegate_ = NULL; |
339 } | 333 } |
340 | 334 |
341 void DownloadManagerImpl::GetTemporaryDownloads( | 335 void DownloadManagerImpl::GetTemporaryDownloads( |
342 const FilePath& dir_path, DownloadVector* result) { | 336 const FilePath& dir_path, DownloadVector* result) { |
343 DCHECK(result); | 337 DCHECK(result); |
344 | 338 |
345 for (DownloadMap::iterator it = downloads_.begin(); | 339 for (DownloadMap::iterator it = downloads_.begin(); |
346 it != downloads_.end(); ++it) { | 340 it != downloads_.end(); ++it) { |
347 DownloadItemImpl* item = it->second; | 341 DownloadItemImpl* item = it->second; |
348 // TODO(benjhayden): Don't check IsPersisted(). | |
349 if (item->IsTemporary() && | 342 if (item->IsTemporary() && |
350 item->IsPersisted() && | |
351 (dir_path.empty() || | 343 (dir_path.empty() || |
352 item->GetTargetFilePath().DirName() == dir_path)) | 344 item->GetTargetFilePath().DirName() == dir_path)) |
353 result->push_back(item); | 345 result->push_back(item); |
354 } | 346 } |
355 } | 347 } |
356 | 348 |
357 void DownloadManagerImpl::GetAllDownloads( | 349 void DownloadManagerImpl::GetAllDownloads( |
358 const FilePath& dir_path, DownloadVector* result) { | 350 const FilePath& dir_path, DownloadVector* result) { |
359 DCHECK(result); | 351 DCHECK(result); |
360 | 352 |
361 for (DownloadMap::iterator it = downloads_.begin(); | 353 for (DownloadMap::iterator it = downloads_.begin(); |
362 it != downloads_.end(); ++it) { | 354 it != downloads_.end(); ++it) { |
363 DownloadItemImpl* item = it->second; | 355 DownloadItemImpl* item = it->second; |
364 // TODO(benjhayden): Don't check IsPersisted(). | |
365 if (!item->IsTemporary() && | 356 if (!item->IsTemporary() && |
366 item->IsPersisted() && | |
367 (dir_path.empty() || | 357 (dir_path.empty() || |
368 item->GetTargetFilePath().DirName() == dir_path)) | 358 item->GetTargetFilePath().DirName() == dir_path)) |
369 result->push_back(item); | 359 result->push_back(item); |
370 } | 360 } |
371 } | 361 } |
372 | 362 |
373 void DownloadManagerImpl::SearchDownloads(const string16& query, | 363 void DownloadManagerImpl::SearchDownloads(const string16& query, |
374 DownloadVector* result) { | 364 DownloadVector* result) { |
375 string16 query_lower(base::i18n::ToLower(query)); | 365 string16 query_lower(base::i18n::ToLower(query)); |
376 | 366 |
377 for (DownloadMap::iterator it = downloads_.begin(); | 367 for (DownloadMap::iterator it = downloads_.begin(); |
378 it != downloads_.end(); ++it) { | 368 it != downloads_.end(); ++it) { |
379 DownloadItemImpl* download_item = it->second; | 369 DownloadItemImpl* download_item = it->second; |
380 // Display Incognito downloads only in Incognito window, and vice versa. | 370 // Display Incognito downloads only in Incognito window, and vice versa. |
381 // The Incognito Downloads page will get the list of non-Incognito downloads | 371 // The Incognito Downloads page will get the list of non-Incognito downloads |
382 // from its parent profile. | 372 // from its parent profile. |
383 // TODO(benjhayden): Don't check IsPersisted(). | |
384 if (!download_item->IsTemporary() && | 373 if (!download_item->IsTemporary() && |
385 download_item->IsPersisted() && | |
386 (browser_context_->IsOffTheRecord() == download_item->IsOtr()) && | 374 (browser_context_->IsOffTheRecord() == download_item->IsOtr()) && |
387 download_item->MatchesQuery(query_lower)) { | 375 download_item->MatchesQuery(query_lower)) { |
388 result->push_back(download_item); | 376 result->push_back(download_item); |
389 } | 377 } |
390 } | 378 } |
391 } | 379 } |
392 | 380 |
393 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { | 381 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { |
394 DCHECK(browser_context); | 382 DCHECK(browser_context); |
395 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; | 383 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 } | 449 } |
462 } | 450 } |
463 | 451 |
464 void DownloadManagerImpl::OnDownloadTargetDetermined( | 452 void DownloadManagerImpl::OnDownloadTargetDetermined( |
465 int32 download_id, | 453 int32 download_id, |
466 const FilePath& target_path, | 454 const FilePath& target_path, |
467 DownloadItem::TargetDisposition disposition, | 455 DownloadItem::TargetDisposition disposition, |
468 content::DownloadDangerType danger_type, | 456 content::DownloadDangerType danger_type, |
469 const FilePath& intermediate_path) { | 457 const FilePath& intermediate_path) { |
470 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 458 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
471 DownloadMap::iterator download_iter = active_downloads_.find(download_id); | 459 DownloadMap::iterator download_iter = downloads_.find(download_id); |
472 if (download_iter != active_downloads_.end()) { | 460 if (download_iter == downloads_.end()) |
473 // Once DownloadItem::OnDownloadTargetDetermined() is called, we expect a | 461 return; |
474 // DownloadRenamedToIntermediateName() callback. This is necessary for the | 462 |
475 // download to proceed. | 463 // Once DownloadItem::OnDownloadTargetDetermined() is called, we expect a |
476 download_iter->second->OnDownloadTargetDetermined( | 464 // DownloadRenamedToIntermediateName() callback. This is necessary for the |
477 target_path, disposition, danger_type, intermediate_path); | 465 // download to proceed. |
| 466 DownloadItemImpl* item = download_iter->second; |
| 467 item->OnDownloadTargetDetermined( |
| 468 target_path, disposition, danger_type, intermediate_path); |
| 469 ShowDownloadInBrowser(item); |
| 470 NotifyModelChanged(); |
| 471 if (!SavePageData::Get(item)) { |
| 472 MaybeCompleteDownload(item); |
478 } | 473 } |
479 } | 474 } |
480 | 475 |
481 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { | 476 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { |
482 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
483 for (DownloadMap::iterator it = downloads_.begin(); | 478 for (DownloadMap::iterator it = downloads_.begin(); |
484 it != downloads_.end(); ++it) { | 479 it != downloads_.end(); ++it) { |
485 DownloadItemImpl* item = it->second; | 480 DownloadItemImpl* item = it->second; |
486 if (item->IsPersisted()) | 481 CheckForFileRemoval(item); |
487 CheckForFileRemoval(item); | |
488 } | 482 } |
489 } | 483 } |
490 | 484 |
491 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { | 485 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { |
492 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 486 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
493 if (download_item->IsComplete() && | 487 if (download_item->IsComplete() && |
494 !download_item->GetFileExternallyRemoved()) { | 488 !download_item->GetFileExternallyRemoved()) { |
495 BrowserThread::PostTask( | 489 BrowserThread::PostTask( |
496 BrowserThread::FILE, FROM_HERE, | 490 BrowserThread::FILE, FROM_HERE, |
497 base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread, | 491 base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 } | 540 } |
547 | 541 |
548 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( | 542 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( |
549 const FilePath& main_file_path, | 543 const FilePath& main_file_path, |
550 const GURL& page_url, | 544 const GURL& page_url, |
551 bool is_otr, | 545 bool is_otr, |
552 const std::string& mime_type, | 546 const std::string& mime_type, |
553 DownloadItem::Observer* observer) { | 547 DownloadItem::Observer* observer) { |
554 net::BoundNetLog bound_net_log = | 548 net::BoundNetLog bound_net_log = |
555 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 549 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
556 DownloadItemImpl* download = factory_->CreateSavePageItem( | 550 DownloadItemImpl* download_item = factory_->CreateSavePageItem( |
557 this, | 551 this, |
558 main_file_path, | 552 main_file_path, |
559 page_url, | 553 page_url, |
560 is_otr, | 554 is_otr, |
561 GetNextId(), | 555 GetNextId(), |
562 mime_type, | 556 mime_type, |
563 bound_net_log); | 557 bound_net_log); |
564 | 558 download_item->AddObserver(observer); |
565 download->AddObserver(observer); | 559 DCHECK(!ContainsKey(downloads_, download_item->GetId())); |
566 | 560 downloads_[download_item->GetId()] = download_item; |
567 DCHECK(!ContainsKey(downloads_, download->GetId())); | 561 DCHECK(!SavePageData::Get(download_item)); |
568 downloads_[download->GetId()] = download; | 562 new SavePageData(download_item); |
569 DCHECK(!SavePageExternalData::Get(download)); | 563 DCHECK(SavePageData::Get(download_item)); |
570 new SavePageExternalData(download); | 564 // TODO(benjhayden) XXX occam test showing SavePackage DownloadItems in ui |
571 DCHECK(SavePageExternalData::Get(download)); | 565 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated( |
572 | 566 this, download_item)); |
573 // TODO(benjhayden): Fire OnDownloadCreated for SavePackage downloads when | 567 return download_item; |
574 // we're comfortable with the user interacting with them. | |
575 // FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | |
576 | |
577 // Will notify the observer in the callback. | |
578 if (delegate_) | |
579 delegate_->AddItemToPersistentStore(download); | |
580 | |
581 return download; | |
582 } | 568 } |
583 | 569 |
584 void DownloadManagerImpl::UpdateDownload(int32 download_id, | 570 void DownloadManagerImpl::UpdateDownload(int32 download_id, |
585 int64 bytes_so_far, | 571 int64 bytes_so_far, |
586 int64 bytes_per_sec, | 572 int64 bytes_per_sec, |
587 const std::string& hash_state) { | 573 const std::string& hash_state) { |
588 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 574 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
589 DownloadMap::iterator it = active_downloads_.find(download_id); | 575 DownloadMap::iterator it = active_downloads_.find(download_id); |
590 if (it != active_downloads_.end()) { | 576 if (it != active_downloads_.end()) { |
591 DownloadItemImpl* download = it->second; | 577 DownloadItemImpl* download = it->second; |
592 if (download->IsInProgress()) { | 578 if (download->IsInProgress()) { |
593 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); | 579 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); |
594 if (delegate_) | |
595 delegate_->UpdateItemInPersistentStore(download); | |
596 } | 580 } |
597 } | 581 } |
598 } | 582 } |
599 | 583 |
600 void DownloadManagerImpl::OnResponseCompleted(int32 download_id, | 584 void DownloadManagerImpl::OnResponseCompleted(int32 download_id, |
601 int64 size, | 585 int64 size, |
602 const std::string& hash) { | 586 const std::string& hash) { |
603 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 587 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
604 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 588 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
605 << " size = " << size; | 589 << " size = " << size; |
606 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 590 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
607 | 591 |
608 // If it's not in active_downloads_, that means it was cancelled; just | 592 // If it's not in active_downloads_, that means it was cancelled; just |
609 // ignore the notification. | 593 // ignore the notification. |
610 if (active_downloads_.count(download_id) == 0) | 594 if (active_downloads_.count(download_id) == 0) |
611 return; | 595 return; |
612 | 596 |
613 DownloadItemImpl* download = active_downloads_[download_id]; | 597 DownloadItemImpl* download = active_downloads_[download_id]; |
614 download->OnAllDataSaved(size, hash); | 598 download->OnAllDataSaved(size, hash); |
615 MaybeCompleteDownload(download); | 599 MaybeCompleteDownload(download); |
616 } | 600 } |
617 | 601 |
618 void DownloadManagerImpl::AssertStateConsistent( | 602 void DownloadManagerImpl::AssertStateConsistent( |
619 DownloadItemImpl* download) const { | 603 DownloadItemImpl* download) const { |
620 if (download->GetState() == DownloadItem::REMOVING) { | |
621 DCHECK(!ContainsKey(downloads_, download->GetId())); | |
622 DCHECK(!ContainsKey(active_downloads_, download->GetId())); | |
623 return; | |
624 } | |
625 | |
626 // Should be in downloads_ if we're not REMOVING. | |
627 CHECK(ContainsKey(downloads_, download->GetId())); | 604 CHECK(ContainsKey(downloads_, download->GetId())); |
628 | 605 |
629 int64 state = download->GetState(); | 606 int64 state = download->GetState(); |
630 base::debug::Alias(&state); | 607 base::debug::Alias(&state); |
631 if (ContainsKey(active_downloads_, download->GetId())) { | |
632 if (download->IsPersisted()) | |
633 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState()); | |
634 if (DownloadItem::IN_PROGRESS != download->GetState()) | |
635 CHECK_EQ(DownloadItem::kUninitializedHandle, download->GetDbHandle()); | |
636 } | |
637 if (DownloadItem::IN_PROGRESS == download->GetState()) | 608 if (DownloadItem::IN_PROGRESS == download->GetState()) |
638 CHECK(ContainsKey(active_downloads_, download->GetId())); | 609 CHECK(ContainsKey(active_downloads_, download->GetId())); |
639 } | 610 } |
640 | 611 |
641 bool DownloadManagerImpl::IsDownloadReadyForCompletion( | 612 bool DownloadManagerImpl::IsDownloadReadyForCompletion( |
642 DownloadItemImpl* download) { | 613 DownloadItemImpl* download) { |
643 // If we don't have all the data, the download is not ready for | 614 // If we don't have all the data, the download is not ready for |
644 // completion. | 615 // completion. |
645 if (!download->AllDataSaved()) | 616 if (!download->AllDataSaved()) |
646 return false; | 617 return false; |
647 | 618 |
648 // If the download is dangerous, but not yet validated, it's not ready for | 619 // If the download is dangerous, but not yet validated, it's not ready for |
649 // completion. | 620 // completion. |
650 if (download->GetSafetyState() == DownloadItem::DANGEROUS) | 621 if (download->GetSafetyState() == DownloadItem::DANGEROUS) |
651 return false; | 622 return false; |
652 | 623 |
653 // If the download isn't active (e.g. has been cancelled) it's not | 624 // If the download isn't active (e.g. has been cancelled) it's not |
654 // ready for completion. | 625 // ready for completion. |
655 if (active_downloads_.count(download->GetId()) == 0) | 626 if (active_downloads_.count(download->GetId()) == 0) |
656 return false; | 627 return false; |
657 | 628 |
658 // If the download hasn't been inserted into the history system | |
659 // (which occurs strictly after file name determination, intermediate | |
660 // file rename, and UI display) then it's not ready for completion. | |
661 if (!download->IsPersisted()) | |
662 return false; | |
663 | |
664 return true; | 629 return true; |
665 } | 630 } |
666 | 631 |
667 // When SavePackage downloads MHTML to GData (see | 632 // When SavePackage downloads MHTML to GData (see |
668 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it | 633 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it |
669 // does for non-SavePackage downloads, but SavePackage downloads never satisfy | 634 // does for non-SavePackage downloads, but SavePackage downloads never satisfy |
670 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls | 635 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls |
671 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage | 636 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage |
672 // notices that the upload has completed and runs its normal Finish() pathway. | 637 // notices that the upload has completed and runs its normal Finish() pathway. |
673 // MaybeCompleteDownload() is never the mechanism by which SavePackage completes | 638 // MaybeCompleteDownload() is never the mechanism by which SavePackage completes |
(...skipping 11 matching lines...) Expand all Loading... |
685 | 650 |
686 // TODO(rdsmith): DCHECK that we only pass through this point | 651 // TODO(rdsmith): DCHECK that we only pass through this point |
687 // once per download. The natural way to do this is by a state | 652 // once per download. The natural way to do this is by a state |
688 // transition on the DownloadItem. | 653 // transition on the DownloadItem. |
689 | 654 |
690 // Confirm we're in the proper set of states to be here; | 655 // Confirm we're in the proper set of states to be here; |
691 // have all data, have a history handle, (validated or safe). | 656 // have all data, have a history handle, (validated or safe). |
692 DCHECK(download->IsInProgress()); | 657 DCHECK(download->IsInProgress()); |
693 DCHECK_NE(DownloadItem::DANGEROUS, download->GetSafetyState()); | 658 DCHECK_NE(DownloadItem::DANGEROUS, download->GetSafetyState()); |
694 DCHECK(download->AllDataSaved()); | 659 DCHECK(download->AllDataSaved()); |
695 DCHECK(download->IsPersisted()); | |
696 | 660 |
697 // Give the delegate a chance to override. It's ok to keep re-setting the | 661 // Give the delegate a chance to override. It's ok to keep re-setting the |
698 // delegate's |complete_callback| cb as long as there isn't another call-point | 662 // delegate's |complete_callback| cb as long as there isn't another call-point |
699 // trying to set it to a different cb. TODO(benjhayden): Change the callback | 663 // trying to set it to a different cb. TODO(benjhayden): Change the callback |
700 // to point directly to the item instead of |this| when DownloadItem supports | 664 // to point directly to the item instead of |this| when DownloadItem supports |
701 // weak-ptrs. | 665 // weak-ptrs. |
702 if (delegate_ && !delegate_->ShouldCompleteDownload(download, base::Bind( | 666 if (delegate_ && !delegate_->ShouldCompleteDownload(download, base::Bind( |
703 &DownloadManagerImpl::MaybeCompleteDownloadById, | 667 &DownloadManagerImpl::MaybeCompleteDownloadById, |
704 this, download->GetId()))) | 668 this, download->GetId()))) |
705 return; | 669 return; |
706 | 670 |
707 VLOG(20) << __FUNCTION__ << "()" << " executing: download = " | 671 VLOG(20) << __FUNCTION__ << "()" << " executing: download = " |
708 << download->DebugString(false); | 672 << download->DebugString(false); |
709 | 673 |
710 if (delegate_) | |
711 delegate_->UpdateItemInPersistentStore(download); | |
712 download->OnDownloadCompleting(); | 674 download->OnDownloadCompleting(); |
713 } | 675 } |
714 | 676 |
715 void DownloadManagerImpl::MaybeCompleteDownloadById(int download_id) { | 677 void DownloadManagerImpl::MaybeCompleteDownloadById(int download_id) { |
716 if (ContainsKey(active_downloads_, download_id)) | 678 if (ContainsKey(active_downloads_, download_id)) |
717 MaybeCompleteDownload(active_downloads_[download_id]); | 679 MaybeCompleteDownload(active_downloads_[download_id]); |
718 } | 680 } |
719 | 681 |
720 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { | 682 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { |
721 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 683 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
722 DCHECK(download); | 684 DCHECK(download); |
723 if (delegate_) | |
724 delegate_->UpdateItemInPersistentStore(download); | |
725 active_downloads_.erase(download->GetId()); | 685 active_downloads_.erase(download->GetId()); |
726 AssertStateConsistent(download); | 686 AssertStateConsistent(download); |
727 } | 687 } |
728 | 688 |
729 void DownloadManagerImpl::CancelDownload(int32 download_id) { | 689 void DownloadManagerImpl::CancelDownload(int32 download_id) { |
730 // A cancel at the right time could remove the download from the | 690 // A cancel at the right time could remove the download from the |
731 // |active_downloads_| map before we get here. | 691 // |active_downloads_| map before we get here. |
732 if (ContainsKey(active_downloads_, download_id)) | 692 if (ContainsKey(active_downloads_, download_id)) |
733 active_downloads_[download_id]->Cancel(true); | 693 active_downloads_[download_id]->Cancel(true); |
734 } | 694 } |
(...skipping 19 matching lines...) Expand all Loading... |
754 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 714 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
755 | 715 |
756 if (!ContainsKey(active_downloads_, download_id)) | 716 if (!ContainsKey(active_downloads_, download_id)) |
757 return; | 717 return; |
758 active_downloads_[download_id]->Interrupt(reason); | 718 active_downloads_[download_id]->Interrupt(reason); |
759 } | 719 } |
760 | 720 |
761 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { | 721 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { |
762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 722 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
763 DCHECK(download); | 723 DCHECK(download); |
764 | 724 active_downloads_.erase(download->GetId()); |
765 // Clean up will happen when the history system create callback runs if we | |
766 // don't have a valid db_handle yet. | |
767 if (download->IsPersisted()) { | |
768 active_downloads_.erase(download->GetId()); | |
769 if (delegate_) | |
770 delegate_->UpdateItemInPersistentStore(download); | |
771 } | |
772 } | 725 } |
773 | 726 |
774 bool DownloadManagerImpl::GenerateFileHash() { | 727 bool DownloadManagerImpl::GenerateFileHash() { |
775 return delegate_ && delegate_->GenerateFileHash(); | 728 return delegate_ && delegate_->GenerateFileHash(); |
776 } | 729 } |
777 | 730 |
778 int DownloadManagerImpl::RemoveDownloadItems( | 731 int DownloadManagerImpl::RemoveDownloadItems( |
779 const DownloadItemImplVector& pending_deletes) { | 732 const DownloadItemImplVector& pending_deletes) { |
780 if (pending_deletes.empty()) | 733 if (pending_deletes.empty()) |
781 return 0; | 734 return 0; |
782 | 735 |
783 // Delete from internal maps. | 736 // Delete from internal maps. |
784 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); | 737 for (DownloadItemImplVector::const_iterator it = pending_deletes.begin(); |
785 it != pending_deletes.end(); | 738 it != pending_deletes.end(); |
786 ++it) { | 739 ++it) { |
787 DownloadItemImpl* download = *it; | 740 DownloadItemImpl* download = *it; |
788 DCHECK(download); | 741 DCHECK(download); |
789 downloads_.erase(download->GetId()); | 742 int32 download_id = download->GetId(); |
| 743 delete download; |
| 744 downloads_.erase(download_id); |
790 } | 745 } |
791 | |
792 // Tell observers to refresh their views. | |
793 NotifyModelChanged(); | 746 NotifyModelChanged(); |
794 | 747 return static_cast<int>(pending_deletes.size()); |
795 // Delete the download items themselves. | |
796 const int num_deleted = static_cast<int>(pending_deletes.size()); | |
797 STLDeleteContainerPointers(pending_deletes.begin(), pending_deletes.end()); | |
798 return num_deleted; | |
799 } | 748 } |
800 | 749 |
801 void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) { | 750 void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) { |
802 if (!download || | 751 if (!download || |
803 downloads_.find(download->GetId()) == downloads_.end()) | 752 downloads_.find(download->GetId()) == downloads_.end()) |
804 return; | 753 return; |
805 | 754 |
806 // TODO(benjhayden,rdsmith): Remove this. | |
807 if (!download->IsPersisted()) | |
808 return; | |
809 | |
810 // Make history update. | |
811 if (delegate_) | |
812 delegate_->RemoveItemFromPersistentStore(download); | |
813 | |
814 // Remove from our tables and delete. | 755 // Remove from our tables and delete. |
815 int downloads_count = | 756 int downloads_count = |
816 RemoveDownloadItems(DownloadItemImplVector(1, download)); | 757 RemoveDownloadItems(DownloadItemImplVector(1, download)); |
817 DCHECK_EQ(1, downloads_count); | 758 DCHECK_EQ(1, downloads_count); |
818 } | 759 } |
819 | 760 |
820 int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin, | 761 int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin, |
821 base::Time remove_end) { | 762 base::Time remove_end) { |
822 if (delegate_) | |
823 delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end); | |
824 | |
825 // All downloads visible to the user will be in the history, | |
826 // so scan that map. | |
827 DownloadItemImplVector pending_deletes; | 763 DownloadItemImplVector pending_deletes; |
828 for (DownloadMap::const_iterator it = downloads_.begin(); | 764 for (DownloadMap::const_iterator it = downloads_.begin(); |
829 it != downloads_.end(); | 765 it != downloads_.end(); |
830 ++it) { | 766 ++it) { |
831 DownloadItemImpl* download = it->second; | 767 DownloadItemImpl* download = it->second; |
832 if (download->IsPersisted() && | 768 if (download->GetStartTime() >= remove_begin && |
833 download->GetStartTime() >= remove_begin && | |
834 (remove_end.is_null() || download->GetStartTime() < remove_end) && | 769 (remove_end.is_null() || download->GetStartTime() < remove_end) && |
835 (download->IsComplete() || download->IsCancelled())) { | 770 (download->IsComplete() || download->IsCancelled())) { |
836 AssertStateConsistent(download); | 771 AssertStateConsistent(download); |
| 772 download->NotifyRemoved(); |
837 pending_deletes.push_back(download); | 773 pending_deletes.push_back(download); |
838 } | 774 } |
839 } | 775 } |
840 return RemoveDownloadItems(pending_deletes); | 776 return RemoveDownloadItems(pending_deletes); |
841 } | 777 } |
842 | 778 |
843 int DownloadManagerImpl::RemoveDownloads(base::Time remove_begin) { | 779 int DownloadManagerImpl::RemoveDownloads(base::Time remove_begin) { |
844 return RemoveDownloadsBetween(remove_begin, base::Time()); | 780 return RemoveDownloadsBetween(remove_begin, base::Time()); |
845 } | 781 } |
846 | 782 |
(...skipping 28 matching lines...) Expand all Loading... |
875 } | 811 } |
876 | 812 |
877 // Operations posted to us from the history service ---------------------------- | 813 // Operations posted to us from the history service ---------------------------- |
878 | 814 |
879 // The history service has retrieved all download entries. 'entries' contains | 815 // The history service has retrieved all download entries. 'entries' contains |
880 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). | 816 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). |
881 void DownloadManagerImpl::OnPersistentStoreQueryComplete( | 817 void DownloadManagerImpl::OnPersistentStoreQueryComplete( |
882 std::vector<DownloadPersistentStoreInfo>* entries) { | 818 std::vector<DownloadPersistentStoreInfo>* entries) { |
883 history_size_ = entries->size(); | 819 history_size_ = entries->size(); |
884 for (size_t i = 0; i < entries->size(); ++i) { | 820 for (size_t i = 0; i < entries->size(); ++i) { |
885 int64 db_handle = entries->at(i).db_handle; | |
886 base::debug::Alias(&db_handle); | |
887 | |
888 net::BoundNetLog bound_net_log = | 821 net::BoundNetLog bound_net_log = |
889 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | 822 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
890 DownloadItemImpl* download = factory_->CreatePersistedItem( | 823 DownloadItemImpl* download = factory_->CreatePersistedItem( |
891 this, GetNextId(), entries->at(i), bound_net_log); | 824 this, GetNextId(), entries->at(i), bound_net_log); |
892 DCHECK(!ContainsKey(downloads_, download->GetId())); | 825 DCHECK(!ContainsKey(downloads_, download->GetId())); |
893 downloads_[download->GetId()] = download; | 826 downloads_[download->GetId()] = download; |
894 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 827 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
895 VLOG(20) << __FUNCTION__ << "()" << i << ">" | 828 VLOG(20) << __FUNCTION__ << "()" << i << ">" |
896 << " download = " << download->DebugString(true); | 829 << " download = " << download->DebugString(true); |
897 } | 830 } |
898 NotifyModelChanged(); | 831 NotifyModelChanged(); |
899 CheckForHistoryFilesRemoval(); | 832 CheckForHistoryFilesRemoval(); |
900 } | 833 } |
901 | 834 |
902 void DownloadManagerImpl::AddDownloadItemToHistory(DownloadItemImpl* download, | |
903 int64 db_handle) { | |
904 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
905 DCHECK_NE(DownloadItem::kUninitializedHandle, db_handle); | |
906 DCHECK(!download->IsPersisted()); | |
907 download->SetDbHandle(db_handle); | |
908 download->SetIsPersisted(); | |
909 | |
910 download_stats::RecordHistorySize(history_size_); | |
911 // Not counting |download|. | |
912 ++history_size_; | |
913 | |
914 // Show in the appropriate browser UI. | |
915 // This includes buttons to save or cancel, for a dangerous download. | |
916 ShowDownloadInBrowser(download); | |
917 | |
918 // Inform interested objects about the new download. | |
919 NotifyModelChanged(); | |
920 } | |
921 | |
922 | |
923 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id, | |
924 int64 db_handle) { | |
925 // It's valid that we don't find a matching item, i.e. on shutdown. | |
926 if (!ContainsKey(downloads_, download_id)) | |
927 return; | |
928 | |
929 DownloadItemImpl* item = downloads_[download_id]; | |
930 AddDownloadItemToHistory(item, db_handle); | |
931 if (SavePageExternalData::Get(item)) { | |
932 OnSavePageItemAddedToPersistentStore(item); | |
933 } else { | |
934 OnDownloadItemAddedToPersistentStore(item); | |
935 } | |
936 } | |
937 | |
938 // Once the new DownloadItem has been committed to the persistent store, | |
939 // associate it with its db_handle (TODO(benjhayden) merge db_handle with id), | |
940 // show it in the browser (TODO(benjhayden) the ui should observe us instead), | |
941 // and notify observers (TODO(benjhayden) observers should be able to see the | |
942 // item when it's created so they can observe it directly. Are there any | |
943 // clients that actually need to know when the item is added to the history?). | |
944 void DownloadManagerImpl::OnDownloadItemAddedToPersistentStore( | |
945 DownloadItemImpl* item) { | |
946 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
947 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << item->GetDbHandle() | |
948 << " download_id = " << item->GetId() | |
949 << " download = " << item->DebugString(true); | |
950 | |
951 // If the download is still in progress, try to complete it. | |
952 // | |
953 // Otherwise, download has been cancelled or interrupted before we've | |
954 // received the DB handle. We post one final message to the history | |
955 // service so that it can be properly in sync with the DownloadItem's | |
956 // completion status, and also inform any observers so that they get | |
957 // more than just the start notification. | |
958 if (item->IsInProgress()) { | |
959 MaybeCompleteDownload(item); | |
960 } else { | |
961 DCHECK(item->IsCancelled()); | |
962 active_downloads_.erase(item->GetId()); | |
963 if (delegate_) | |
964 delegate_->UpdateItemInPersistentStore(item); | |
965 item->UpdateObservers(); | |
966 } | |
967 } | |
968 | |
969 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) { | 835 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) { |
970 // The 'contents' may no longer exist if the user closed the contents before | 836 // The 'contents' may no longer exist if the user closed the contents before |
971 // we get this start completion event. | 837 // we get this start completion event. |
972 WebContents* content = download->GetWebContents(); | 838 WebContents* content = download->GetWebContents(); |
973 | 839 |
974 // If the contents no longer exists, we ask the embedder to suggest another | 840 // If the contents no longer exists, we ask the embedder to suggest another |
975 // contents. | 841 // contents. |
976 if (!content && delegate_) | 842 if (!content && delegate_) |
977 content = delegate_->GetAlternativeWebContentsToNotifyForDownload(); | 843 content = delegate_->GetAlternativeWebContentsToNotifyForDownload(); |
978 | 844 |
(...skipping 12 matching lines...) Expand all Loading... |
991 if (item->IsInProgress()) | 857 if (item->IsInProgress()) |
992 ++count; | 858 ++count; |
993 } | 859 } |
994 return count; | 860 return count; |
995 } | 861 } |
996 | 862 |
997 void DownloadManagerImpl::NotifyModelChanged() { | 863 void DownloadManagerImpl::NotifyModelChanged() { |
998 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged(this)); | 864 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged(this)); |
999 } | 865 } |
1000 | 866 |
| 867 // TODO(benjhayden): Kill this method premailing XXX occam |
1001 DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) { | 868 DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) { |
1002 DownloadItem* download = GetDownload(download_id); | 869 return GetDownload(download_id); |
1003 return (download && download->IsPersisted()) ? download : NULL; | |
1004 } | 870 } |
1005 | 871 |
1006 DownloadItem* DownloadManagerImpl::GetDownload(int download_id) { | 872 DownloadItem* DownloadManagerImpl::GetDownload(int download_id) { |
1007 return ContainsKey(downloads_, download_id) ? downloads_[download_id] : NULL; | 873 return ContainsKey(downloads_, download_id) ? downloads_[download_id] : NULL; |
1008 } | 874 } |
1009 | 875 |
1010 DownloadItem* DownloadManagerImpl::GetActiveDownloadItem(int download_id) { | 876 DownloadItem* DownloadManagerImpl::GetActiveDownloadItem(int download_id) { |
1011 if (ContainsKey(active_downloads_, download_id)) | 877 if (ContainsKey(active_downloads_, download_id)) |
1012 return active_downloads_[download_id]; | 878 return active_downloads_[download_id]; |
1013 return NULL; | 879 return NULL; |
(...skipping 26 matching lines...) Expand all Loading... |
1040 DownloadSet remainder; | 906 DownloadSet remainder; |
1041 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); | 907 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); |
1042 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), | 908 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), |
1043 all_downloads.begin(), all_downloads.end(), | 909 all_downloads.begin(), all_downloads.end(), |
1044 insert_it); | 910 insert_it); |
1045 DCHECK(remainder.empty()); | 911 DCHECK(remainder.empty()); |
1046 } | 912 } |
1047 #endif | 913 #endif |
1048 } | 914 } |
1049 | 915 |
1050 // SavePackage will call SavePageDownloadFinished upon completion/cancellation. | |
1051 // The history callback will call OnSavePageItemAddedToPersistentStore. | |
1052 // If the download finishes before the history callback, | |
1053 // OnSavePageItemAddedToPersistentStore calls SavePageDownloadFinished, ensuring | |
1054 // that the history event is update regardless of the order in which these two | |
1055 // events complete. | |
1056 // If something removes the download item from the download manager (Remove, | |
1057 // Shutdown) the result will be that the SavePage system will not be able to | |
1058 // properly update the download item (which no longer exists) or the download | |
1059 // history, but the action will complete properly anyway. This may lead to the | |
1060 // history entry being wrong on a reload of chrome (specifically in the case of | |
1061 // Initiation -> History Callback -> Removal -> Completion), but there's no way | |
1062 // to solve that without canceling on Remove (which would then update the DB). | |
1063 | |
1064 void DownloadManagerImpl::OnSavePageItemAddedToPersistentStore( | |
1065 DownloadItemImpl* item) { | |
1066 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
1067 | |
1068 // Finalize this download if it finished before the history callback. | |
1069 if (!item->IsInProgress()) | |
1070 SavePageDownloadFinished(item); | |
1071 } | |
1072 | |
1073 void DownloadManagerImpl::SavePageDownloadFinished( | 916 void DownloadManagerImpl::SavePageDownloadFinished( |
1074 content::DownloadItem* download) { | 917 content::DownloadItem* download) { |
1075 if (download->IsPersisted()) { | 918 if (download->IsComplete()) |
1076 if (delegate_) | 919 content::NotificationService::current()->Notify( |
1077 delegate_->UpdateItemInPersistentStore(download); | 920 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, |
1078 if (download->IsComplete()) | 921 content::Source<DownloadManager>(this), |
1079 content::NotificationService::current()->Notify( | 922 content::Details<DownloadItem>(download)); |
1080 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, | |
1081 content::Source<DownloadManager>(this), | |
1082 content::Details<DownloadItem>(download)); | |
1083 } | |
1084 } | 923 } |
1085 | 924 |
1086 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) { | 925 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) { |
1087 if (delegate_) | |
1088 delegate_->UpdateItemInPersistentStore(download); | |
1089 int num_unopened = 0; | 926 int num_unopened = 0; |
1090 for (DownloadMap::iterator it = downloads_.begin(); | 927 for (DownloadMap::iterator it = downloads_.begin(); |
1091 it != downloads_.end(); ++it) { | 928 it != downloads_.end(); ++it) { |
1092 DownloadItemImpl* item = it->second; | 929 DownloadItemImpl* item = it->second; |
1093 if (item->IsComplete() && | 930 if (item->IsComplete() && |
1094 !item->GetOpened()) | 931 !item->GetOpened()) |
1095 ++num_unopened; | 932 ++num_unopened; |
1096 } | 933 } |
1097 download_stats::RecordOpensOutstanding(num_unopened); | 934 download_stats::RecordOpensOutstanding(num_unopened); |
1098 } | 935 } |
1099 | 936 |
| 937 // TODO(benjhayden) this should be a method on DI |
1100 void DownloadManagerImpl::DownloadRenamedToIntermediateName( | 938 void DownloadManagerImpl::DownloadRenamedToIntermediateName( |
1101 DownloadItemImpl* download) { | 939 DownloadItemImpl* download) { |
1102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 940 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1103 // download->GetFullPath() is only expected to be meaningful after this | 941 download->UpdateObservers(); |
1104 // callback is received. Therefore we can now add the download to a persistent | |
1105 // store. If the rename failed, we receive an OnDownloadInterrupted() call | |
1106 // before we receive the DownloadRenamedToIntermediateName() call. | |
1107 if (delegate_) { | |
1108 delegate_->AddItemToPersistentStore(download); | |
1109 } else { | |
1110 OnItemAddedToPersistentStore(download->GetId(), | |
1111 DownloadItem::kUninitializedHandle); | |
1112 } | |
1113 } | 942 } |
1114 | 943 |
| 944 // TODO(benjhayden) this should be a method on DI |
1115 void DownloadManagerImpl::DownloadRenamedToFinalName( | 945 void DownloadManagerImpl::DownloadRenamedToFinalName( |
1116 DownloadItemImpl* download) { | 946 DownloadItemImpl* download) { |
1117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 947 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1118 // If the rename failed, we receive an OnDownloadInterrupted() call before we | 948 // If the rename failed, we receive an OnDownloadInterrupted() call before we |
1119 // receive the DownloadRenamedToFinalName() call. | 949 // receive the DownloadRenamedToFinalName() call. |
1120 if (delegate_) { | 950 download->UpdateObservers(); |
1121 delegate_->UpdatePathForItemInPersistentStore( | |
1122 download, download->GetFullPath()); | |
1123 } | |
1124 } | 951 } |
OLD | NEW |