| Index: chrome/browser/download/chrome_download_manager_delegate.cc
|
| diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
|
| index e069eddcbe8445310dd4b054cd0f2370aa27cdcd..a25012e6ef891e6cb009b830de80482e1179183f 100644
|
| --- a/chrome/browser/download/chrome_download_manager_delegate.cc
|
| +++ b/chrome/browser/download/chrome_download_manager_delegate.cc
|
| @@ -69,13 +69,50 @@ namespace {
|
| static const char safe_browsing_id[] = "Safe Browsing ID";
|
|
|
| // The state of a safebrowsing check.
|
| -struct SafeBrowsingState : public DownloadItem::ExternalData {
|
| +class SafeBrowsingState : public DownloadItem::ExternalData {
|
| + public:
|
| + explicit SafeBrowsingState(const base::Closure& complete_callback)
|
| + : pending_(true),
|
| + verdict_(DownloadProtectionService::SAFE),
|
| + complete_callback_(complete_callback) {
|
| + }
|
| +
|
| + virtual ~SafeBrowsingState();
|
| +
|
| // If true the SafeBrowsing check is not done yet.
|
| - bool pending;
|
| + bool pending() const { return pending_; }
|
| +
|
| // The verdict that we got from calling CheckClientDownload.
|
| - safe_browsing::DownloadProtectionService::DownloadCheckResult verdict;
|
| + DownloadProtectionService::DownloadCheckResult verdict() const {
|
| + return verdict_;
|
| + }
|
| +
|
| + // |cb| will be run when CompleteDownload() is called.
|
| + void set_complete_callback(const base::Closure& cb) {
|
| + // Be very careful to avoid calling cb twice, or more than one cb!
|
| + if (pending())
|
| + complete_callback_ = cb;
|
| + }
|
| +
|
| + void CompleteDownload(DownloadProtectionService::DownloadCheckResult result) {
|
| + pending_ = false;
|
| + verdict_ = result;
|
| + if (!complete_callback_.is_null()) {
|
| + complete_callback_.Run();
|
| + complete_callback_.Reset();
|
| + }
|
| + }
|
| +
|
| + private:
|
| + bool pending_;
|
| + DownloadProtectionService::DownloadCheckResult verdict_;
|
| + base::Closure complete_callback_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingState);
|
| };
|
|
|
| +SafeBrowsingState::~SafeBrowsingState() {}
|
| +
|
| } // namespace
|
|
|
| ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
|
| @@ -154,11 +191,11 @@ void ChromeDownloadManagerDelegate::ChooseDownloadPath(
|
| int32 download_id) {
|
| // Deletes itself.
|
| #if defined(OS_CHROMEOS)
|
| - new DownloadFilePickerChromeOS(
|
| + new DownloadFilePickerChromeOS
|
| #else
|
| - new DownloadFilePicker(
|
| + new DownloadFilePicker
|
| #endif
|
| - download_manager_, web_contents, suggested_path, download_id);
|
| + (download_manager_, web_contents, suggested_path, download_id);
|
| }
|
|
|
| FilePath ChromeDownloadManagerDelegate::GetIntermediatePath(
|
| @@ -193,23 +230,32 @@ bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension(
|
| return download_prefs_->IsAutoOpenEnabledForExtension(extension);
|
| }
|
|
|
| -bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(DownloadItem* item) {
|
| +bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(
|
| + DownloadItem* item,
|
| + const base::Closure& complete_callback) {
|
| #if defined(ENABLE_SAFE_BROWSING)
|
| // See if there is already a pending SafeBrowsing check for that download.
|
| SafeBrowsingState* state = static_cast<SafeBrowsingState*>(
|
| item->GetExternalData(&safe_browsing_id));
|
| - if (state)
|
| + if (state) {
|
| // Don't complete the download until we have an answer.
|
| - return !state->pending;
|
| + if (!state->pending())
|
| + return true;
|
| +
|
| + // Allow calling ShouldCompleteDownload() first with a null callback, then
|
| + // with a non-null callback.
|
| + if (!complete_callback.is_null())
|
| + state->set_complete_callback(complete_callback);
|
| +
|
| + return false;
|
| + }
|
|
|
| // Begin the safe browsing download protection check.
|
| DownloadProtectionService* service = GetDownloadProtectionService();
|
| if (service) {
|
| VLOG(2) << __FUNCTION__ << "() Start SB download check for download = "
|
| << item->DebugString(false);
|
| - state = new SafeBrowsingState();
|
| - state->pending = true;
|
| - state->verdict = DownloadProtectionService::SAFE;
|
| + state = new SafeBrowsingState(complete_callback);
|
| item->SetExternalData(&safe_browsing_id, state);
|
| service->CheckClientDownload(
|
| DownloadProtectionService::DownloadInfo::FromDownloadItem(*item),
|
| @@ -223,7 +269,8 @@ bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(DownloadItem* item) {
|
| #if defined(OS_CHROMEOS)
|
| // If there's a GData upload associated with this download, we wait until that
|
| // is complete before allowing the download item to complete.
|
| - if (!gdata::GDataDownloadObserver::IsReadyToComplete(item))
|
| + if (!gdata::GDataDownloadObserver::IsReadyToComplete(
|
| + item, complete_callback))
|
| return false;
|
| #endif
|
| return true;
|
| @@ -447,12 +494,7 @@ void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
|
|
|
| SafeBrowsingState* state = static_cast<SafeBrowsingState*>(
|
| item->GetExternalData(&safe_browsing_id));
|
| - DCHECK(state);
|
| - if (state) {
|
| - state->pending = false;
|
| - state->verdict = result;
|
| - }
|
| - item->MaybeCompleteDownload();
|
| + state->CompleteDownload(result);
|
| }
|
|
|
| // content::NotificationObserver implementation.
|
|
|