OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/download/chrome_download_manager_delegate.h" | 5 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 } | 130 } |
131 | 131 |
132 DownloadId ChromeDownloadManagerDelegate::GetNextId() { | 132 DownloadId ChromeDownloadManagerDelegate::GetNextId() { |
133 if (!profile_->IsOffTheRecord()) | 133 if (!profile_->IsOffTheRecord()) |
134 return DownloadId(this, next_download_id_++); | 134 return DownloadId(this, next_download_id_++); |
135 | 135 |
136 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())-> | 136 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())-> |
137 GetDelegate()->GetNextId(); | 137 GetDelegate()->GetNextId(); |
138 } | 138 } |
139 | 139 |
140 bool ChromeDownloadManagerDelegate::ShouldStartDownload(int32 download_id) { | 140 bool ChromeDownloadManagerDelegate::DetermineDownloadTarget( |
141 // We create a download item and store it in our download map, and inform the | 141 DownloadItem* download, |
142 // history system of a new download. Since this method can be called while the | 142 const content::DownloadTargetCallback& callback) { |
143 // history service thread is still reading the persistent state, we do not | |
144 // insert the new DownloadItem into 'history_downloads_' or inform our | |
145 // observers at this point. OnCreateDownloadEntryComplete() handles that | |
146 // finalization of the the download creation as a callback from the history | |
147 // thread. | |
148 DownloadItem* download = | |
149 download_manager_->GetActiveDownloadItem(download_id); | |
150 if (!download) | |
151 return false; | |
152 | |
153 #if defined(ENABLE_SAFE_BROWSING) | 143 #if defined(ENABLE_SAFE_BROWSING) |
154 DownloadProtectionService* service = GetDownloadProtectionService(); | 144 DownloadProtectionService* service = GetDownloadProtectionService(); |
155 if (service) { | 145 if (service) { |
156 VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = " | 146 VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = " |
157 << download->DebugString(false); | 147 << download->DebugString(false); |
158 service->CheckDownloadUrl( | 148 service->CheckDownloadUrl( |
159 DownloadProtectionService::DownloadInfo::FromDownloadItem(*download), | 149 DownloadProtectionService::DownloadInfo::FromDownloadItem(*download), |
160 base::Bind( | 150 base::Bind( |
161 &ChromeDownloadManagerDelegate::CheckDownloadUrlDone, | 151 &ChromeDownloadManagerDelegate::CheckDownloadUrlDone, |
162 this, | 152 this, |
163 download->GetId())); | 153 download->GetId(), |
164 return false; | 154 callback)); |
| 155 return true; |
165 } | 156 } |
166 #endif | 157 #endif |
167 CheckDownloadUrlDone(download_id, DownloadProtectionService::SAFE); | 158 CheckDownloadUrlDone(download->GetId(), callback, |
168 return false; | 159 DownloadProtectionService::SAFE); |
| 160 return true; |
169 } | 161 } |
170 | 162 |
171 void ChromeDownloadManagerDelegate::ChooseDownloadPath(DownloadItem* item) { | 163 void ChromeDownloadManagerDelegate::ChooseDownloadPath( |
| 164 DownloadItem* item, |
| 165 const FilePath& suggested_path, |
| 166 const FileSelectedCallback& file_selected_callback) { |
172 // Deletes itself. | 167 // Deletes itself. |
173 DownloadFilePicker* file_picker = | 168 DownloadFilePicker* file_picker = |
174 #if defined(OS_CHROMEOS) | 169 #if defined(OS_CHROMEOS) |
175 new DownloadFilePickerChromeOS(); | 170 new DownloadFilePickerChromeOS(); |
176 #else | 171 #else |
177 new DownloadFilePicker(); | 172 new DownloadFilePicker(); |
178 #endif | 173 #endif |
179 file_picker->Init(download_manager_, item); | 174 file_picker->Init(download_manager_, item, suggested_path, |
| 175 file_selected_callback); |
180 } | 176 } |
181 | 177 |
182 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( | 178 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( |
183 const DownloadItem& download) { | 179 const FilePath& target_path, |
| 180 content::DownloadDangerType danger_type) { |
184 // If the download is not dangerous, just append .crdownload to the target | 181 // If the download is not dangerous, just append .crdownload to the target |
185 // path. | 182 // path. |
186 if (download.GetDangerType() == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) | 183 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) |
187 return download_util::GetCrDownloadPath(download.GetTargetFilePath()); | 184 return download_util::GetCrDownloadPath(target_path); |
188 | 185 |
189 // If the download is potentially dangerous we create a filename of the form | 186 // If the download is potentially dangerous we create a filename of the form |
190 // 'Unconfirmed <random>.crdownload'. | 187 // 'Unconfirmed <random>.crdownload'. |
191 FilePath::StringType file_name; | 188 FilePath::StringType file_name; |
192 FilePath dir = download.GetTargetFilePath().DirName(); | 189 FilePath dir = target_path.DirName(); |
193 #if defined(OS_WIN) | 190 #if defined(OS_WIN) |
194 string16 unconfirmed_prefix = | 191 string16 unconfirmed_prefix = |
195 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); | 192 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); |
196 #else | 193 #else |
197 std::string unconfirmed_prefix = | 194 std::string unconfirmed_prefix = |
198 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); | 195 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); |
199 #endif | 196 #endif |
200 base::SStringPrintf( | 197 base::SStringPrintf( |
201 &file_name, | 198 &file_name, |
202 unconfirmed_prefix.append( | 199 unconfirmed_prefix.append( |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 const content::SavePackagePathPickedCallback& callback) { | 472 const content::SavePackagePathPickedCallback& callback) { |
476 // Deletes itself. | 473 // Deletes itself. |
477 #if defined(OS_CHROMEOS) | 474 #if defined(OS_CHROMEOS) |
478 new SavePackageFilePickerChromeOS(web_contents, suggested_path, callback); | 475 new SavePackageFilePickerChromeOS(web_contents, suggested_path, callback); |
479 #else | 476 #else |
480 new SavePackageFilePicker(web_contents, suggested_path, default_extension, | 477 new SavePackageFilePicker(web_contents, suggested_path, default_extension, |
481 can_save_as_complete, download_prefs_.get(), callback); | 478 can_save_as_complete, download_prefs_.get(), callback); |
482 #endif | 479 #endif |
483 } | 480 } |
484 | 481 |
| 482 void ChromeDownloadManagerDelegate::ClearLastDownloadPath() { |
| 483 last_download_path_.clear(); |
| 484 } |
| 485 |
485 DownloadProtectionService* | 486 DownloadProtectionService* |
486 ChromeDownloadManagerDelegate::GetDownloadProtectionService() { | 487 ChromeDownloadManagerDelegate::GetDownloadProtectionService() { |
487 #if defined(ENABLE_SAFE_BROWSING) | 488 #if defined(ENABLE_SAFE_BROWSING) |
488 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); | 489 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); |
489 if (sb_service && sb_service->download_protection_service() && | 490 if (sb_service && sb_service->download_protection_service() && |
490 profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) { | 491 profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) { |
491 return sb_service->download_protection_service(); | 492 return sb_service->download_protection_service(); |
492 } | 493 } |
493 #endif | 494 #endif |
494 return NULL; | 495 return NULL; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 return !download.HasUserGesture() || !visited_referrer_before; | 528 return !download.HasUserGesture() || !visited_referrer_before; |
528 | 529 |
529 return danger_level == download_util::Dangerous; | 530 return danger_level == download_util::Dangerous; |
530 } | 531 } |
531 | 532 |
532 void ChromeDownloadManagerDelegate::GetReservedPath( | 533 void ChromeDownloadManagerDelegate::GetReservedPath( |
533 DownloadItem& download, | 534 DownloadItem& download, |
534 const FilePath& target_path, | 535 const FilePath& target_path, |
535 const FilePath& default_download_path, | 536 const FilePath& default_download_path, |
536 bool should_uniquify_path, | 537 bool should_uniquify_path, |
537 const DownloadPathReservationTracker::ReservedPathCallback callback) { | 538 const DownloadPathReservationTracker::ReservedPathCallback& callback) { |
538 DownloadPathReservationTracker::GetReservedPath( | 539 DownloadPathReservationTracker::GetReservedPath( |
539 download, target_path, default_download_path, should_uniquify_path, | 540 download, target_path, default_download_path, should_uniquify_path, |
540 callback); | 541 callback); |
541 } | 542 } |
542 | 543 |
543 void ChromeDownloadManagerDelegate::CheckDownloadUrlDone( | 544 void ChromeDownloadManagerDelegate::CheckDownloadUrlDone( |
544 int32 download_id, | 545 int32 download_id, |
| 546 const content::DownloadTargetCallback& callback, |
545 DownloadProtectionService::DownloadCheckResult result) { | 547 DownloadProtectionService::DownloadCheckResult result) { |
546 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 548 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
547 DownloadItem* download = | 549 DownloadItem* download = |
548 download_manager_->GetActiveDownloadItem(download_id); | 550 download_manager_->GetActiveDownloadItem(download_id); |
549 if (!download) | 551 if (!download) |
550 return; | 552 return; |
551 | 553 |
552 VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false) | 554 VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false) |
553 << " verdict = " << result; | 555 << " verdict = " << result; |
554 content::DownloadDangerType danger_type = download->GetDangerType(); | 556 content::DownloadDangerType danger_type = download->GetDangerType(); |
555 if (result != DownloadProtectionService::SAFE) | 557 if (result != DownloadProtectionService::SAFE) |
556 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; | 558 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; |
557 | 559 |
558 download_history_->CheckVisitedReferrerBefore( | 560 download_history_->CheckVisitedReferrerBefore( |
559 download_id, download->GetReferrerUrl(), | 561 download_id, download->GetReferrerUrl(), |
560 base::Bind(&ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone, | 562 base::Bind(&ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone, |
561 base::Unretained(this), download_id, danger_type)); | 563 base::Unretained(this), download_id, callback, danger_type)); |
562 } | 564 } |
563 | 565 |
564 void ChromeDownloadManagerDelegate::CheckClientDownloadDone( | 566 void ChromeDownloadManagerDelegate::CheckClientDownloadDone( |
565 int32 download_id, | 567 int32 download_id, |
566 DownloadProtectionService::DownloadCheckResult result) { | 568 DownloadProtectionService::DownloadCheckResult result) { |
567 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); | 569 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); |
568 if (!item) | 570 if (!item) |
569 return; | 571 return; |
570 | 572 |
571 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false) | 573 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 int download_id = crx_installers_[installer]; | 611 int download_id = crx_installers_[installer]; |
610 crx_installers_.erase(installer.get()); | 612 crx_installers_.erase(installer.get()); |
611 | 613 |
612 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); | 614 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); |
613 if (item) | 615 if (item) |
614 item->DelayedDownloadOpened(installer->did_handle_successfully()); | 616 item->DelayedDownloadOpened(installer->did_handle_successfully()); |
615 } | 617 } |
616 | 618 |
617 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone( | 619 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone( |
618 int32 download_id, | 620 int32 download_id, |
| 621 const content::DownloadTargetCallback& callback, |
619 content::DownloadDangerType danger_type, | 622 content::DownloadDangerType danger_type, |
620 bool visited_referrer_before) { | 623 bool visited_referrer_before) { |
621 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 624 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
622 | 625 |
623 DownloadItem* download = | 626 DownloadItem* download = |
624 download_manager_->GetActiveDownloadItem(download_id); | 627 download_manager_->GetActiveDownloadItem(download_id); |
625 if (!download) | 628 if (!download) |
626 return; | 629 return; |
627 | 630 |
628 bool should_prompt = (download->GetTargetDisposition() == | 631 bool should_prompt = (download->GetTargetDisposition() == |
(...skipping 21 matching lines...) Expand all Loading... |
650 !ShouldOpenFileBasedOnExtension(generated_name)) | 653 !ShouldOpenFileBasedOnExtension(generated_name)) |
651 should_prompt = true; | 654 should_prompt = true; |
652 } | 655 } |
653 if (download_prefs_->IsDownloadPathManaged()) | 656 if (download_prefs_->IsDownloadPathManaged()) |
654 should_prompt = false; | 657 should_prompt = false; |
655 | 658 |
656 // Determine the proper path for a download, by either one of the following: | 659 // Determine the proper path for a download, by either one of the following: |
657 // 1) using the default download directory. | 660 // 1) using the default download directory. |
658 // 2) prompting the user. | 661 // 2) prompting the user. |
659 FilePath target_directory; | 662 FilePath target_directory; |
660 if (should_prompt && !download_manager_->LastDownloadPath().empty()) | 663 if (should_prompt && !last_download_path_.empty()) |
661 target_directory = download_manager_->LastDownloadPath(); | 664 target_directory = last_download_path_; |
662 else | 665 else |
663 target_directory = download_prefs_->download_path(); | 666 target_directory = download_prefs_->download_path(); |
664 suggested_path = target_directory.Append(generated_name); | 667 suggested_path = target_directory.Append(generated_name); |
665 } else { | 668 } else { |
666 DCHECK(!should_prompt); | 669 DCHECK(!should_prompt); |
667 suggested_path = download->GetForcedFilePath(); | 670 suggested_path = download->GetForcedFilePath(); |
668 } | 671 } |
669 | 672 |
670 // If the download hasn't already been marked dangerous (could be | 673 // If the download hasn't already been marked dangerous (could be |
671 // DANGEROUS_URL), check if it is a dangerous file. | 674 // DANGEROUS_URL), check if it is a dangerous file. |
(...skipping 22 matching lines...) Expand all Loading... |
694 } else { | 697 } else { |
695 // Currently we only expect this case. | 698 // Currently we only expect this case. |
696 DCHECK_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, danger_type); | 699 DCHECK_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, danger_type); |
697 } | 700 } |
698 | 701 |
699 #if defined (OS_CHROMEOS) | 702 #if defined (OS_CHROMEOS) |
700 gdata::GDataDownloadObserver::SubstituteGDataDownloadPath( | 703 gdata::GDataDownloadObserver::SubstituteGDataDownloadPath( |
701 profile_, suggested_path, download, | 704 profile_, suggested_path, download, |
702 base::Bind( | 705 base::Bind( |
703 &ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback, | 706 &ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback, |
704 this, download->GetId(), should_prompt, is_forced_path, danger_type)); | 707 this, download->GetId(), callback, should_prompt, is_forced_path, |
| 708 danger_type)); |
705 #else | 709 #else |
706 GetReservedPath( | 710 GetReservedPath( |
707 *download, suggested_path, download_prefs_->download_path(), | 711 *download, suggested_path, download_prefs_->download_path(), |
708 !is_forced_path, | 712 !is_forced_path, |
709 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, | 713 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, |
710 this, download->GetId(), should_prompt, danger_type)); | 714 this, download->GetId(), callback, should_prompt, |
| 715 danger_type)); |
711 #endif | 716 #endif |
712 } | 717 } |
713 | 718 |
714 #if defined (OS_CHROMEOS) | 719 #if defined (OS_CHROMEOS) |
| 720 // TODO(asanka): Merge this logic with the logic in DownloadFilePickerChromeOS. |
715 void ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback( | 721 void ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback( |
716 int32 download_id, | 722 int32 download_id, |
| 723 const content::DownloadTargetCallback& callback, |
717 bool should_prompt, | 724 bool should_prompt, |
718 bool is_forced_path, | 725 bool is_forced_path, |
719 content::DownloadDangerType danger_type, | 726 content::DownloadDangerType danger_type, |
720 const FilePath& suggested_path) { | 727 const FilePath& suggested_path) { |
721 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 728 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
722 DownloadItem* download = | 729 DownloadItem* download = |
723 download_manager_->GetActiveDownloadItem(download_id); | 730 download_manager_->GetActiveDownloadItem(download_id); |
724 if (!download) | 731 if (!download) |
725 return; | 732 return; |
726 | 733 |
727 GetReservedPath( | 734 GetReservedPath( |
728 *download, suggested_path, download_prefs_->download_path(), | 735 *download, suggested_path, download_prefs_->download_path(), |
729 !is_forced_path, | 736 !is_forced_path, |
730 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, | 737 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, |
731 this, download->GetId(), should_prompt, danger_type)); | 738 this, download->GetId(), callback, should_prompt, |
| 739 danger_type)); |
732 } | 740 } |
733 #endif | 741 #endif |
734 | 742 |
735 void ChromeDownloadManagerDelegate::OnPathReservationAvailable( | 743 void ChromeDownloadManagerDelegate::OnPathReservationAvailable( |
736 int32 download_id, | 744 int32 download_id, |
| 745 const content::DownloadTargetCallback& callback, |
737 bool should_prompt, | 746 bool should_prompt, |
738 content::DownloadDangerType danger_type, | 747 content::DownloadDangerType danger_type, |
739 const FilePath& target_path, | 748 const FilePath& reserved_path, |
740 bool target_path_verified) { | 749 bool reserved_path_verified) { |
741 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 750 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
742 DownloadItem* download = | 751 DownloadItem* download = |
743 download_manager_->GetActiveDownloadItem(download_id); | 752 download_manager_->GetActiveDownloadItem(download_id); |
744 if (!download) | 753 if (!download) |
745 return; | 754 return; |
746 DownloadItem::TargetDisposition disposition; | 755 if (should_prompt || !reserved_path_verified) { |
747 // If the target path could not be verified then the path was non-existant, | 756 // If the target path could not be verified then the path was non-existant, |
748 // non writeable or could not be uniquified. Prompt the user. | 757 // non writeable or could not be uniquified. Prompt the user. |
749 if (should_prompt || !target_path_verified) | 758 ChooseDownloadPath( |
750 disposition = DownloadItem::TARGET_DISPOSITION_PROMPT; | 759 download, reserved_path, |
751 else | 760 base::Bind(&ChromeDownloadManagerDelegate::OnTargetPathDetermined, |
752 disposition = DownloadItem::TARGET_DISPOSITION_OVERWRITE; | 761 this, download_id, callback, |
753 download->OnTargetPathDetermined(target_path, disposition, danger_type); | 762 DownloadItem::TARGET_DISPOSITION_PROMPT, danger_type)); |
754 download_manager_->RestartDownload(download_id); | 763 } else { |
| 764 OnTargetPathDetermined(download_id, callback, |
| 765 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 766 danger_type, reserved_path); |
| 767 } |
| 768 } |
| 769 |
| 770 void ChromeDownloadManagerDelegate::OnTargetPathDetermined( |
| 771 int32 download_id, |
| 772 const content::DownloadTargetCallback& callback, |
| 773 DownloadItem::TargetDisposition disposition, |
| 774 content::DownloadDangerType danger_type, |
| 775 const FilePath& target_path) { |
| 776 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 777 FilePath intermediate_path; |
| 778 DownloadItem* download = |
| 779 download_manager_->GetActiveDownloadItem(download_id); |
| 780 if (!download) |
| 781 return; |
| 782 |
| 783 // If |target_path| is empty, then that means that the user wants to cancel |
| 784 // the download. |
| 785 if (!target_path.empty()) { |
| 786 intermediate_path = GetIntermediatePath(target_path, danger_type); |
| 787 |
| 788 // Retain the last directory. Exclude temporary downloads since the path |
| 789 // likely points at the location of a temporary file. |
| 790 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a |
| 791 // directory to persist. Or perhaps, if the GData path |
| 792 // substitution logic is moved here, then we would have a |
| 793 // persistable path after the DownloadFilePicker is done. |
| 794 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT && |
| 795 !download->IsTemporary()) |
| 796 last_download_path_ = target_path.DirName(); |
| 797 } |
| 798 callback.Run(target_path, disposition, danger_type, intermediate_path); |
755 } | 799 } |
756 | 800 |
757 void ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore( | 801 void ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore( |
758 int32 download_id, int64 db_handle) { | 802 int32 download_id, int64 db_handle) { |
759 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 803 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
760 // call this function with an invalid |db_handle|. For instance, this can | 804 // call this function with an invalid |db_handle|. For instance, this can |
761 // happen when the history database is offline. We cannot have multiple | 805 // happen when the history database is offline. We cannot have multiple |
762 // DownloadItems with the same invalid db_handle, so we need to assign a | 806 // DownloadItems with the same invalid db_handle, so we need to assign a |
763 // unique |db_handle| here. | 807 // unique |db_handle| here. |
764 if (db_handle == DownloadItem::kUninitializedHandle) | 808 if (db_handle == DownloadItem::kUninitializedHandle) |
765 db_handle = download_history_->GetNextFakeDbHandle(); | 809 db_handle = download_history_->GetNextFakeDbHandle(); |
766 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); | 810 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); |
767 } | 811 } |
OLD | NEW |