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

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: @r165669 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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 } 124 }
126 125
127 class DownloadItemFactoryImpl : public DownloadItemFactory { 126 class DownloadItemFactoryImpl : public DownloadItemFactory {
128 public: 127 public:
129 DownloadItemFactoryImpl() {} 128 DownloadItemFactoryImpl() {}
130 virtual ~DownloadItemFactoryImpl() {} 129 virtual ~DownloadItemFactoryImpl() {}
131 130
132 virtual DownloadItemImpl* CreatePersistedItem( 131 virtual DownloadItemImpl* CreatePersistedItem(
133 DownloadItemImplDelegate* delegate, 132 DownloadItemImplDelegate* delegate,
134 DownloadId download_id, 133 DownloadId download_id,
135 const DownloadPersistentStoreInfo& info, 134 const FilePath& path,
135 const GURL& url,
136 const GURL& referrer_url,
137 const base::Time& start_time,
138 const base::Time& end_time,
139 int64 received_bytes,
140 int64 total_bytes,
141 DownloadItem::DownloadState state,
142 bool opened,
136 const net::BoundNetLog& bound_net_log) OVERRIDE { 143 const net::BoundNetLog& bound_net_log) OVERRIDE {
137 return new DownloadItemImpl(delegate, download_id, info, bound_net_log); 144 return new DownloadItemImpl(
145 delegate,
146 download_id,
147 path,
148 url,
149 referrer_url,
150 start_time,
151 end_time,
152 received_bytes,
153 total_bytes,
154 state,
155 opened,
156 bound_net_log);
138 } 157 }
139 158
140 virtual DownloadItemImpl* CreateActiveItem( 159 virtual DownloadItemImpl* CreateActiveItem(
141 DownloadItemImplDelegate* delegate, 160 DownloadItemImplDelegate* delegate,
142 const DownloadCreateInfo& info, 161 const DownloadCreateInfo& info,
143 scoped_ptr<DownloadRequestHandleInterface> request_handle, 162 scoped_ptr<DownloadRequestHandleInterface> request_handle,
144 const net::BoundNetLog& bound_net_log) OVERRIDE { 163 const net::BoundNetLog& bound_net_log) OVERRIDE {
145 return new DownloadItemImpl(delegate, info, request_handle.Pass(), 164 return new DownloadItemImpl(delegate, info, request_handle.Pass(),
146 bound_net_log); 165 bound_net_log);
147 } 166 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 // from the disk. This may or may not result in it being 283 // from the disk. This may or may not result in it being
265 // removed from the DownloadManager queues and deleted 284 // removed from the DownloadManager queues and deleted
266 // (specifically, DownloadManager::DownloadRemoved only 285 // (specifically, DownloadManager::DownloadRemoved only
267 // removes and deletes it if it's known to the history service) 286 // removes and deletes it if it's known to the history service)
268 // so the only thing we know after calling this function is that 287 // so the only thing we know after calling this function is that
269 // the download was deleted if-and-only-if it was removed 288 // the download was deleted if-and-only-if it was removed
270 // from all queues. 289 // from all queues.
271 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN); 290 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN);
272 } else if (download->IsPartialDownload()) { 291 } else if (download->IsPartialDownload()) {
273 download->Cancel(false); 292 download->Cancel(false);
274 if (delegate_)
275 delegate_->UpdateItemInPersistentStore(download);
276 } 293 }
277 } 294 }
278 295
279 // At this point, all dangerous downloads have had their files removed 296 // At this point, all dangerous downloads have had their files removed
280 // and all in progress downloads have been cancelled. We can now delete 297 // and all in progress downloads have been cancelled. We can now delete
281 // anything left. 298 // anything left.
282 299
283 // We delete the downloads before clearing the active_downloads_ map 300 // We delete the downloads before clearing the active_downloads_ map
284 // so that downloads in the COMPLETING_INTERNAL state (which will have 301 // so that downloads in the COMPLETING_INTERNAL state (which will have
285 // ignored the Cancel() above) will still show up in active_downloads_ 302 // ignored the Cancel() above) will still show up in active_downloads_
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 358 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
342 359
343 return download; 360 return download;
344 } 361 }
345 362
346 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { 363 void DownloadManagerImpl::CheckForHistoryFilesRemoval() {
347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
348 for (DownloadMap::iterator it = downloads_.begin(); 365 for (DownloadMap::iterator it = downloads_.begin();
349 it != downloads_.end(); ++it) { 366 it != downloads_.end(); ++it) {
350 DownloadItemImpl* item = it->second; 367 DownloadItemImpl* item = it->second;
351 if (item->IsPersisted()) 368 CheckForFileRemoval(item);
352 CheckForFileRemoval(item);
353 } 369 }
354 } 370 }
355 371
356 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) { 372 void DownloadManagerImpl::CheckForFileRemoval(DownloadItemImpl* download_item) {
357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
358 if (download_item->IsComplete() && 374 if (download_item->IsComplete() &&
359 !download_item->GetFileExternallyRemoved()) { 375 !download_item->GetFileExternallyRemoved()) {
360 BrowserThread::PostTask( 376 BrowserThread::PostTask(
361 BrowserThread::FILE, FROM_HERE, 377 BrowserThread::FILE, FROM_HERE,
362 base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread, 378 base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 return download; 423 return download;
408 } 424 }
409 425
410 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( 426 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem(
411 const FilePath& main_file_path, 427 const FilePath& main_file_path,
412 const GURL& page_url, 428 const GURL& page_url,
413 const std::string& mime_type, 429 const std::string& mime_type,
414 DownloadItem::Observer* observer) { 430 DownloadItem::Observer* observer) {
415 net::BoundNetLog bound_net_log = 431 net::BoundNetLog bound_net_log =
416 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); 432 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
417 DownloadItemImpl* download = item_factory_->CreateSavePageItem( 433 DownloadItemImpl* download_item = item_factory_->CreateSavePageItem(
418 this, 434 this,
419 main_file_path, 435 main_file_path,
420 page_url, 436 page_url,
421 GetNextId(), 437 GetNextId(),
422 mime_type, 438 mime_type,
423 bound_net_log); 439 bound_net_log);
424 440
425 download->AddObserver(observer); 441 download_item->AddObserver(observer);
442 DCHECK(!ContainsKey(downloads_, download_item->GetId()));
443 downloads_[download_item->GetId()] = download_item;
444 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(
445 this, download_item));
426 446
427 DCHECK(!ContainsKey(downloads_, download->GetId())); 447 // TODO(asanka): Make the ui an observer.
428 downloads_[download->GetId()] = download; 448 ShowDownloadInBrowser(download_item);
429 449
430 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 450 return download_item;
431
432 // Will notify the observer in the callback.
433 if (delegate_)
434 delegate_->AddItemToPersistentStore(download);
435
436 return download;
437 } 451 }
438 452
439 void DownloadManagerImpl::AssertStateConsistent( 453 void DownloadManagerImpl::AssertStateConsistent(
440 DownloadItemImpl* download) const { 454 DownloadItemImpl* download) const {
441 CHECK(ContainsKey(downloads_, download->GetId())); 455 CHECK(ContainsKey(downloads_, download->GetId()));
442 456
443 int64 state = download->GetState(); 457 int64 state = download->GetState();
444 base::debug::Alias(&state); 458 base::debug::Alias(&state);
445 if (ContainsKey(active_downloads_, download->GetId())) {
446 if (download->IsPersisted())
447 CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState());
448 if (DownloadItem::IN_PROGRESS != download->GetState())
449 CHECK_EQ(DownloadItem::kUninitializedHandle, download->GetDbHandle());
450 }
451 if (DownloadItem::IN_PROGRESS == download->GetState()) 459 if (DownloadItem::IN_PROGRESS == download->GetState())
452 CHECK(ContainsKey(active_downloads_, download->GetId())); 460 CHECK(ContainsKey(active_downloads_, download->GetId()));
453 } 461 }
454 462
455 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { 463 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) {
456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 464 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
457 DCHECK(download); 465 DCHECK(download);
458 if (delegate_)
459 delegate_->UpdateItemInPersistentStore(download);
460 active_downloads_.erase(download->GetId()); 466 active_downloads_.erase(download->GetId());
461 AssertStateConsistent(download); 467 AssertStateConsistent(download);
462 } 468 }
463 469
464 void DownloadManagerImpl::CancelDownload(int32 download_id) { 470 void DownloadManagerImpl::CancelDownload(int32 download_id) {
465 // A cancel at the right time could remove the download from the 471 // A cancel at the right time could remove the download from the
466 // |active_downloads_| map before we get here. 472 // |active_downloads_| map before we get here.
467 if (ContainsKey(active_downloads_, download_id)) 473 if (ContainsKey(active_downloads_, download_id))
468 active_downloads_[download_id]->Cancel(true); 474 active_downloads_[download_id]->Cancel(true);
469 } 475 }
470 476
471 void DownloadManagerImpl::UpdatePersistence(DownloadItemImpl* download) {
472 if (delegate_)
473 delegate_->UpdateItemInPersistentStore(download);
474 }
475
476 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { 477 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) {
477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 478 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
478 479
479 VLOG(20) << __FUNCTION__ << "()" 480 VLOG(20) << __FUNCTION__ << "()"
480 << " download = " << download->DebugString(true); 481 << " download = " << download->DebugString(true);
481 482
482 RemoveFromActiveList(download); 483 RemoveFromActiveList(download);
483 // This function is called from the DownloadItem, so DI state 484 // This function is called from the DownloadItem, so DI state
484 // should already have been updated. 485 // should already have been updated.
485 AssertStateConsistent(download); 486 AssertStateConsistent(download);
486 } 487 }
487 488
488 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { 489 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) {
489 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
490 DCHECK(download); 491 DCHECK(download);
491 492 active_downloads_.erase(download->GetId());
492 // Clean up will happen when the history system create callback runs if we
493 // don't have a valid db_handle yet.
494 if (download->IsPersisted()) {
495 active_downloads_.erase(download->GetId());
496 if (delegate_)
497 delegate_->UpdateItemInPersistentStore(download);
498 }
499 } 493 }
500 494
501 void DownloadManagerImpl::SetDownloadItemFactoryForTesting( 495 void DownloadManagerImpl::SetDownloadItemFactoryForTesting(
502 scoped_ptr<DownloadItemFactory> item_factory) { 496 scoped_ptr<DownloadItemFactory> item_factory) {
503 item_factory_ = item_factory.Pass(); 497 item_factory_ = item_factory.Pass();
504 } 498 }
505 499
506 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( 500 void DownloadManagerImpl::SetDownloadFileFactoryForTesting(
507 scoped_ptr<DownloadFileFactory> file_factory) { 501 scoped_ptr<DownloadFileFactory> file_factory) {
508 file_factory_ = file_factory.Pass(); 502 file_factory_ = file_factory.Pass();
(...skipping 20 matching lines...) Expand all
529 } 523 }
530 NotifyModelChanged(); 524 NotifyModelChanged();
531 return static_cast<int>(pending_deletes.size()); 525 return static_cast<int>(pending_deletes.size());
532 } 526 }
533 527
534 void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) { 528 void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) {
535 if (!download || 529 if (!download ||
536 downloads_.find(download->GetId()) == downloads_.end()) 530 downloads_.find(download->GetId()) == downloads_.end())
537 return; 531 return;
538 532
539 // TODO(benjhayden,rdsmith): Remove this.
540 if (!download->IsPersisted())
541 return;
542
543 // Make history update.
544 if (delegate_)
545 delegate_->RemoveItemFromPersistentStore(download);
546
547 // Remove from our tables and delete. 533 // Remove from our tables and delete.
548 int downloads_count = 534 int downloads_count =
549 RemoveDownloadItems(DownloadItemImplVector(1, download)); 535 RemoveDownloadItems(DownloadItemImplVector(1, download));
550 DCHECK_EQ(1, downloads_count); 536 DCHECK_EQ(1, downloads_count);
551 } 537 }
552 538
553 int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin, 539 int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin,
554 base::Time remove_end) { 540 base::Time remove_end) {
555 if (delegate_)
556 delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end);
557
558 DownloadItemImplVector pending_deletes; 541 DownloadItemImplVector pending_deletes;
559 for (DownloadMap::const_iterator it = downloads_.begin(); 542 for (DownloadMap::const_iterator it = downloads_.begin();
560 it != downloads_.end(); 543 it != downloads_.end();
561 ++it) { 544 ++it) {
562 DownloadItemImpl* download = it->second; 545 DownloadItemImpl* download = it->second;
563 if (download->IsPersisted() && 546 if (download->GetStartTime() >= remove_begin &&
564 download->GetStartTime() >= remove_begin &&
565 (remove_end.is_null() || download->GetStartTime() < remove_end) && 547 (remove_end.is_null() || download->GetStartTime() < remove_end) &&
566 (download->IsComplete() || download->IsCancelled())) { 548 (download->IsComplete() || download->IsCancelled())) {
567 AssertStateConsistent(download); 549 AssertStateConsistent(download);
568 download->NotifyRemoved(); 550 download->NotifyRemoved();
569 pending_deletes.push_back(download); 551 pending_deletes.push_back(download);
570 } 552 }
571 } 553 }
572 return RemoveDownloadItems(pending_deletes); 554 return RemoveDownloadItems(pending_deletes);
573 } 555 }
574 556
(...skipping 24 matching lines...) Expand all
599 // TODO: It is the responsibility of the observers to query the 581 // TODO: It is the responsibility of the observers to query the
600 // DownloadManager. Remove the following call from here and update all 582 // DownloadManager. Remove the following call from here and update all
601 // observers. 583 // observers.
602 observer->ModelChanged(this); 584 observer->ModelChanged(this);
603 } 585 }
604 586
605 void DownloadManagerImpl::RemoveObserver(Observer* observer) { 587 void DownloadManagerImpl::RemoveObserver(Observer* observer) {
606 observers_.RemoveObserver(observer); 588 observers_.RemoveObserver(observer);
607 } 589 }
608 590
609 // Operations posted to us from the history service ---------------------------- 591 DownloadItem* DownloadManagerImpl::CreateDownloadItem(
610 592 const FilePath& path,
611 // The history service has retrieved all download entries. 'entries' contains 593 const GURL& url,
612 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). 594 const GURL& referrer_url,
613 void DownloadManagerImpl::OnPersistentStoreQueryComplete( 595 const base::Time& start_time,
614 std::vector<DownloadPersistentStoreInfo>* entries) { 596 const base::Time& end_time,
615 history_size_ = entries->size(); 597 int64 received_bytes,
616 for (size_t i = 0; i < entries->size(); ++i) { 598 int64 total_bytes,
617 int64 db_handle = entries->at(i).db_handle; 599 DownloadItem::DownloadState state,
618 base::debug::Alias(&db_handle); 600 bool opened) {
619 601 DownloadItemImpl* item = item_factory_->CreatePersistedItem(
620 net::BoundNetLog bound_net_log = 602 this,
621 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); 603 GetNextId(),
622 DownloadItemImpl* download = item_factory_->CreatePersistedItem( 604 path,
623 this, GetNextId(), entries->at(i), bound_net_log); 605 url,
624 DCHECK(!ContainsKey(downloads_, download->GetId())); 606 referrer_url,
625 downloads_[download->GetId()] = download; 607 start_time,
626 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 608 end_time,
627 VLOG(20) << __FUNCTION__ << "()" << i << ">" 609 received_bytes,
628 << " download = " << download->DebugString(true); 610 total_bytes,
629 } 611 state,
612 opened,
613 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD));
614 DCHECK(!ContainsKey(downloads_, item->GetId()));
615 downloads_[item->GetId()] = item;
616 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, item));
617 VLOG(20) << __FUNCTION__ << "() download = " << item->DebugString(true);
630 NotifyModelChanged(); 618 NotifyModelChanged();
631 CheckForHistoryFilesRemoval(); 619 return item;
632 } 620 }
633 621
634 void DownloadManagerImpl::AddDownloadItemToHistory(DownloadItemImpl* download, 622 // TODO(asanka) Move into an observer.
635 int64 db_handle) {
636 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
637 DCHECK_NE(DownloadItem::kUninitializedHandle, db_handle);
638 DCHECK(!download->IsPersisted());
639 download->SetDbHandle(db_handle);
640 download->SetIsPersisted();
641
642 RecordHistorySize(history_size_);
643 // Not counting |download|.
644 ++history_size_;
645
646 // Show in the appropriate browser UI.
647 // This includes buttons to save or cancel, for a dangerous download.
648 ShowDownloadInBrowser(download);
649
650 // Inform interested objects about the new download.
651 NotifyModelChanged();
652 }
653
654 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id,
655 int64 db_handle) {
656 // It's valid that we don't find a matching item, i.e. on shutdown.
657 if (!ContainsKey(downloads_, download_id))
658 return;
659
660 DownloadItemImpl* item = downloads_[download_id];
661 AddDownloadItemToHistory(item, db_handle);
662 if (item->IsSavePackageDownload()) {
663 OnSavePageItemAddedToPersistentStore(item);
664 } else {
665 OnDownloadItemAddedToPersistentStore(item);
666 }
667 }
668
669 // Once the new DownloadItem has been committed to the persistent store,
670 // associate it with its db_handle (TODO(benjhayden) merge db_handle with id),
671 // show it in the browser (TODO(benjhayden) the ui should observe us instead),
672 // and notify observers (TODO(benjhayden) observers should be able to see the
673 // item when it's created so they can observe it directly. Are there any
674 // clients that actually need to know when the item is added to the history?).
675 void DownloadManagerImpl::OnDownloadItemAddedToPersistentStore(
676 DownloadItemImpl* item) {
677 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
678 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << item->GetDbHandle()
679 << " download_id = " << item->GetId()
680 << " download = " << item->DebugString(true);
681
682 // If the download is still in progress, try to complete it.
683 //
684 // Otherwise, download has been cancelled or interrupted before we've
685 // received the DB handle. We post one final message to the history
686 // service so that it can be properly in sync with the DownloadItem's
687 // completion status, and also inform any observers so that they get
688 // more than just the start notification.
689 if (item->IsInProgress()) {
690 item->MaybeCompleteDownload();
691 } else {
692 DCHECK(item->IsCancelled());
693 active_downloads_.erase(item->GetId());
694 if (delegate_)
695 delegate_->UpdateItemInPersistentStore(item);
696 item->UpdateObservers();
697 }
698 }
699
700 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) { 623 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) {
701 // The 'contents' may no longer exist if the user closed the contents before 624 // The 'contents' may no longer exist if the user closed the contents before
702 // we get this start completion event. 625 // we get this start completion event.
703 WebContents* content = download->GetWebContents(); 626 WebContents* content = download->GetWebContents();
704 627
705 // If the contents no longer exists, we ask the embedder to suggest another 628 // If the contents no longer exists, we ask the embedder to suggest another
706 // contents. 629 // contents.
707 if (!content && delegate_) 630 if (!content && delegate_)
708 content = delegate_->GetAlternativeWebContentsToNotifyForDownload(); 631 content = delegate_->GetAlternativeWebContentsToNotifyForDownload();
709 632
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 DownloadSet remainder; 690 DownloadSet remainder;
768 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); 691 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin());
769 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), 692 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(),
770 all_downloads.begin(), all_downloads.end(), 693 all_downloads.begin(), all_downloads.end(),
771 insert_it); 694 insert_it);
772 DCHECK(remainder.empty()); 695 DCHECK(remainder.empty());
773 } 696 }
774 #endif 697 #endif
775 } 698 }
776 699
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) { 700 void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) {
808 if (delegate_)
809 delegate_->UpdateItemInPersistentStore(download);
810 int num_unopened = 0; 701 int num_unopened = 0;
811 for (DownloadMap::iterator it = downloads_.begin(); 702 for (DownloadMap::iterator it = downloads_.begin();
812 it != downloads_.end(); ++it) { 703 it != downloads_.end(); ++it) {
813 DownloadItemImpl* item = it->second; 704 DownloadItemImpl* item = it->second;
814 if (item->IsComplete() && 705 if (item->IsComplete() &&
815 !item->GetOpened()) 706 !item->GetOpened())
816 ++num_unopened; 707 ++num_unopened;
817 } 708 }
818 RecordOpensOutstanding(num_unopened); 709 RecordOpensOutstanding(num_unopened);
819 } 710 }
820 711
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 712 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698