Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: content/browser/download/download_manager_impl.cc

Issue 10915180: Make DownloadHistory observe manager, items (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: @r168573 Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 15 matching lines...) Expand all
26 #include "content/browser/download/download_item_impl.h" 26 #include "content/browser/download/download_item_impl.h"
27 #include "content/browser/download/download_stats.h" 27 #include "content/browser/download/download_stats.h"
28 #include "content/browser/renderer_host/render_view_host_impl.h" 28 #include "content/browser/renderer_host/render_view_host_impl.h"
29 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" 29 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
30 #include "content/browser/web_contents/web_contents_impl.h" 30 #include "content/browser/web_contents/web_contents_impl.h"
31 #include "content/public/browser/browser_context.h" 31 #include "content/public/browser/browser_context.h"
32 #include "content/public/browser/browser_thread.h" 32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/content_browser_client.h" 33 #include "content/public/browser/content_browser_client.h"
34 #include "content/public/browser/download_interrupt_reasons.h" 34 #include "content/public/browser/download_interrupt_reasons.h"
35 #include "content/public/browser/download_manager_delegate.h" 35 #include "content/public/browser/download_manager_delegate.h"
36 #include "content/public/browser/download_persistent_store_info.h"
37 #include "content/public/browser/download_url_parameters.h" 36 #include "content/public/browser/download_url_parameters.h"
38 #include "content/public/browser/notification_service.h" 37 #include "content/public/browser/notification_service.h"
39 #include "content/public/browser/notification_types.h" 38 #include "content/public/browser/notification_types.h"
40 #include "content/public/browser/render_process_host.h" 39 #include "content/public/browser/render_process_host.h"
41 #include "content/public/browser/resource_context.h" 40 #include "content/public/browser/resource_context.h"
42 #include "content/public/browser/web_contents_delegate.h" 41 #include "content/public/browser/web_contents_delegate.h"
43 #include "net/base/load_flags.h" 42 #include "net/base/load_flags.h"
44 #include "net/base/upload_data.h" 43 #include "net/base/upload_data.h"
45 #include "net/url_request/url_request_context.h" 44 #include "net/url_request/url_request_context.h"
46 #include "webkit/glue/webkit_glue.h" 45 #include "webkit/glue/webkit_glue.h"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 } 133 }
135 134
136 class DownloadItemFactoryImpl : public DownloadItemFactory { 135 class DownloadItemFactoryImpl : public DownloadItemFactory {
137 public: 136 public:
138 DownloadItemFactoryImpl() {} 137 DownloadItemFactoryImpl() {}
139 virtual ~DownloadItemFactoryImpl() {} 138 virtual ~DownloadItemFactoryImpl() {}
140 139
141 virtual DownloadItemImpl* CreatePersistedItem( 140 virtual DownloadItemImpl* CreatePersistedItem(
142 DownloadItemImplDelegate* delegate, 141 DownloadItemImplDelegate* delegate,
143 DownloadId download_id, 142 DownloadId download_id,
144 const DownloadPersistentStoreInfo& info, 143 const FilePath& path,
144 const GURL& url,
145 const GURL& referrer_url,
146 const base::Time& start_time,
147 const base::Time& end_time,
148 int64 received_bytes,
149 int64 total_bytes,
150 DownloadItem::DownloadState state,
151 bool opened,
145 const net::BoundNetLog& bound_net_log) OVERRIDE { 152 const net::BoundNetLog& bound_net_log) OVERRIDE {
146 return new DownloadItemImpl(delegate, download_id, info, bound_net_log); 153 return new DownloadItemImpl(
154 delegate,
155 download_id,
156 path,
157 url,
158 referrer_url,
159 start_time,
160 end_time,
161 received_bytes,
162 total_bytes,
163 state,
164 opened,
165 bound_net_log);
147 } 166 }
148 167
149 virtual DownloadItemImpl* CreateActiveItem( 168 virtual DownloadItemImpl* CreateActiveItem(
150 DownloadItemImplDelegate* delegate, 169 DownloadItemImplDelegate* delegate,
151 const DownloadCreateInfo& info, 170 const DownloadCreateInfo& info,
152 scoped_ptr<DownloadRequestHandleInterface> request_handle, 171 scoped_ptr<DownloadRequestHandleInterface> request_handle,
153 const net::BoundNetLog& bound_net_log) OVERRIDE { 172 const net::BoundNetLog& bound_net_log) OVERRIDE {
154 return new DownloadItemImpl(delegate, info, request_handle.Pass(), 173 return new DownloadItemImpl(delegate, info, request_handle.Pass(),
155 bound_net_log); 174 bound_net_log);
156 } 175 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 // from the disk. This may or may not result in it being 296 // from the disk. This may or may not result in it being
278 // removed from the DownloadManager queues and deleted 297 // removed from the DownloadManager queues and deleted
279 // (specifically, DownloadManager::DownloadRemoved only 298 // (specifically, DownloadManager::DownloadRemoved only
280 // removes and deletes it if it's known to the history service) 299 // removes and deletes it if it's known to the history service)
281 // so the only thing we know after calling this function is that 300 // so the only thing we know after calling this function is that
282 // the download was deleted if-and-only-if it was removed 301 // the download was deleted if-and-only-if it was removed
283 // from all queues. 302 // from all queues.
284 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN); 303 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN);
285 } else if (download->IsPartialDownload()) { 304 } else if (download->IsPartialDownload()) {
286 download->Cancel(false); 305 download->Cancel(false);
287 if (delegate_)
288 delegate_->UpdateItemInPersistentStore(download);
289 } 306 }
290 } 307 }
291 308
292 // At this point, all dangerous downloads have had their files removed 309 // At this point, all dangerous downloads have had their files removed
293 // and all in progress downloads have been cancelled. We can now delete 310 // and all in progress downloads have been cancelled. We can now delete
294 // anything left. 311 // anything left.
295 312
296 // We delete the downloads before clearing the active_downloads_ map 313 // We delete the downloads before clearing the active_downloads_ map
297 // so that downloads in the COMPLETING_INTERNAL state (which will have 314 // so that downloads in the COMPLETING_INTERNAL state (which will have
298 // ignored the Cancel() above) will still show up in active_downloads_ 315 // ignored the Cancel() above) will still show up in active_downloads_
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 371 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
355 372
356 return download; 373 return download;
357 } 374 }
358 375
359 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { 376 void DownloadManagerImpl::CheckForHistoryFilesRemoval() {
360 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 377 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
361 for (DownloadMap::iterator it = downloads_.begin(); 378 for (DownloadMap::iterator it = downloads_.begin();
362 it != downloads_.end(); ++it) { 379 it != downloads_.end(); ++it) {
363 DownloadItemImpl* item = it->second; 380 DownloadItemImpl* item = it->second;
364 if (item->IsPersisted()) 381 CheckForFileRemoval(item);
365 CheckForFileRemoval(item);
366 } 382 }
367 } 383 }
368 384
369 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { 385 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) {
370 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
371 if (download_item->IsComplete() && 387 if (download_item->IsComplete() &&
372 !download_item->GetFileExternallyRemoved()) { 388 !download_item->GetFileExternallyRemoved()) {
373 BrowserThread::PostTask( 389 BrowserThread::PostTask(
374 BrowserThread::FILE, FROM_HERE, 390 BrowserThread::FILE, FROM_HERE,
375 base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread, 391 base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 return download; 436 return download;
421 } 437 }
422 438
423 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( 439 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem(
424 const FilePath& main_file_path, 440 const FilePath& main_file_path,
425 const GURL& page_url, 441 const GURL& page_url,
426 const std::string& mime_type, 442 const std::string& mime_type,
427 DownloadItem::Observer* observer) { 443 DownloadItem::Observer* observer) {
428 net::BoundNetLog bound_net_log = 444 net::BoundNetLog bound_net_log =
429 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); 445 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
430 DownloadItemImpl* download = item_factory_->CreateSavePageItem( 446 DownloadItemImpl* download_item = item_factory_->CreateSavePageItem(
431 this, 447 this,
432 main_file_path, 448 main_file_path,
433 page_url, 449 page_url,
434 GetNextId(), 450 GetNextId(),
435 mime_type, 451 mime_type,
436 bound_net_log); 452 bound_net_log);
437 453
438 download->AddObserver(observer); 454 download_item->AddObserver(observer);
455 DCHECK(!ContainsKey(downloads_, download_item->GetId()));
456 downloads_[download_item->GetId()] = download_item;
457 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(
458 this, download_item));
439 459
440 DCHECK(!ContainsKey(downloads_, download->GetId())); 460 // TODO(asanka): Make the ui an observer.
441 downloads_[download->GetId()] = download; 461 ShowDownloadInBrowser(download_item);
442 462
443 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 463 return download_item;
444
445 // Will notify the observer in the callback.
446 if (delegate_)
447 delegate_->AddItemToPersistentStore(download);
448
449 return download;
450 } 464 }
451 465
452 void DownloadManagerImpl::AssertStateConsistent( 466 void DownloadManagerImpl::AssertStateConsistent(
453 DownloadItemImpl* download) const { 467 DownloadItemImpl* download) const {
454 CHECK(ContainsKey(downloads_, download->GetId())); 468 CHECK(ContainsKey(downloads_, download->GetId()));
455 469
456 int64 state = download->GetState(); 470 int64 state = download->GetState();
457 base::debug::Alias(&state); 471 base::debug::Alias(&state);
458 if (ContainsKey(active_downloads_, download->GetId())) {
459 if (download->IsPersisted())
460 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState());
461 if (DownloadItem::IN_PROGRESS != download->GetState())
462 CHECK_EQ(DownloadItem::kUninitializedHandle, download->GetDbHandle());
463 }
464 if (DownloadItem::IN_PROGRESS == download->GetState()) 472 if (DownloadItem::IN_PROGRESS == download->GetState())
465 CHECK(ContainsKey(active_downloads_, download->GetId())); 473 CHECK(ContainsKey(active_downloads_, download->GetId()));
466 } 474 }
467 475
468 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { 476 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) {
469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
470 DCHECK(download); 478 DCHECK(download);
471 if (delegate_)
472 delegate_->UpdateItemInPersistentStore(download);
473 active_downloads_.erase(download->GetId()); 479 active_downloads_.erase(download->GetId());
474 AssertStateConsistent(download); 480 AssertStateConsistent(download);
475 } 481 }
476 482
477 void DownloadManagerImpl::CancelDownload(int32 download_id) { 483 void DownloadManagerImpl::CancelDownload(int32 download_id) {
478 // A cancel at the right time could remove the download from the 484 // A cancel at the right time could remove the download from the
479 // |active_downloads_| map before we get here. 485 // |active_downloads_| map before we get here.
480 if (ContainsKey(active_downloads_, download_id)) 486 if (ContainsKey(active_downloads_, download_id))
481 active_downloads_[download_id]->Cancel(true); 487 active_downloads_[download_id]->Cancel(true);
482 } 488 }
483 489
484 void DownloadManagerImpl::UpdatePersistence(DownloadItemImpl* download) {
485 if (delegate_)
486 delegate_->UpdateItemInPersistentStore(download);
487 }
488
489 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { 490 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) {
490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 491 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
491 492
492 VLOG(20) << __FUNCTION__ << "()" 493 VLOG(20) << __FUNCTION__ << "()"
493 << " download = " << download->DebugString(true); 494 << " download = " << download->DebugString(true);
494 495
495 RemoveFromActiveList(download); 496 RemoveFromActiveList(download);
496 // This function is called from the DownloadItem, so DI state 497 // This function is called from the DownloadItem, so DI state
497 // should already have been updated. 498 // should already have been updated.
498 AssertStateConsistent(download); 499 AssertStateConsistent(download);
499 } 500 }
500 501
501 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { 502 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) {
502 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
503 DCHECK(download); 504 DCHECK(download);
504 505 active_downloads_.erase(download->GetId());
505 // Clean up will happen when the history system create callback runs if we
506 // don't have a valid db_handle yet.
507 if (download->IsPersisted()) {
508 active_downloads_.erase(download->GetId());
509 if (delegate_)
510 delegate_->UpdateItemInPersistentStore(download);
511 }
512 } 506 }
513 507
514 void DownloadManagerImpl::SetDownloadItemFactoryForTesting( 508 void DownloadManagerImpl::SetDownloadItemFactoryForTesting(
515 scoped_ptr<DownloadItemFactory> item_factory) { 509 scoped_ptr<DownloadItemFactory> item_factory) {
516 item_factory_ = item_factory.Pass(); 510 item_factory_ = item_factory.Pass();
517 } 511 }
518 512
519 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( 513 void DownloadManagerImpl::SetDownloadFileFactoryForTesting(
520 scoped_ptr<DownloadFileFactory> file_factory) { 514 scoped_ptr<DownloadFileFactory> file_factory) {
521 file_factory_ = file_factory.Pass(); 515 file_factory_ = file_factory.Pass();
(...skipping 19 matching lines...) Expand all
541 downloads_.erase(download_id); 535 downloads_.erase(download_id);
542 } 536 }
543 return static_cast<int>(pending_deletes.size()); 537 return static_cast<int>(pending_deletes.size());
544 } 538 }
545 539
546 void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) { 540 void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) {
547 if (!download || 541 if (!download ||
548 downloads_.find(download->GetId()) == downloads_.end()) 542 downloads_.find(download->GetId()) == downloads_.end())
549 return; 543 return;
550 544
551 // TODO(benjhayden,rdsmith): Remove this.
552 if (!download->IsPersisted())
553 return;
554
555 // Make history update.
556 if (delegate_)
557 delegate_->RemoveItemFromPersistentStore(download);
558
559 // Remove from our tables and delete. 545 // Remove from our tables and delete.
560 int downloads_count = 546 int downloads_count =
561 RemoveDownloadItems(DownloadItemImplVector(1, download)); 547 RemoveDownloadItems(DownloadItemImplVector(1, download));
562 DCHECK_EQ(1, downloads_count); 548 DCHECK_EQ(1, downloads_count);
563 } 549 }
564 550
565 int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin, 551 int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin,
566 base::Time remove_end) { 552 base::Time remove_end) {
567 if (delegate_)
568 delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end);
569
570 DownloadItemImplVector pending_deletes; 553 DownloadItemImplVector pending_deletes;
571 for (DownloadMap::const_iterator it = downloads_.begin(); 554 for (DownloadMap::const_iterator it = downloads_.begin();
572 it != downloads_.end(); 555 it != downloads_.end();
573 ++it) { 556 ++it) {
574 DownloadItemImpl* download = it->second; 557 DownloadItemImpl* download = it->second;
575 if (download->IsPersisted() && 558 if (download->GetStartTime() >= remove_begin &&
576 download->GetStartTime() >= remove_begin &&
577 (remove_end.is_null() || download->GetStartTime() < remove_end) && 559 (remove_end.is_null() || download->GetStartTime() < remove_end) &&
578 (download->IsComplete() || download->IsCancelled())) { 560 (download->IsComplete() || download->IsCancelled())) {
579 AssertStateConsistent(download); 561 AssertStateConsistent(download);
580 download->NotifyRemoved(); 562 download->NotifyRemoved();
581 pending_deletes.push_back(download); 563 pending_deletes.push_back(download);
582 } 564 }
583 } 565 }
584 return RemoveDownloadItems(pending_deletes); 566 return RemoveDownloadItems(pending_deletes);
585 } 567 }
586 568
(...skipping 20 matching lines...) Expand all
607 } 589 }
608 590
609 void DownloadManagerImpl::AddObserver(Observer* observer) { 591 void DownloadManagerImpl::AddObserver(Observer* observer) {
610 observers_.AddObserver(observer); 592 observers_.AddObserver(observer);
611 } 593 }
612 594
613 void DownloadManagerImpl::RemoveObserver(Observer* observer) { 595 void DownloadManagerImpl::RemoveObserver(Observer* observer) {
614 observers_.RemoveObserver(observer); 596 observers_.RemoveObserver(observer);
615 } 597 }
616 598
617 // Operations posted to us from the history service ---------------------------- 599 DownloadItem* DownloadManagerImpl::CreateDownloadItem(
618 600 const FilePath& path,
619 // The history service has retrieved all download entries. 'entries' contains 601 const GURL& url,
620 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). 602 const GURL& referrer_url,
621 void DownloadManagerImpl::OnPersistentStoreQueryComplete( 603 const base::Time& start_time,
622 std::vector<DownloadPersistentStoreInfo>* entries) { 604 const base::Time& end_time,
623 history_size_ = entries->size(); 605 int64 received_bytes,
624 for (size_t i = 0; i < entries->size(); ++i) { 606 int64 total_bytes,
625 int64 db_handle = entries->at(i).db_handle; 607 DownloadItem::DownloadState state,
626 base::debug::Alias(&db_handle); 608 bool opened) {
627 609 DownloadItemImpl* item = item_factory_->CreatePersistedItem(
628 net::BoundNetLog bound_net_log = 610 this,
629 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); 611 GetNextId(),
630 DownloadItemImpl* download = item_factory_->CreatePersistedItem( 612 path,
631 this, GetNextId(), entries->at(i), bound_net_log); 613 url,
632 DCHECK(!ContainsKey(downloads_, download->GetId())); 614 referrer_url,
633 downloads_[download->GetId()] = download; 615 start_time,
634 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 616 end_time,
635 VLOG(20) << __FUNCTION__ << "()" << i << ">" 617 received_bytes,
636 << " download = " << download->DebugString(true); 618 total_bytes,
637 } 619 state,
638 CheckForHistoryFilesRemoval(); 620 opened,
621 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD));
622 DCHECK(!ContainsKey(downloads_, item->GetId()));
623 downloads_[item->GetId()] = item;
624 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, item));
625 VLOG(20) << __FUNCTION__ << "() download = " << item->DebugString(true);
626 return item;
639 } 627 }
640 628
641 void DownloadManagerImpl::AddDownloadItemToHistory(DownloadItemImpl* download, 629 // TODO(asanka) Move into an observer.
642 int64 db_handle) {
643 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
644 DCHECK_NE(DownloadItem::kUninitializedHandle, db_handle);
645 DCHECK(!download->IsPersisted());
646 download->SetDbHandle(db_handle);
647 download->SetIsPersisted();
648
649 RecordHistorySize(history_size_);
650 // Not counting |download|.
651 ++history_size_;
652
653 // Show in the appropriate browser UI.
654 // This includes buttons to save or cancel, for a dangerous download.
655 ShowDownloadInBrowser(download);
656 }
657
658 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id,
659 int64 db_handle) {
660 // It's valid that we don't find a matching item, i.e. on shutdown.
661 if (!ContainsKey(downloads_, download_id))
662 return;
663
664 DownloadItemImpl* item = downloads_[download_id];
665 AddDownloadItemToHistory(item, db_handle);
666 if (item->IsSavePackageDownload()) {
667 OnSavePageItemAddedToPersistentStore(item);
668 } else {
669 OnDownloadItemAddedToPersistentStore(item);
670 }
671 }
672
673 // Once the new DownloadItem has been committed to the persistent store,
674 // associate it with its db_handle (TODO(benjhayden) merge db_handle with id),
675 // show it in the browser (TODO(benjhayden) the ui should observe us instead),
676 // and notify observers (TODO(benjhayden) observers should be able to see the
677 // item when it's created so they can observe it directly. Are there any
678 // clients that actually need to know when the item is added to the history?).
679 void DownloadManagerImpl::OnDownloadItemAddedToPersistentStore(
680 DownloadItemImpl* item) {
681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
682 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << item->GetDbHandle()
683 << " download_id = " << item->GetId()
684 << " download = " << item->DebugString(true);
685
686 // If the download is still in progress, try to complete it.
687 //
688 // Otherwise, download has been cancelled or interrupted before we've
689 // received the DB handle. We post one final message to the history
690 // service so that it can be properly in sync with the DownloadItem's
691 // completion status, and also inform any observers so that they get
692 // more than just the start notification.
693 if (item->IsInProgress()) {
694 item->MaybeCompleteDownload();
695 } else {
696 DCHECK(item->IsCancelled());
697 active_downloads_.erase(item->GetId());
698 if (delegate_)
699 delegate_->UpdateItemInPersistentStore(item);
700 item->UpdateObservers();
701 }
702 }
703
704 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) { 630 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) {
705 // The 'contents' may no longer exist if the user closed the contents before 631 // The 'contents' may no longer exist if the user closed the contents before
706 // we get this start completion event. 632 // we get this start completion event.
707 WebContents* content = download->GetWebContents(); 633 WebContents* content = download->GetWebContents();
708 634
709 // If the contents no longer exists, we ask the embedder to suggest another 635 // If the contents no longer exists, we ask the embedder to suggest another
710 // contents. 636 // contents.
711 if (!content && delegate_) 637 if (!content && delegate_)
712 content = delegate_->GetAlternativeWebContentsToNotifyForDownload(); 638 content = delegate_->GetAlternativeWebContentsToNotifyForDownload();
713 639
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 DownloadSet remainder; 693 DownloadSet remainder;
768 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); 694 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin());
769 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), 695 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(),
770 all_downloads.begin(), all_downloads.end(), 696 all_downloads.begin(), all_downloads.end(),
771 insert_it); 697 insert_it);
772 DCHECK(remainder.empty()); 698 DCHECK(remainder.empty());
773 } 699 }
774 #endif 700 #endif
775 } 701 }
776 702
777 // SavePackage will call SavePageDownloadFinished upon completion/cancellation.
778 // The history callback will call OnSavePageItemAddedToPersistentStore.
779 // If the download finishes before the history callback,
780 // OnSavePageItemAddedToPersistentStore calls SavePageDownloadFinished, ensuring
781 // that the history event is update regardless of the order in which these two
782 // events complete.
783 // If something removes the download item from the download manager (Remove,
784 // Shutdown) the result will be that the SavePage system will not be able to
785 // properly update the download item (which no longer exists) or the download
786 // history, but the action will complete properly anyway. This may lead to the
787 // history entry being wrong on a reload of chrome (specifically in the case of
788 // Initiation -> History Callback -> Removal -> Completion), but there's no way
789 // to solve that without canceling on Remove (which would then update the DB).
790
791 void DownloadManagerImpl::OnSavePageItemAddedToPersistentStore(
792 DownloadItemImpl* item) {
793 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
794
795 // Finalize this download if it finished before the history callback.
796 if (!item->IsInProgress())
797 SavePageDownloadFinished(item);
798 }
799
800 void DownloadManagerImpl::SavePageDownloadFinished(DownloadItem* download) {
801 if (download->IsPersisted()) {
802 if (delegate_)
803 delegate_->UpdateItemInPersistentStore(download);
804 }
805 }
806
807 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) { 703 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) {
808 if (delegate_)
809 delegate_->UpdateItemInPersistentStore(download);
810 int num_unopened = 0; 704 int num_unopened = 0;
811 for (DownloadMap::iterator it = downloads_.begin(); 705 for (DownloadMap::iterator it = downloads_.begin();
812 it != downloads_.end(); ++it) { 706 it != downloads_.end(); ++it) {
813 DownloadItemImpl* item = it->second; 707 DownloadItemImpl* item = it->second;
814 if (item->IsComplete() && 708 if (item->IsComplete() &&
815 !item->GetOpened()) 709 !item->GetOpened())
816 ++num_unopened; 710 ++num_unopened;
817 } 711 }
818 RecordOpensOutstanding(num_unopened); 712 RecordOpensOutstanding(num_unopened);
819 } 713 }
820 714
821 void DownloadManagerImpl::DownloadRenamedToIntermediateName(
822 DownloadItemImpl* download) {
823 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
824 // download->GetFullPath() is only expected to be meaningful after this
825 // callback is received. Therefore we can now add the download to a persistent
826 // store. If the rename failed, we processed an interrupt
827 // before we receive the DownloadRenamedToIntermediateName() call.
828 if (delegate_) {
829 delegate_->AddItemToPersistentStore(download);
830 } else {
831 OnItemAddedToPersistentStore(download->GetId(),
832 DownloadItem::kUninitializedHandle);
833 }
834 }
835
836 void DownloadManagerImpl::DownloadRenamedToFinalName(
837 DownloadItemImpl* download) {
838 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
839 // If the rename failed, we processed an interrupt before we get here.
840 if (delegate_) {
841 delegate_->UpdatePathForItemInPersistentStore(
842 download, download->GetFullPath());
843 }
844 }
845
846 } // namespace content 715 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698