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