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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 } | 147 } |
148 | 148 |
149 DownloadId ChromeDownloadManagerDelegate::GetNextId() { | 149 DownloadId ChromeDownloadManagerDelegate::GetNextId() { |
150 if (!profile_->IsOffTheRecord()) | 150 if (!profile_->IsOffTheRecord()) |
151 return DownloadId(this, next_download_id_++); | 151 return DownloadId(this, next_download_id_++); |
152 | 152 |
153 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())-> | 153 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())-> |
154 GetDelegate()->GetNextId(); | 154 GetDelegate()->GetNextId(); |
155 } | 155 } |
156 | 156 |
157 bool ChromeDownloadManagerDelegate::ShouldStartDownload(int32 download_id) { | 157 bool ChromeDownloadManagerDelegate::DetermineDownloadTarget( |
158 // We create a download item and store it in our download map, and inform the | 158 DownloadItem* download, |
159 // history system of a new download. Since this method can be called while the | 159 const content::DownloadTargetCallback& callback) { |
160 // history service thread is still reading the persistent state, we do not | |
161 // insert the new DownloadItem into 'history_downloads_' or inform our | |
162 // observers at this point. OnCreateDownloadEntryComplete() handles that | |
163 // finalization of the the download creation as a callback from the history | |
164 // thread. | |
165 DownloadItem* download = | |
166 download_manager_->GetActiveDownloadItem(download_id); | |
167 if (!download) | |
168 return false; | |
169 | |
170 #if defined(ENABLE_SAFE_BROWSING) | 160 #if defined(ENABLE_SAFE_BROWSING) |
171 DownloadProtectionService* service = GetDownloadProtectionService(); | 161 DownloadProtectionService* service = GetDownloadProtectionService(); |
172 if (service) { | 162 if (service) { |
173 VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = " | 163 VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = " |
174 << download->DebugString(false); | 164 << download->DebugString(false); |
175 service->CheckDownloadUrl( | 165 service->CheckDownloadUrl( |
176 DownloadProtectionService::DownloadInfo::FromDownloadItem(*download), | 166 DownloadProtectionService::DownloadInfo::FromDownloadItem(*download), |
177 base::Bind( | 167 base::Bind( |
178 &ChromeDownloadManagerDelegate::CheckDownloadUrlDone, | 168 &ChromeDownloadManagerDelegate::CheckDownloadUrlDone, |
179 this, | 169 this, |
180 download->GetId())); | 170 download->GetId(), |
181 return false; | 171 callback)); |
| 172 return true; |
182 } | 173 } |
183 #endif | 174 #endif |
184 CheckDownloadUrlDone(download_id, DownloadProtectionService::SAFE); | 175 CheckDownloadUrlDone(download->GetId(), callback, |
185 return false; | 176 DownloadProtectionService::SAFE); |
| 177 return true; |
186 } | 178 } |
187 | 179 |
188 void ChromeDownloadManagerDelegate::ChooseDownloadPath(DownloadItem* item) { | 180 void ChromeDownloadManagerDelegate::ChooseDownloadPath( |
| 181 DownloadItem* item, |
| 182 const FilePath& suggested_path, |
| 183 const FileSelectedCallback& file_selected_callback) { |
189 // Deletes itself. | 184 // Deletes itself. |
190 DownloadFilePicker* file_picker = | 185 DownloadFilePicker* file_picker = |
191 #if defined(OS_CHROMEOS) | 186 #if defined(OS_CHROMEOS) |
192 new DownloadFilePickerChromeOS(); | 187 new DownloadFilePickerChromeOS(); |
193 #else | 188 #else |
194 new DownloadFilePicker(); | 189 new DownloadFilePicker(); |
195 #endif | 190 #endif |
196 file_picker->Init(download_manager_, item); | 191 file_picker->Init(download_manager_, item, suggested_path, |
| 192 file_selected_callback); |
197 } | 193 } |
198 | 194 |
199 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( | 195 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( |
200 const DownloadItem& download) { | 196 const FilePath& target_path, |
| 197 content::DownloadDangerType danger_type) { |
201 // If the download is not dangerous, just append .crdownload to the target | 198 // If the download is not dangerous, just append .crdownload to the target |
202 // path. | 199 // path. |
203 if (download.GetDangerType() == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) | 200 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) |
204 return download_util::GetCrDownloadPath(download.GetTargetFilePath()); | 201 return download_util::GetCrDownloadPath(target_path); |
205 | 202 |
206 // If the download is potentially dangerous we create a filename of the form | 203 // If the download is potentially dangerous we create a filename of the form |
207 // 'Unconfirmed <random>.crdownload'. | 204 // 'Unconfirmed <random>.crdownload'. |
208 FilePath::StringType file_name; | 205 FilePath::StringType file_name; |
209 FilePath dir = download.GetTargetFilePath().DirName(); | 206 FilePath dir = target_path.DirName(); |
210 #if defined(OS_WIN) | 207 #if defined(OS_WIN) |
211 string16 unconfirmed_prefix = | 208 string16 unconfirmed_prefix = |
212 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); | 209 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); |
213 #else | 210 #else |
214 std::string unconfirmed_prefix = | 211 std::string unconfirmed_prefix = |
215 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); | 212 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); |
216 #endif | 213 #endif |
217 base::SStringPrintf( | 214 base::SStringPrintf( |
218 &file_name, | 215 &file_name, |
219 unconfirmed_prefix.append( | 216 unconfirmed_prefix.append( |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 const content::SavePackagePathPickedCallback& callback) { | 487 const content::SavePackagePathPickedCallback& callback) { |
491 // Deletes itself. | 488 // Deletes itself. |
492 #if defined(OS_CHROMEOS) | 489 #if defined(OS_CHROMEOS) |
493 new SavePackageFilePickerChromeOS(web_contents, suggested_path, callback); | 490 new SavePackageFilePickerChromeOS(web_contents, suggested_path, callback); |
494 #else | 491 #else |
495 new SavePackageFilePicker(web_contents, suggested_path, default_extension, | 492 new SavePackageFilePicker(web_contents, suggested_path, default_extension, |
496 can_save_as_complete, download_prefs_.get(), callback); | 493 can_save_as_complete, download_prefs_.get(), callback); |
497 #endif | 494 #endif |
498 } | 495 } |
499 | 496 |
| 497 void ChromeDownloadManagerDelegate::ClearLastDownloadPath() { |
| 498 last_download_path_.clear(); |
| 499 } |
| 500 |
500 DownloadProtectionService* | 501 DownloadProtectionService* |
501 ChromeDownloadManagerDelegate::GetDownloadProtectionService() { | 502 ChromeDownloadManagerDelegate::GetDownloadProtectionService() { |
502 #if defined(ENABLE_SAFE_BROWSING) | 503 #if defined(ENABLE_SAFE_BROWSING) |
503 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); | 504 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); |
504 if (sb_service && sb_service->download_protection_service() && | 505 if (sb_service && sb_service->download_protection_service() && |
505 profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) { | 506 profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) { |
506 return sb_service->download_protection_service(); | 507 return sb_service->download_protection_service(); |
507 } | 508 } |
508 #endif | 509 #endif |
509 return NULL; | 510 return NULL; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 return !download.HasUserGesture() || !visited_referrer_before; | 543 return !download.HasUserGesture() || !visited_referrer_before; |
543 | 544 |
544 return danger_level == download_util::Dangerous; | 545 return danger_level == download_util::Dangerous; |
545 } | 546 } |
546 | 547 |
547 void ChromeDownloadManagerDelegate::GetReservedPath( | 548 void ChromeDownloadManagerDelegate::GetReservedPath( |
548 DownloadItem& download, | 549 DownloadItem& download, |
549 const FilePath& target_path, | 550 const FilePath& target_path, |
550 const FilePath& default_download_path, | 551 const FilePath& default_download_path, |
551 bool should_uniquify_path, | 552 bool should_uniquify_path, |
552 const DownloadPathReservationTracker::ReservedPathCallback callback) { | 553 const DownloadPathReservationTracker::ReservedPathCallback& callback) { |
553 DownloadPathReservationTracker::GetReservedPath( | 554 DownloadPathReservationTracker::GetReservedPath( |
554 download, target_path, default_download_path, should_uniquify_path, | 555 download, target_path, default_download_path, should_uniquify_path, |
555 callback); | 556 callback); |
556 } | 557 } |
557 | 558 |
558 void ChromeDownloadManagerDelegate::CheckDownloadUrlDone( | 559 void ChromeDownloadManagerDelegate::CheckDownloadUrlDone( |
559 int32 download_id, | 560 int32 download_id, |
| 561 const content::DownloadTargetCallback& callback, |
560 DownloadProtectionService::DownloadCheckResult result) { | 562 DownloadProtectionService::DownloadCheckResult result) { |
561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 563 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
562 DownloadItem* download = | 564 DownloadItem* download = |
563 download_manager_->GetActiveDownloadItem(download_id); | 565 download_manager_->GetActiveDownloadItem(download_id); |
564 if (!download) | 566 if (!download) |
565 return; | 567 return; |
566 | 568 |
567 VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false) | 569 VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false) |
568 << " verdict = " << result; | 570 << " verdict = " << result; |
569 content::DownloadDangerType danger_type = download->GetDangerType(); | 571 content::DownloadDangerType danger_type = download->GetDangerType(); |
570 if (result != DownloadProtectionService::SAFE) | 572 if (result != DownloadProtectionService::SAFE) |
571 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; | 573 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; |
572 | 574 |
573 download_history_->CheckVisitedReferrerBefore( | 575 download_history_->CheckVisitedReferrerBefore( |
574 download_id, download->GetReferrerUrl(), | 576 download_id, download->GetReferrerUrl(), |
575 base::Bind(&ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone, | 577 base::Bind(&ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone, |
576 base::Unretained(this), download_id, danger_type)); | 578 base::Unretained(this), download_id, callback, danger_type)); |
577 } | 579 } |
578 | 580 |
579 void ChromeDownloadManagerDelegate::CheckClientDownloadDone( | 581 void ChromeDownloadManagerDelegate::CheckClientDownloadDone( |
580 int32 download_id, | 582 int32 download_id, |
581 DownloadProtectionService::DownloadCheckResult result) { | 583 DownloadProtectionService::DownloadCheckResult result) { |
582 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); | 584 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); |
583 if (!item) | 585 if (!item) |
584 return; | 586 return; |
585 | 587 |
586 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false) | 588 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 int download_id = crx_installers_[installer]; | 626 int download_id = crx_installers_[installer]; |
625 crx_installers_.erase(installer.get()); | 627 crx_installers_.erase(installer.get()); |
626 | 628 |
627 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); | 629 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); |
628 if (item) | 630 if (item) |
629 item->DelayedDownloadOpened(installer->did_handle_successfully()); | 631 item->DelayedDownloadOpened(installer->did_handle_successfully()); |
630 } | 632 } |
631 | 633 |
632 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone( | 634 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone( |
633 int32 download_id, | 635 int32 download_id, |
| 636 const content::DownloadTargetCallback& callback, |
634 content::DownloadDangerType danger_type, | 637 content::DownloadDangerType danger_type, |
635 bool visited_referrer_before) { | 638 bool visited_referrer_before) { |
636 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 639 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
637 | 640 |
638 DownloadItem* download = | 641 DownloadItem* download = |
639 download_manager_->GetActiveDownloadItem(download_id); | 642 download_manager_->GetActiveDownloadItem(download_id); |
640 if (!download) | 643 if (!download) |
641 return; | 644 return; |
642 | 645 |
643 bool should_prompt = (download->GetTargetDisposition() == | 646 bool should_prompt = (download->GetTargetDisposition() == |
(...skipping 21 matching lines...) Expand all Loading... |
665 !ShouldOpenFileBasedOnExtension(generated_name)) | 668 !ShouldOpenFileBasedOnExtension(generated_name)) |
666 should_prompt = true; | 669 should_prompt = true; |
667 } | 670 } |
668 if (download_prefs_->IsDownloadPathManaged()) | 671 if (download_prefs_->IsDownloadPathManaged()) |
669 should_prompt = false; | 672 should_prompt = false; |
670 | 673 |
671 // Determine the proper path for a download, by either one of the following: | 674 // Determine the proper path for a download, by either one of the following: |
672 // 1) using the default download directory. | 675 // 1) using the default download directory. |
673 // 2) prompting the user. | 676 // 2) prompting the user. |
674 FilePath target_directory; | 677 FilePath target_directory; |
675 if (should_prompt && !download_manager_->LastDownloadPath().empty()) | 678 if (should_prompt && !last_download_path_.empty()) |
676 target_directory = download_manager_->LastDownloadPath(); | 679 target_directory = last_download_path_; |
677 else | 680 else |
678 target_directory = download_prefs_->DownloadPath(); | 681 target_directory = download_prefs_->DownloadPath(); |
679 suggested_path = target_directory.Append(generated_name); | 682 suggested_path = target_directory.Append(generated_name); |
680 } else { | 683 } else { |
681 DCHECK(!should_prompt); | 684 DCHECK(!should_prompt); |
682 suggested_path = download->GetForcedFilePath(); | 685 suggested_path = download->GetForcedFilePath(); |
683 } | 686 } |
684 | 687 |
685 // If the download hasn't already been marked dangerous (could be | 688 // If the download hasn't already been marked dangerous (could be |
686 // DANGEROUS_URL), check if it is a dangerous file. | 689 // DANGEROUS_URL), check if it is a dangerous file. |
(...skipping 22 matching lines...) Expand all Loading... |
709 } else { | 712 } else { |
710 // Currently we only expect this case. | 713 // Currently we only expect this case. |
711 DCHECK_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, danger_type); | 714 DCHECK_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, danger_type); |
712 } | 715 } |
713 | 716 |
714 #if defined (OS_CHROMEOS) | 717 #if defined (OS_CHROMEOS) |
715 gdata::GDataDownloadObserver::SubstituteGDataDownloadPath( | 718 gdata::GDataDownloadObserver::SubstituteGDataDownloadPath( |
716 profile_, suggested_path, download, | 719 profile_, suggested_path, download, |
717 base::Bind( | 720 base::Bind( |
718 &ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback, | 721 &ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback, |
719 this, download->GetId(), should_prompt, is_forced_path, danger_type)); | 722 this, download->GetId(), callback, should_prompt, is_forced_path, |
| 723 danger_type)); |
720 #else | 724 #else |
721 GetReservedPath( | 725 GetReservedPath( |
722 *download, suggested_path, download_prefs_->DownloadPath(), | 726 *download, suggested_path, download_prefs_->DownloadPath(), |
723 !is_forced_path, | 727 !is_forced_path, |
724 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, | 728 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, |
725 this, download->GetId(), should_prompt, danger_type)); | 729 this, download->GetId(), callback, should_prompt, |
| 730 danger_type)); |
726 #endif | 731 #endif |
727 } | 732 } |
728 | 733 |
729 #if defined (OS_CHROMEOS) | 734 #if defined (OS_CHROMEOS) |
| 735 // TODO(asanka): Merge this logic with the logic in DownloadFilePickerChromeOS. |
730 void ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback( | 736 void ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback( |
731 int32 download_id, | 737 int32 download_id, |
| 738 const content::DownloadTargetCallback& callback, |
732 bool should_prompt, | 739 bool should_prompt, |
733 bool is_forced_path, | 740 bool is_forced_path, |
734 content::DownloadDangerType danger_type, | 741 content::DownloadDangerType danger_type, |
735 const FilePath& suggested_path) { | 742 const FilePath& suggested_path) { |
736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 743 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
737 DownloadItem* download = | 744 DownloadItem* download = |
738 download_manager_->GetActiveDownloadItem(download_id); | 745 download_manager_->GetActiveDownloadItem(download_id); |
739 if (!download) | 746 if (!download) |
740 return; | 747 return; |
741 | 748 |
742 GetReservedPath( | 749 GetReservedPath( |
743 *download, suggested_path, download_prefs_->DownloadPath(), | 750 *download, suggested_path, download_prefs_->DownloadPath(), |
744 !is_forced_path, | 751 !is_forced_path, |
745 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, | 752 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, |
746 this, download->GetId(), should_prompt, danger_type)); | 753 this, download->GetId(), callback, should_prompt, |
| 754 danger_type)); |
747 } | 755 } |
748 #endif | 756 #endif |
749 | 757 |
750 void ChromeDownloadManagerDelegate::OnPathReservationAvailable( | 758 void ChromeDownloadManagerDelegate::OnPathReservationAvailable( |
751 int32 download_id, | 759 int32 download_id, |
| 760 const content::DownloadTargetCallback& callback, |
752 bool should_prompt, | 761 bool should_prompt, |
753 content::DownloadDangerType danger_type, | 762 content::DownloadDangerType danger_type, |
754 const FilePath& target_path, | 763 const FilePath& reserved_path, |
755 bool target_path_verified) { | 764 bool reserved_path_verified) { |
756 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 765 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
757 DownloadItem* download = | 766 DownloadItem* download = |
758 download_manager_->GetActiveDownloadItem(download_id); | 767 download_manager_->GetActiveDownloadItem(download_id); |
759 if (!download) | 768 if (!download) |
760 return; | 769 return; |
761 DownloadItem::TargetDisposition disposition; | 770 if (should_prompt || !reserved_path_verified) { |
762 // If the target path could not be verified then the path was non-existant, | 771 // If the target path could not be verified then the path was non-existant, |
763 // non writeable or could not be uniquified. Prompt the user. | 772 // non writeable or could not be uniquified. Prompt the user. |
764 if (should_prompt || !target_path_verified) | 773 ChooseDownloadPath( |
765 disposition = DownloadItem::TARGET_DISPOSITION_PROMPT; | 774 download, reserved_path, |
766 else | 775 base::Bind(&ChromeDownloadManagerDelegate::OnTargetPathDetermined, |
767 disposition = DownloadItem::TARGET_DISPOSITION_OVERWRITE; | 776 this, download_id, callback, |
768 download->OnTargetPathDetermined(target_path, disposition, danger_type); | 777 DownloadItem::TARGET_DISPOSITION_PROMPT, danger_type)); |
769 download_manager_->RestartDownload(download_id); | 778 } else { |
| 779 OnTargetPathDetermined(download_id, callback, |
| 780 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 781 danger_type, reserved_path); |
| 782 } |
| 783 } |
| 784 |
| 785 void ChromeDownloadManagerDelegate::OnTargetPathDetermined( |
| 786 int32 download_id, |
| 787 const content::DownloadTargetCallback& callback, |
| 788 DownloadItem::TargetDisposition disposition, |
| 789 content::DownloadDangerType danger_type, |
| 790 const FilePath& target_path) { |
| 791 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 792 FilePath intermediate_path; |
| 793 DownloadItem* download = |
| 794 download_manager_->GetActiveDownloadItem(download_id); |
| 795 if (!download) |
| 796 return; |
| 797 |
| 798 // If |target_path| is empty, then that means that the user wants to cancel |
| 799 // the download. |
| 800 if (!target_path.empty()) { |
| 801 intermediate_path = GetIntermediatePath(target_path, danger_type); |
| 802 |
| 803 // Retain the last directory. Exclude temporary downloads since the path |
| 804 // likely points at the location of a temporary file. |
| 805 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a |
| 806 // directory to persist. Or perhaps, if the GData path |
| 807 // substitution logic is moved here, then we would have a |
| 808 // persistable path after the DownloadFilePicker is done. |
| 809 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT && |
| 810 !download->IsTemporary()) |
| 811 last_download_path_ = target_path.DirName(); |
| 812 } |
| 813 callback.Run(target_path, disposition, danger_type, intermediate_path); |
770 } | 814 } |
771 | 815 |
772 void ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore( | 816 void ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore( |
773 int32 download_id, int64 db_handle) { | 817 int32 download_id, int64 db_handle) { |
774 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 818 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
775 // call this function with an invalid |db_handle|. For instance, this can | 819 // call this function with an invalid |db_handle|. For instance, this can |
776 // happen when the history database is offline. We cannot have multiple | 820 // happen when the history database is offline. We cannot have multiple |
777 // DownloadItems with the same invalid db_handle, so we need to assign a | 821 // DownloadItems with the same invalid db_handle, so we need to assign a |
778 // unique |db_handle| here. | 822 // unique |db_handle| here. |
779 if (db_handle == DownloadItem::kUninitializedHandle) | 823 if (db_handle == DownloadItem::kUninitializedHandle) |
780 db_handle = download_history_->GetNextFakeDbHandle(); | 824 db_handle = download_history_->GetNextFakeDbHandle(); |
781 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); | 825 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); |
782 } | 826 } |
OLD | NEW |