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

Side by Side Diff: chrome/browser/download/chrome_download_manager_delegate.cc

Issue 10915180: Make DownloadHistory observe manager, items (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: @r166419 Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "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"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/file_util.h" 12 #include "base/file_util.h"
13 #include "base/rand_util.h" 13 #include "base/rand_util.h"
14 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
15 #include "base/time.h" 15 #include "base/time.h"
16 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
17 #include "chrome/browser/api/prefs/pref_member.h" 17 #include "chrome/browser/api/prefs/pref_member.h"
18 #include "chrome/browser/browser_process.h" 18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/download/download_completion_blocker.h" 19 #include "chrome/browser/download/download_completion_blocker.h"
20 #include "chrome/browser/download/download_crx_util.h" 20 #include "chrome/browser/download/download_crx_util.h"
21 #include "chrome/browser/download/download_extensions.h" 21 #include "chrome/browser/download/download_extensions.h"
22 #include "chrome/browser/download/download_file_picker.h" 22 #include "chrome/browser/download/download_file_picker.h"
23 #include "chrome/browser/download/download_history.h" 23 #include "chrome/browser/download/download_history.h"
24 #include "chrome/browser/download/download_path_reservation_tracker.h" 24 #include "chrome/browser/download/download_path_reservation_tracker.h"
25 #include "chrome/browser/download/download_prefs.h" 25 #include "chrome/browser/download/download_prefs.h"
26 #include "chrome/browser/download/download_service.h"
27 #include "chrome/browser/download/download_service_factory.h"
26 #include "chrome/browser/download/download_status_updater.h" 28 #include "chrome/browser/download/download_status_updater.h"
27 #include "chrome/browser/download/download_util.h" 29 #include "chrome/browser/download/download_util.h"
28 #include "chrome/browser/download/save_package_file_picker.h" 30 #include "chrome/browser/download/save_package_file_picker.h"
29 #include "chrome/browser/extensions/api/downloads/downloads_api.h" 31 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
30 #include "chrome/browser/extensions/crx_installer.h" 32 #include "chrome/browser/extensions/crx_installer.h"
31 #include "chrome/browser/extensions/extension_service.h" 33 #include "chrome/browser/extensions/extension_service.h"
34 #include "chrome/browser/history/history.h"
35 #include "chrome/browser/history/history_service_factory.h"
32 #include "chrome/browser/intents/web_intents_util.h" 36 #include "chrome/browser/intents/web_intents_util.h"
33 #include "chrome/browser/prefs/pref_service.h" 37 #include "chrome/browser/prefs/pref_service.h"
34 #include "chrome/browser/profiles/profile.h" 38 #include "chrome/browser/profiles/profile.h"
35 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 39 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
36 #include "chrome/browser/ui/browser_tabstrip.h" 40 #include "chrome/browser/ui/browser_tabstrip.h"
37 #include "chrome/common/chrome_notification_types.h" 41 #include "chrome/common/chrome_notification_types.h"
38 #include "chrome/common/extensions/feature_switch.h" 42 #include "chrome/common/extensions/feature_switch.h"
39 #include "chrome/common/extensions/user_script.h" 43 #include "chrome/common/extensions/user_script.h"
40 #include "chrome/common/pref_names.h" 44 #include "chrome/common/pref_names.h"
41 #include "content/public/browser/download_item.h" 45 #include "content/public/browser/download_item.h"
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 : profile_(profile), 150 : profile_(profile),
147 next_download_id_(0), 151 next_download_id_(0),
148 download_prefs_(new DownloadPrefs(profile)) { 152 download_prefs_(new DownloadPrefs(profile)) {
149 } 153 }
150 154
151 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { 155 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {
152 } 156 }
153 157
154 void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) { 158 void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) {
155 download_manager_ = dm; 159 download_manager_ = dm;
156 download_history_.reset(new DownloadHistory(profile_));
157 if (!profile_->IsOffTheRecord()) {
158 // DownloadManager should not be RefCountedThreadSafe.
159 // ChromeDownloadManagerDelegate outlives DownloadManager, and
160 // DownloadHistory uses a scoped canceller to cancel tasks when it is
161 // deleted. Almost all callbacks to DownloadManager should use weak pointers
162 // or bounce off a container object that uses ManagerGoingDown() to simulate
163 // a weak pointer.
164 download_history_->Load(
165 base::Bind(&DownloadManager::OnPersistentStoreQueryComplete,
166 download_manager_));
167 }
168 #if !defined(OS_ANDROID) 160 #if !defined(OS_ANDROID)
169 extension_event_router_.reset(new ExtensionDownloadsEventRouter( 161 extension_event_router_.reset(new ExtensionDownloadsEventRouter(
170 profile_, download_manager_)); 162 profile_, download_manager_));
171 #endif 163 #endif
172 } 164 }
173 165
174 void ChromeDownloadManagerDelegate::Shutdown() { 166 void ChromeDownloadManagerDelegate::Shutdown() {
175 download_history_.reset();
176 download_prefs_.reset(); 167 download_prefs_.reset();
177 #if !defined(OS_ANDROID) 168 #if !defined(OS_ANDROID)
178 extension_event_router_.reset(); 169 extension_event_router_.reset();
179 #endif 170 #endif
180 } 171 }
181 172
182 DownloadId ChromeDownloadManagerDelegate::GetNextId() { 173 DownloadId ChromeDownloadManagerDelegate::GetNextId() {
183 if (!profile_->IsOffTheRecord()) 174 if (!profile_->IsOffTheRecord())
184 return DownloadId(this, next_download_id_++); 175 return DownloadId(this, next_download_id_++);
185 176
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 476
486 bool ChromeDownloadManagerDelegate::GenerateFileHash() { 477 bool ChromeDownloadManagerDelegate::GenerateFileHash() {
487 #if defined(ENABLE_SAFE_BROWSING) 478 #if defined(ENABLE_SAFE_BROWSING)
488 return profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled) && 479 return profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled) &&
489 g_browser_process->safe_browsing_service()->DownloadBinHashNeeded(); 480 g_browser_process->safe_browsing_service()->DownloadBinHashNeeded();
490 #else 481 #else
491 return false; 482 return false;
492 #endif 483 #endif
493 } 484 }
494 485
495 void ChromeDownloadManagerDelegate::AddItemToPersistentStore(
496 DownloadItem* item) {
497 if (profile_->IsOffTheRecord()) {
498 OnItemAddedToPersistentStore(
499 item->GetId(), download_history_->GetNextFakeDbHandle());
500 return;
501 }
502 download_history_->AddEntry(item,
503 base::Bind(&ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore,
504 this));
505 }
506
507 void ChromeDownloadManagerDelegate::UpdateItemInPersistentStore(
508 DownloadItem* item) {
509 download_history_->UpdateEntry(item);
510 }
511
512 void ChromeDownloadManagerDelegate::UpdatePathForItemInPersistentStore(
513 DownloadItem* item,
514 const FilePath& new_path) {
515 download_history_->UpdateDownloadPath(item, new_path);
516 }
517
518 void ChromeDownloadManagerDelegate::RemoveItemFromPersistentStore(
519 DownloadItem* item) {
520 download_history_->RemoveEntry(item);
521 }
522
523 void ChromeDownloadManagerDelegate::RemoveItemsFromPersistentStoreBetween(
524 base::Time remove_begin,
525 base::Time remove_end) {
526 if (profile_->IsOffTheRecord())
527 return;
528 download_history_->RemoveEntriesBetween(remove_begin, remove_end);
529 }
530
531 void ChromeDownloadManagerDelegate::GetSaveDir(BrowserContext* browser_context, 486 void ChromeDownloadManagerDelegate::GetSaveDir(BrowserContext* browser_context,
532 FilePath* website_save_dir, 487 FilePath* website_save_dir,
533 FilePath* download_save_dir, 488 FilePath* download_save_dir,
534 bool* skip_dir_check) { 489 bool* skip_dir_check) {
535 Profile* profile = Profile::FromBrowserContext(browser_context); 490 Profile* profile = Profile::FromBrowserContext(browser_context);
536 PrefService* prefs = profile->GetPrefs(); 491 PrefService* prefs = profile->GetPrefs();
537 492
538 // Check whether the preference has the preferred directory for saving file. 493 // Check whether the preference has the preferred directory for saving file.
539 // If not, initialize it with default directory. 494 // If not, initialize it with default directory.
540 if (!prefs->FindPreference(prefs::kSaveFileDefaultDirectory)) { 495 if (!prefs->FindPreference(prefs::kSaveFileDefaultDirectory)) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 DownloadItem& download, 583 DownloadItem& download,
629 const FilePath& target_path, 584 const FilePath& target_path,
630 const FilePath& default_download_path, 585 const FilePath& default_download_path,
631 bool should_uniquify_path, 586 bool should_uniquify_path,
632 const DownloadPathReservationTracker::ReservedPathCallback& callback) { 587 const DownloadPathReservationTracker::ReservedPathCallback& callback) {
633 DownloadPathReservationTracker::GetReservedPath( 588 DownloadPathReservationTracker::GetReservedPath(
634 download, target_path, default_download_path, should_uniquify_path, 589 download, target_path, default_download_path, should_uniquify_path,
635 callback); 590 callback);
636 } 591 }
637 592
593 ChromeDownloadManagerDelegate::VisitedReferrerBeforeDoneParameters::
594 VisitedReferrerBeforeDoneParameters() {}
595 ChromeDownloadManagerDelegate::VisitedReferrerBeforeDoneParameters::
596 ~VisitedReferrerBeforeDoneParameters() {}
597
638 void ChromeDownloadManagerDelegate::CheckDownloadUrlDone( 598 void ChromeDownloadManagerDelegate::CheckDownloadUrlDone(
639 int32 download_id, 599 int32 download_id,
640 const content::DownloadTargetCallback& callback, 600 const content::DownloadTargetCallback& callback,
641 DownloadProtectionService::DownloadCheckResult result) { 601 DownloadProtectionService::DownloadCheckResult result) {
642 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 602 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
643 DownloadItem* download = download_manager_->GetDownload(download_id); 603 DownloadItem* download = download_manager_->GetDownload(download_id);
644 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS)) 604 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
645 return; 605 return;
646 606
647 VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false) 607 VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false)
648 << " verdict = " << result; 608 << " verdict = " << result;
649 content::DownloadDangerType danger_type = download->GetDangerType(); 609 content::DownloadDangerType danger_type = download->GetDangerType();
650 if (result != DownloadProtectionService::SAFE) 610 if (result != DownloadProtectionService::SAFE)
651 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; 611 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL;
652 612
653 download_history_->CheckVisitedReferrerBefore( 613 VisitedReferrerBeforeDoneParameters params;
654 download_id, download->GetReferrerUrl(), 614 params.download_id = download_id;
615 params.callback = callback;
616 params.danger_type = danger_type;
617
618 HistoryService* history = HistoryServiceFactory::GetForProfile(
619 profile_->GetOriginalProfile(), Profile::EXPLICIT_ACCESS);
Randy Smith (Not in Mondays) 2012/11/07 21:10:29 As I read the code, you don't need the GetOriginal
benjhayden 2012/11/08 18:57:03 Done.
620 if (!history || !download->GetReferrerUrl().is_valid()) {
621 // If the original profile doesn't have a HistoryService or the referrer url
622 // is invalid, then give up and assume the referrer has not been visited
623 // before. There's no history for on-record profiles in unit_tests, for
624 // example.
625 CheckVisitedReferrerBeforeDone(params, 0, false, 0, base::Time::Now());
626 return;
627 }
628 history->GetVisibleVisitCountToHost(
629 download->GetReferrerUrl(), &history_consumer_,
655 base::Bind(&ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone, 630 base::Bind(&ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone,
656 this, download_id, callback, danger_type)); 631 this, params));
657 } 632 }
658 633
659 void ChromeDownloadManagerDelegate::CheckClientDownloadDone( 634 void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
660 int32 download_id, 635 int32 download_id,
661 DownloadProtectionService::DownloadCheckResult result) { 636 DownloadProtectionService::DownloadCheckResult result) {
662 DownloadItem* item = download_manager_->GetDownload(download_id); 637 DownloadItem* item = download_manager_->GetDownload(download_id);
663 if (!item || (item->GetState() != DownloadItem::IN_PROGRESS)) 638 if (!item || (item->GetState() != DownloadItem::IN_PROGRESS))
664 return; 639 return;
665 640
666 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false) 641 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 content::Source<extensions::CrxInstaller>(source).ptr(); 678 content::Source<extensions::CrxInstaller>(source).ptr();
704 int download_id = crx_installers_[installer]; 679 int download_id = crx_installers_[installer];
705 crx_installers_.erase(installer.get()); 680 crx_installers_.erase(installer.get());
706 681
707 DownloadItem* item = download_manager_->GetDownload(download_id); 682 DownloadItem* item = download_manager_->GetDownload(download_id);
708 if (item) 683 if (item)
709 item->DelayedDownloadOpened(installer->did_handle_successfully()); 684 item->DelayedDownloadOpened(installer->did_handle_successfully());
710 } 685 }
711 686
712 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone( 687 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone(
713 int32 download_id, 688 const VisitedReferrerBeforeDoneParameters& params,
714 const content::DownloadTargetCallback& callback, 689 HistoryService::Handle unused_handle,
715 content::DownloadDangerType danger_type, 690 bool found_visits,
716 bool visited_referrer_before) { 691 int count,
692 base::Time first_visit) {
717 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 693 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
718 694
695 bool visited_referrer_before = (found_visits && count &&
696 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight()));
697
719 DownloadItem* download = 698 DownloadItem* download =
720 download_manager_->GetDownload(download_id); 699 download_manager_->GetDownload(params.download_id);
721 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS)) 700 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
722 return; 701 return;
723 702
724 bool should_prompt = (download->GetTargetDisposition() == 703 bool should_prompt = (download->GetTargetDisposition() ==
725 DownloadItem::TARGET_DISPOSITION_PROMPT); 704 DownloadItem::TARGET_DISPOSITION_PROMPT);
726 bool is_forced_path = !download->GetForcedFilePath().empty(); 705 bool is_forced_path = !download->GetForcedFilePath().empty();
727 FilePath suggested_path; 706 FilePath suggested_path;
728 707
729 // Check whether this download is for an extension install or not. 708 // Check whether this download is for an extension install or not.
730 // Allow extensions to be explicitly saved. 709 // Allow extensions to be explicitly saved.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } 746 }
768 747
769 // If we will open the file with a web intents dispatch, 748 // If we will open the file with a web intents dispatch,
770 // give it a name that will not allow the OS to open it using usual 749 // give it a name that will not allow the OS to open it using usual
771 // associated apps. 750 // associated apps.
772 if (ShouldOpenWithWebIntents(download)) { 751 if (ShouldOpenWithWebIntents(download)) {
773 download->SetDisplayName(suggested_path.BaseName()); 752 download->SetDisplayName(suggested_path.BaseName());
774 suggested_path = suggested_path.AddExtension(kWebIntentsFileExtension); 753 suggested_path = suggested_path.AddExtension(kWebIntentsFileExtension);
775 } 754 }
776 755
756 content::DownloadDangerType danger_type = params.danger_type;
757
777 // If the download hasn't already been marked dangerous (could be 758 // If the download hasn't already been marked dangerous (could be
778 // DANGEROUS_URL), check if it is a dangerous file. 759 // DANGEROUS_URL), check if it is a dangerous file.
779 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { 760 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
780 if (!should_prompt && !is_forced_path && 761 if (!should_prompt && !is_forced_path &&
781 IsDangerousFile(*download, suggested_path, visited_referrer_before)) { 762 IsDangerousFile(*download, suggested_path, visited_referrer_before)) {
782 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; 763 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
783 } 764 }
784 765
785 #if defined(ENABLE_SAFE_BROWSING) 766 #if defined(ENABLE_SAFE_BROWSING)
786 DownloadProtectionService* service = GetDownloadProtectionService(); 767 DownloadProtectionService* service = GetDownloadProtectionService();
(...skipping 14 matching lines...) Expand all
801 } else { 782 } else {
802 // Currently we only expect this case. 783 // Currently we only expect this case.
803 DCHECK_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, danger_type); 784 DCHECK_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, danger_type);
804 } 785 }
805 786
806 #if defined (OS_CHROMEOS) 787 #if defined (OS_CHROMEOS)
807 drive::DriveDownloadObserver::SubstituteDriveDownloadPath( 788 drive::DriveDownloadObserver::SubstituteDriveDownloadPath(
808 profile_, suggested_path, download, 789 profile_, suggested_path, download,
809 base::Bind( 790 base::Bind(
810 &ChromeDownloadManagerDelegate::SubstituteDriveDownloadPathCallback, 791 &ChromeDownloadManagerDelegate::SubstituteDriveDownloadPathCallback,
811 this, download->GetId(), callback, should_prompt, is_forced_path, 792 this, download->GetId(), params.callback, should_prompt,
812 danger_type)); 793 is_forced_path, danger_type));
813 #else 794 #else
814 GetReservedPath( 795 GetReservedPath(
815 *download, suggested_path, download_prefs_->DownloadPath(), 796 *download, suggested_path, download_prefs_->DownloadPath(),
816 !is_forced_path, 797 !is_forced_path,
817 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, 798 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable,
818 this, download->GetId(), callback, should_prompt, 799 this, download->GetId(), params.callback, should_prompt,
819 danger_type)); 800 danger_type));
820 #endif 801 #endif
821 } 802 }
822 803
823 #if defined (OS_CHROMEOS) 804 #if defined (OS_CHROMEOS)
824 // TODO(asanka): Merge this logic with the logic in DownloadFilePickerChromeOS. 805 // TODO(asanka): Merge this logic with the logic in DownloadFilePickerChromeOS.
825 void ChromeDownloadManagerDelegate::SubstituteDriveDownloadPathCallback( 806 void ChromeDownloadManagerDelegate::SubstituteDriveDownloadPathCallback(
826 int32 download_id, 807 int32 download_id,
827 const content::DownloadTargetCallback& callback, 808 const content::DownloadTargetCallback& callback,
828 bool should_prompt, 809 bool should_prompt,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a 875 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a
895 // directory to persist. Or perhaps, if the Drive path 876 // directory to persist. Or perhaps, if the Drive path
896 // substitution logic is moved here, then we would have a 877 // substitution logic is moved here, then we would have a
897 // persistable path after the DownloadFilePicker is done. 878 // persistable path after the DownloadFilePicker is done.
898 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT && 879 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT &&
899 !download->IsTemporary()) 880 !download->IsTemporary())
900 last_download_path_ = target_path.DirName(); 881 last_download_path_ = target_path.DirName();
901 } 882 }
902 callback.Run(target_path, disposition, danger_type, intermediate_path); 883 callback.Run(target_path, disposition, danger_type, intermediate_path);
903 } 884 }
904
905 void ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore(
906 int32 download_id, int64 db_handle) {
907 // It's not immediately obvious, but HistoryBackend::CreateDownload() can
908 // call this function with an invalid |db_handle|. For instance, this can
909 // happen when the history database is offline. We cannot have multiple
910 // DownloadItems with the same invalid db_handle, so we need to assign a
911 // unique |db_handle| here.
912 if (db_handle == DownloadItem::kUninitializedHandle)
913 db_handle = download_history_->GetNextFakeDbHandle();
914 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle);
915 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698