OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/download/download_manager.h" | 5 #include "chrome/browser/download/download_manager.h" |
6 | 6 |
7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "app/resource_bundle.h" | 8 #include "app/resource_bundle.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 new OtherDownloadManagerObserver(this)); | 234 new OtherDownloadManagerObserver(this)); |
235 | 235 |
236 return true; | 236 return true; |
237 } | 237 } |
238 | 238 |
239 // We have received a message from DownloadFileManager about a new download. We | 239 // We have received a message from DownloadFileManager about a new download. We |
240 // create a download item and store it in our download map, and inform the | 240 // create a download item and store it in our download map, and inform the |
241 // history system of a new download. Since this method can be called while the | 241 // history system of a new download. Since this method can be called while the |
242 // history service thread is still reading the persistent state, we do not | 242 // history service thread is still reading the persistent state, we do not |
243 // insert the new DownloadItem into 'history_downloads_' or inform our | 243 // insert the new DownloadItem into 'history_downloads_' or inform our |
244 // observers at this point. OnCreateDatabaseEntryComplete() handles that | 244 // observers at this point. OnCreateDownloadEntryComplete() handles that |
245 // finalization of the the download creation as a callback from the | 245 // finalization of the the download creation as a callback from the |
246 // history thread. | 246 // history thread. |
247 void DownloadManager::StartDownload(DownloadCreateInfo* info) { | 247 void DownloadManager::StartDownload(DownloadCreateInfo* info) { |
248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
249 DCHECK(info); | 249 DCHECK(info); |
250 | 250 |
251 // Check whether this download is for an extension install or not. | 251 // Check whether this download is for an extension install or not. |
252 // Allow extensions to be explicitly saved. | 252 // Allow extensions to be explicitly saved. |
253 if (!info->prompt_user_for_save_location) { | 253 if (!info->prompt_user_for_save_location) { |
254 if (UserScript::HasUserScriptFileExtension(info->url) || | 254 if (UserScript::HasUserScriptFileExtension(info->url) || |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 DownloadItem* download = new DownloadItem(this, *info, | 423 DownloadItem* download = new DownloadItem(this, *info, |
424 profile_->IsOffTheRecord()); | 424 profile_->IsOffTheRecord()); |
425 DCHECK(!ContainsKey(in_progress_, info->download_id)); | 425 DCHECK(!ContainsKey(in_progress_, info->download_id)); |
426 DCHECK(!ContainsKey(active_downloads_, info->download_id)); | 426 DCHECK(!ContainsKey(active_downloads_, info->download_id)); |
427 downloads_.insert(download); | 427 downloads_.insert(download); |
428 active_downloads_[info->download_id] = download; | 428 active_downloads_[info->download_id] = download; |
429 } | 429 } |
430 | 430 |
431 void DownloadManager::AttachDownloadItem(DownloadCreateInfo* info, | 431 void DownloadManager::AttachDownloadItem(DownloadCreateInfo* info, |
432 const FilePath& target_path) { | 432 const FilePath& target_path) { |
| 433 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString(); |
| 434 |
433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
434 | 436 |
435 scoped_ptr<DownloadCreateInfo> infop(info); | 437 scoped_ptr<DownloadCreateInfo> infop(info); |
436 info->path = target_path; | 438 info->path = target_path; |
437 | 439 |
438 // NOTE(ahendrickson) Eventually |active_downloads_| will replace | 440 // NOTE(ahendrickson) Eventually |active_downloads_| will replace |
439 // |in_progress_|, but we don't want to change the semantics yet. | 441 // |in_progress_|, but we don't want to change the semantics yet. |
440 DCHECK(!ContainsKey(in_progress_, info->download_id)); | 442 DCHECK(!ContainsKey(in_progress_, info->download_id)); |
441 DCHECK(ContainsKey(active_downloads_, info->download_id)); | 443 DCHECK(ContainsKey(active_downloads_, info->download_id)); |
442 DownloadItem* download = active_downloads_[info->download_id]; | 444 DownloadItem* download = active_downloads_[info->download_id]; |
443 DCHECK(download != NULL); | 445 DCHECK(download != NULL); |
444 DCHECK(ContainsKey(downloads_, download)); | 446 DCHECK(ContainsKey(downloads_, download)); |
445 | 447 |
446 download->SetFileCheckResults(info->path, | 448 download->SetFileCheckResults(info->path, |
447 info->is_dangerous, | 449 info->is_dangerous, |
448 info->path_uniquifier, | 450 info->path_uniquifier, |
449 info->prompt_user_for_save_location, | 451 info->prompt_user_for_save_location, |
450 info->is_extension_install, | 452 info->is_extension_install, |
451 info->original_name); | 453 info->original_name); |
452 in_progress_[info->download_id] = download; | 454 in_progress_[info->download_id] = download; |
| 455 UpdateAppIcon(); // Reflect entry into in_progress_. |
453 | 456 |
454 bool download_finished = ContainsKey(pending_finished_downloads_, | 457 // Rename to intermediate name. |
455 info->download_id); | 458 if (info->is_dangerous) { |
456 | 459 // The download is not safe. We can now rename the file to its |
457 VLOG(20) << __FUNCTION__ << "()" | 460 // tentative name using OnFinalDownloadName (the actual final |
458 << " target_path = \"" << target_path.value() << "\"" | 461 // name after user confirmation will be set in |
459 << " download_finished = " << download_finished | 462 // ProceedWithFinishedDangerousDownload). |
460 << " info = " << info->DebugString() | |
461 << " download = " << download->DebugString(true); | |
462 | |
463 if (download_finished || info->is_dangerous) { | |
464 // The download has already finished or the download is not safe. | |
465 // We can now rename the file to its final name (or its tentative name | |
466 // in dangerous download cases). | |
467 BrowserThread::PostTask( | 463 BrowserThread::PostTask( |
468 BrowserThread::FILE, FROM_HERE, | 464 BrowserThread::FILE, FROM_HERE, |
469 NewRunnableMethod( | 465 NewRunnableMethod( |
470 file_manager_, &DownloadFileManager::OnFinalDownloadName, | 466 file_manager_, &DownloadFileManager::OnFinalDownloadName, |
471 download->id(), target_path, !info->is_dangerous, | 467 download->id(), target_path, false, |
472 make_scoped_refptr(this))); | 468 make_scoped_refptr(this))); |
473 } else { | 469 } else { |
474 // The download hasn't finished and it is a safe download. We need to | 470 // The download is a safe download. We need to |
475 // rename it to its intermediate '.crdownload' path. | 471 // rename it to its intermediate '.crdownload' path. The final |
| 472 // name after user confirmation will be set from |
| 473 // DownloadItem::OnSafeDownloadFinished. |
476 FilePath download_path = download_util::GetCrDownloadPath(target_path); | 474 FilePath download_path = download_util::GetCrDownloadPath(target_path); |
477 BrowserThread::PostTask( | 475 BrowserThread::PostTask( |
478 BrowserThread::FILE, FROM_HERE, | 476 BrowserThread::FILE, FROM_HERE, |
479 NewRunnableMethod( | 477 NewRunnableMethod( |
480 file_manager_, &DownloadFileManager::OnIntermediateDownloadName, | 478 file_manager_, &DownloadFileManager::OnIntermediateDownloadName, |
481 download->id(), download_path, make_scoped_refptr(this))); | 479 download->id(), download_path, make_scoped_refptr(this))); |
482 download->Rename(download_path); | 480 download->Rename(download_path); |
483 } | 481 } |
484 | 482 |
485 if (download_finished) { | |
486 // If the download already completed by the time we reached this point, then | |
487 // notify observers that it did. | |
488 OnAllDataSaved(info->download_id, | |
489 pending_finished_downloads_[info->download_id]); | |
490 } | |
491 | |
492 download_history_->AddEntry(*info, download, | 483 download_history_->AddEntry(*info, download, |
493 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); | 484 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); |
494 | |
495 UpdateAppIcon(); | |
496 } | 485 } |
497 | 486 |
498 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { | 487 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { |
499 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 488 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
500 DownloadMap::iterator it = active_downloads_.find(download_id); | 489 DownloadMap::iterator it = active_downloads_.find(download_id); |
501 if (it != active_downloads_.end()) { | 490 if (it != active_downloads_.end()) { |
502 DownloadItem* download = it->second; | 491 DownloadItem* download = it->second; |
503 if (download->state() == DownloadItem::IN_PROGRESS) { | 492 if (download->state() == DownloadItem::IN_PROGRESS) { |
504 download->Update(size); | 493 download->Update(size); |
| 494 UpdateAppIcon(); // Reflect size updates. |
505 download_history_->UpdateEntry(download); | 495 download_history_->UpdateEntry(download); |
506 } | 496 } |
507 } | 497 } |
508 UpdateAppIcon(); | |
509 } | 498 } |
510 | 499 |
511 void DownloadManager::OnAllDataSaved(int32 download_id, int64 size) { | 500 void DownloadManager::OnAllDataSaved(int32 download_id, int64 size) { |
512 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 501 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
513 << " size = " << size; | 502 << " size = " << size; |
514 DownloadMap::iterator it = in_progress_.find(download_id); | |
515 if (it == in_progress_.end()) { | |
516 // The download is done, but the user hasn't selected a final location for | |
517 // it yet (the Save As dialog box is probably still showing), so just keep | |
518 // track of the fact that this download id is complete, when the | |
519 // DownloadItem is constructed later we'll notify its completion then. | |
520 DCHECK(!ContainsKey(pending_finished_downloads_, download_id)); | |
521 pending_finished_downloads_[download_id] = size; | |
522 VLOG(20) << __FUNCTION__ << "()" << " Added download_id = " << download_id | |
523 << " to pending_finished_downloads_"; | |
524 return; | |
525 } | |
526 | 503 |
527 // Remove the id from the list of pending ids. | 504 DCHECK_EQ(1U, active_downloads_.count(download_id)); |
528 PendingFinishedMap::iterator erase_it = | 505 DownloadItem* download = active_downloads_[download_id]; |
529 pending_finished_downloads_.find(download_id); | |
530 if (erase_it != pending_finished_downloads_.end()) { | |
531 pending_finished_downloads_.erase(erase_it); | |
532 VLOG(20) << __FUNCTION__ << "()" << " Removed download_id = " << download_id | |
533 << " from pending_finished_downloads_"; | |
534 } | |
535 | |
536 DownloadItem* download = it->second; | |
537 | |
538 VLOG(20) << __FUNCTION__ << "()" | |
539 << " download = " << download->DebugString(true); | |
540 | |
541 download->OnAllDataSaved(size); | 506 download->OnAllDataSaved(size); |
542 | 507 |
543 // Clean up will happen when the history system create callback runs if we | 508 MaybeCompleteDownload(download); |
544 // don't have a valid db_handle yet. | 509 } |
545 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { | 510 |
546 in_progress_.erase(it); | 511 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { |
547 download_history_->UpdateEntry(download); | 512 // If we don't have all the data, the download is not ready for |
| 513 // completion. |
| 514 if (!download->AllDataReceived()) |
| 515 return false; |
| 516 |
| 517 // If the download isn't active (e.g. has been cancelled) it's not |
| 518 // ready for completion. |
| 519 if (active_downloads_.count(download->id()) == 0) |
| 520 return false; |
| 521 |
| 522 // If the download hasn't been inserted into the history system |
| 523 // (which occurs strictly after file name determination, intermediate |
| 524 // file rename, and UI display) then it's not ready for completion. |
| 525 return (download->db_handle() != DownloadHistory::kUninitializedHandle); |
| 526 } |
| 527 |
| 528 void DownloadManager::MaybeCompleteDownload(DownloadItem* download) { |
| 529 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 530 VLOG(20) << __FUNCTION__ << "()" << " download = " |
| 531 << download->DebugString(false); |
| 532 |
| 533 if (!IsDownloadReadyForCompletion(download)) |
| 534 return; |
| 535 |
| 536 // TODO(rdsmith): DCHECK that we only pass through this point |
| 537 // once per download. The natural way to do this is by a state |
| 538 // transition on the DownloadItem. |
| 539 |
| 540 // Confirm we're in the proper set of states to be here; |
| 541 // in in_progress_, have all data, have a history handle. |
| 542 DCHECK_EQ(1u, in_progress_.count(download->id())); |
| 543 DCHECK(download->AllDataReceived()); |
| 544 DCHECK(download->db_handle() != DownloadHistory::kUninitializedHandle); |
| 545 DCHECK_EQ(1u, history_downloads_.count(download->db_handle())); |
| 546 |
| 547 VLOG(20) << __FUNCTION__ << "()" << " executing: download = " |
| 548 << download->DebugString(false); |
| 549 |
| 550 // Remove the id from in_progress |
| 551 in_progress_.erase(download->id()); |
| 552 UpdateAppIcon(); // Reflect removal from in_progress_. |
| 553 |
| 554 // Final update of download item and history. |
| 555 download->OnDataReceptionAccepted(); |
| 556 download_history_->UpdateEntry(download); |
| 557 |
| 558 switch (download->safety_state()) { |
| 559 case DownloadItem::DANGEROUS: |
| 560 // If this a dangerous download not yet validated by the user, don't do |
| 561 // anything. When the user notifies us, it will trigger a call to |
| 562 // ProceedWithFinishedDangerousDownload. |
| 563 return; |
| 564 case DownloadItem::DANGEROUS_BUT_VALIDATED: |
| 565 // The dangerous download has been validated by the user. We first |
| 566 // need to rename the downloaded file from its temporary name to |
| 567 // its final name. We will continue the download processing in the |
| 568 // callback. |
| 569 BrowserThread::PostTask( |
| 570 BrowserThread::FILE, FROM_HERE, |
| 571 NewRunnableMethod( |
| 572 this, &DownloadManager::ProceedWithFinishedDangerousDownload, |
| 573 download->db_handle(), |
| 574 download->full_path(), download->target_name())); |
| 575 return; |
| 576 case DownloadItem::SAFE: |
| 577 // The download is safe; just finish it. |
| 578 download->OnSafeDownloadFinished(file_manager_); |
| 579 return; |
548 } | 580 } |
549 | |
550 UpdateAppIcon(); | |
551 | |
552 // If this a dangerous download not yet validated by the user, don't do | |
553 // anything. When the user notifies us, it will trigger a call to | |
554 // ProceedWithFinishedDangerousDownload. | |
555 if (download->safety_state() == DownloadItem::DANGEROUS) { | |
556 return; | |
557 } | |
558 | |
559 if (download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) { | |
560 // We first need to rename the downloaded file from its temporary name to | |
561 // its final name before we can continue. | |
562 BrowserThread::PostTask( | |
563 BrowserThread::FILE, FROM_HERE, | |
564 NewRunnableMethod( | |
565 this, &DownloadManager::ProceedWithFinishedDangerousDownload, | |
566 download->db_handle(), | |
567 download->full_path(), download->target_name())); | |
568 return; | |
569 } | |
570 | |
571 download->OnSafeDownloadFinished(file_manager_); | |
572 } | 581 } |
573 | 582 |
574 void DownloadManager::RemoveFromActiveList(int32 download_id) { | 583 void DownloadManager::RemoveFromActiveList(int32 download_id) { |
575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 584 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
576 active_downloads_.erase(download_id); | 585 active_downloads_.erase(download_id); |
577 } | 586 } |
578 | 587 |
579 void DownloadManager::DownloadRenamedToFinalName(int download_id, | 588 void DownloadManager::DownloadRenamedToFinalName(int download_id, |
580 const FilePath& full_path) { | 589 const FilePath& full_path) { |
581 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 590 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 DownloadItem* download = it->second; | 661 DownloadItem* download = it->second; |
653 | 662 |
654 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 663 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
655 << " download = " << download->DebugString(true); | 664 << " download = " << download->DebugString(true); |
656 | 665 |
657 // Clean up will happen when the history system create callback runs if we | 666 // Clean up will happen when the history system create callback runs if we |
658 // don't have a valid db_handle yet. | 667 // don't have a valid db_handle yet. |
659 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { | 668 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { |
660 in_progress_.erase(it); | 669 in_progress_.erase(it); |
661 active_downloads_.erase(download_id); | 670 active_downloads_.erase(download_id); |
| 671 UpdateAppIcon(); // Reflect removal from in_progress_. |
662 download_history_->UpdateEntry(download); | 672 download_history_->UpdateEntry(download); |
663 } | 673 } |
664 | 674 |
665 DownloadCancelledInternal(download_id, | 675 DownloadCancelledInternal(download_id, |
666 download->render_process_id(), | 676 download->render_process_id(), |
667 download->request_id()); | 677 download->request_id()); |
668 UpdateAppIcon(); | |
669 } | 678 } |
670 | 679 |
671 void DownloadManager::DownloadCancelledInternal(int download_id, | 680 void DownloadManager::DownloadCancelledInternal(int download_id, |
672 int render_process_id, | 681 int render_process_id, |
673 int request_id) { | 682 int request_id) { |
674 // Cancel the network request. RDH is guaranteed to outlive the IO thread. | 683 // Cancel the network request. RDH is guaranteed to outlive the IO thread. |
675 BrowserThread::PostTask( | 684 BrowserThread::PostTask( |
676 BrowserThread::IO, FROM_HERE, | 685 BrowserThread::IO, FROM_HERE, |
677 NewRunnableFunction(&download_util::CancelDownloadRequest, | 686 NewRunnableFunction(&download_util::CancelDownloadRequest, |
678 g_browser_process->resource_dispatcher_host(), | 687 g_browser_process->resource_dispatcher_host(), |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 // Insert into our full map. | 987 // Insert into our full map. |
979 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); | 988 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); |
980 history_downloads_[download->db_handle()] = download; | 989 history_downloads_[download->db_handle()] = download; |
981 | 990 |
982 // Show in the appropriate browser UI. | 991 // Show in the appropriate browser UI. |
983 ShowDownloadInBrowser(info, download); | 992 ShowDownloadInBrowser(info, download); |
984 | 993 |
985 // Inform interested objects about the new download. | 994 // Inform interested objects about the new download. |
986 NotifyModelChanged(); | 995 NotifyModelChanged(); |
987 | 996 |
988 // If this download has been completed before we've received the db handle, | 997 // If this download has been cancelled before we've received the DB handle, |
989 // post one final message to the history service so that it can be properly | 998 // post one final message to the history service so that it can be properly |
990 // in sync with the DownloadItem's completion status, and also inform any | 999 // in sync with the DownloadItem's completion status, and also inform any |
991 // observers so that they get more than just the start notification. | 1000 // observers so that they get more than just the start notification. |
| 1001 // |
| 1002 // Otherwise, try to complete the download |
992 if (download->state() != DownloadItem::IN_PROGRESS) { | 1003 if (download->state() != DownloadItem::IN_PROGRESS) { |
| 1004 DCHECK_EQ(DownloadItem::CANCELLED, download->state()); |
993 in_progress_.erase(it); | 1005 in_progress_.erase(it); |
994 // TODO(ahendrickson) -- We don't actually know whether or not we can | |
995 // remove the download item from the |active_downloads_| map, as there | |
996 // is no state in |DownloadItem::DownloadState| to indicate that the | |
997 // downloads system is done with an item. Fix this when we have a | |
998 // proper final state to check for. | |
999 active_downloads_.erase(info.download_id); | 1006 active_downloads_.erase(info.download_id); |
1000 download_history_->UpdateEntry(download); | 1007 download_history_->UpdateEntry(download); |
1001 download->UpdateObservers(); | 1008 download->UpdateObservers(); |
| 1009 } else { |
| 1010 MaybeCompleteDownload(download); |
1002 } | 1011 } |
1003 | |
1004 UpdateAppIcon(); | |
1005 } | 1012 } |
1006 | 1013 |
1007 void DownloadManager::ShowDownloadInBrowser(const DownloadCreateInfo& info, | 1014 void DownloadManager::ShowDownloadInBrowser(const DownloadCreateInfo& info, |
1008 DownloadItem* download) { | 1015 DownloadItem* download) { |
1009 // The 'contents' may no longer exist if the user closed the tab before we | 1016 // The 'contents' may no longer exist if the user closed the tab before we |
1010 // get this start completion event. If it does, tell the origin TabContents | 1017 // get this start completion event. If it does, tell the origin TabContents |
1011 // to display its download shelf. | 1018 // to display its download shelf. |
1012 TabContents* contents = tab_util::GetTabContentsByID(info.child_id, | 1019 TabContents* contents = tab_util::GetTabContentsByID(info.child_id, |
1013 info.render_view_id); | 1020 info.render_view_id); |
1014 | 1021 |
(...skipping 27 matching lines...) Expand all Loading... |
1042 return item; | 1049 return item; |
1043 } | 1050 } |
1044 return NULL; | 1051 return NULL; |
1045 } | 1052 } |
1046 | 1053 |
1047 // Confirm that everything in all maps is also in |downloads_|, and that | 1054 // Confirm that everything in all maps is also in |downloads_|, and that |
1048 // everything in |downloads_| is also in some other map. | 1055 // everything in |downloads_| is also in some other map. |
1049 void DownloadManager::AssertContainersConsistent() const { | 1056 void DownloadManager::AssertContainersConsistent() const { |
1050 #if !defined(NDEBUG) | 1057 #if !defined(NDEBUG) |
1051 // Turn everything into sets. | 1058 // Turn everything into sets. |
1052 DownloadSet in_progress_set, history_set; | 1059 DownloadSet active_set, history_set; |
1053 const DownloadMap* input_maps[] = {&active_downloads_, &history_downloads_}; | 1060 const DownloadMap* input_maps[] = {&active_downloads_, &history_downloads_}; |
1054 DownloadSet* local_sets[] = {&in_progress_set, &history_set}; | 1061 DownloadSet* local_sets[] = {&active_set, &history_set}; |
1055 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets)); | 1062 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets)); |
1056 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { | 1063 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { |
1057 for (DownloadMap::const_iterator it = input_maps[i]->begin(); | 1064 for (DownloadMap::const_iterator it = input_maps[i]->begin(); |
1058 it != input_maps[i]->end(); it++) { | 1065 it != input_maps[i]->end(); it++) { |
1059 local_sets[i]->insert(&*it->second); | 1066 local_sets[i]->insert(&*it->second); |
1060 } | 1067 } |
1061 } | 1068 } |
1062 | 1069 |
1063 // Check if each set is fully present in downloads, and create a union. | 1070 // Check if each set is fully present in downloads, and create a union. |
1064 const DownloadSet* all_sets[] = {&in_progress_set, &history_set, | 1071 const DownloadSet* all_sets[] = {&active_set, &history_set, |
1065 &save_page_as_downloads_}; | 1072 &save_page_as_downloads_}; |
1066 DownloadSet downloads_union; | 1073 DownloadSet downloads_union; |
1067 for (int i = 0; i < static_cast<int>(ARRAYSIZE_UNSAFE(all_sets)); i++) { | 1074 for (int i = 0; i < static_cast<int>(ARRAYSIZE_UNSAFE(all_sets)); i++) { |
1068 DownloadSet remainder; | 1075 DownloadSet remainder; |
1069 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); | 1076 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); |
1070 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), | 1077 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), |
1071 downloads_.begin(), downloads_.end(), | 1078 downloads_.begin(), downloads_.end(), |
1072 insert_it); | 1079 insert_it); |
1073 DCHECK(remainder.empty()); | 1080 DCHECK(remainder.empty()); |
1074 std::insert_iterator<DownloadSet> | 1081 std::insert_iterator<DownloadSet> |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 observed_download_manager_->RemoveObserver(this); | 1117 observed_download_manager_->RemoveObserver(this); |
1111 } | 1118 } |
1112 | 1119 |
1113 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { | 1120 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { |
1114 observing_download_manager_->NotifyModelChanged(); | 1121 observing_download_manager_->NotifyModelChanged(); |
1115 } | 1122 } |
1116 | 1123 |
1117 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { | 1124 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { |
1118 observed_download_manager_ = NULL; | 1125 observed_download_manager_ = NULL; |
1119 } | 1126 } |
OLD | NEW |