| 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 |