Chromium Code Reviews| 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 using content::WebContents; | 62 using content::WebContents; |
| 63 using safe_browsing::DownloadProtectionService; | 63 using safe_browsing::DownloadProtectionService; |
| 64 | 64 |
| 65 namespace { | 65 namespace { |
| 66 | 66 |
| 67 // String pointer used for identifying safebrowing data associated with | 67 // String pointer used for identifying safebrowing data associated with |
| 68 // a download item. | 68 // a download item. |
| 69 static const char safe_browsing_id[] = "Safe Browsing ID"; | 69 static const char safe_browsing_id[] = "Safe Browsing ID"; |
| 70 | 70 |
| 71 // The state of a safebrowsing check. | 71 // The state of a safebrowsing check. |
| 72 struct SafeBrowsingState : public DownloadItem::ExternalData { | 72 class SafeBrowsingState : public DownloadItem::ExternalData { |
| 73 public: | |
| 74 explicit SafeBrowsingState(const base::Closure& complete_cb) | |
| 75 : pending_(true), | |
| 76 verdict_(DownloadProtectionService::SAFE), | |
| 77 complete_cb_(complete_cb) { | |
| 78 } | |
| 79 | |
| 80 virtual ~SafeBrowsingState(); | |
| 81 | |
| 73 // If true the SafeBrowsing check is not done yet. | 82 // If true the SafeBrowsing check is not done yet. |
| 74 bool pending; | 83 bool pending() const { return pending_; } |
| 84 | |
| 75 // The verdict that we got from calling CheckClientDownload. | 85 // The verdict that we got from calling CheckClientDownload. |
| 76 safe_browsing::DownloadProtectionService::DownloadCheckResult verdict; | 86 DownloadProtectionService::DownloadCheckResult verdict() const { |
| 87 return verdict_; | |
| 88 } | |
| 89 | |
| 90 // |cb| will be run when CompleteDownload() is called. | |
| 91 void set_complete_callback(const base::Closure& cb) { | |
| 92 // Be very careful to avoid calling cb twice, or more than one cb! | |
| 93 if (pending()) | |
| 94 complete_cb_ = cb; | |
| 95 } | |
| 96 | |
| 97 void CompleteDownload(DownloadProtectionService::DownloadCheckResult result) { | |
| 98 pending_ = false; | |
| 99 verdict_ = result; | |
| 100 if (!complete_cb_.is_null()) { | |
| 101 complete_cb_.Run(); | |
| 102 complete_cb_.Reset(); | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 private: | |
| 107 bool pending_; | |
| 108 DownloadProtectionService::DownloadCheckResult verdict_; | |
| 109 base::Closure complete_cb_; | |
| 110 | |
| 111 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingState); | |
| 77 }; | 112 }; |
| 78 | 113 |
| 114 SafeBrowsingState::~SafeBrowsingState() {} | |
| 115 | |
| 79 } // namespace | 116 } // namespace |
| 80 | 117 |
| 81 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile) | 118 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile) |
| 82 : profile_(profile), | 119 : profile_(profile), |
| 83 next_download_id_(0), | 120 next_download_id_(0), |
| 84 download_prefs_(new DownloadPrefs(profile->GetPrefs())) { | 121 download_prefs_(new DownloadPrefs(profile->GetPrefs())) { |
| 85 } | 122 } |
| 86 | 123 |
| 87 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { | 124 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { |
| 88 } | 125 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 147 CheckDownloadUrlDone(download_id, DownloadProtectionService::SAFE); | 184 CheckDownloadUrlDone(download_id, DownloadProtectionService::SAFE); |
| 148 return false; | 185 return false; |
| 149 } | 186 } |
| 150 | 187 |
| 151 void ChromeDownloadManagerDelegate::ChooseDownloadPath( | 188 void ChromeDownloadManagerDelegate::ChooseDownloadPath( |
| 152 WebContents* web_contents, | 189 WebContents* web_contents, |
| 153 const FilePath& suggested_path, | 190 const FilePath& suggested_path, |
| 154 int32 download_id) { | 191 int32 download_id) { |
| 155 // Deletes itself. | 192 // Deletes itself. |
| 156 #if defined(OS_CHROMEOS) | 193 #if defined(OS_CHROMEOS) |
| 157 new DownloadFilePickerChromeOS( | 194 new DownloadFilePickerChromeOS |
| 158 #else | 195 #else |
| 159 new DownloadFilePicker( | 196 new DownloadFilePicker |
| 160 #endif | 197 #endif |
| 161 download_manager_, web_contents, suggested_path, download_id); | 198 (download_manager_, web_contents, suggested_path, download_id); |
| 162 } | 199 } |
| 163 | 200 |
| 164 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( | 201 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( |
| 165 const FilePath& suggested_path) { | 202 const FilePath& suggested_path) { |
| 166 return download_util::GetCrDownloadPath(suggested_path); | 203 return download_util::GetCrDownloadPath(suggested_path); |
| 167 } | 204 } |
| 168 | 205 |
| 169 WebContents* ChromeDownloadManagerDelegate:: | 206 WebContents* ChromeDownloadManagerDelegate:: |
| 170 GetAlternativeWebContentsToNotifyForDownload() { | 207 GetAlternativeWebContentsToNotifyForDownload() { |
| 171 #if defined(OS_ANDROID) | 208 #if defined(OS_ANDROID) |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 186 FilePath::StringType extension = path.Extension(); | 223 FilePath::StringType extension = path.Extension(); |
| 187 if (extension.empty()) | 224 if (extension.empty()) |
| 188 return false; | 225 return false; |
| 189 if (Extension::IsExtension(path)) | 226 if (Extension::IsExtension(path)) |
| 190 return false; | 227 return false; |
| 191 DCHECK(extension[0] == FilePath::kExtensionSeparator); | 228 DCHECK(extension[0] == FilePath::kExtensionSeparator); |
| 192 extension.erase(0, 1); | 229 extension.erase(0, 1); |
| 193 return download_prefs_->IsAutoOpenEnabledForExtension(extension); | 230 return download_prefs_->IsAutoOpenEnabledForExtension(extension); |
| 194 } | 231 } |
| 195 | 232 |
| 196 bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(DownloadItem* item) { | 233 bool ChromeDownloadManagerDelegate::ShouldCompleteDownload( |
| 234 DownloadItem* item, | |
| 235 const base::Closure& complete_cb) { | |
| 197 #if defined(ENABLE_SAFE_BROWSING) | 236 #if defined(ENABLE_SAFE_BROWSING) |
| 198 // See if there is already a pending SafeBrowsing check for that download. | 237 // See if there is already a pending SafeBrowsing check for that download. |
| 199 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | 238 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
| 200 item->GetExternalData(&safe_browsing_id)); | 239 item->GetExternalData(&safe_browsing_id)); |
| 201 if (state) | 240 if (state) { |
| 241 // Allow calling ShouldCompleteDownload() first with a null callback, then | |
| 242 // with a non-null callback. | |
| 243 if (!complete_cb.is_null()) | |
|
Randy Smith (Not in Mondays)
2012/05/01 18:21:49
Same comment as for gdata; why not pass along a nu
benjhayden
2012/05/01 19:00:30
"You can't unset it once you set it" was supposed
| |
| 244 state->set_complete_callback(complete_cb); | |
| 245 | |
| 202 // Don't complete the download until we have an answer. | 246 // Don't complete the download until we have an answer. |
| 203 return !state->pending; | 247 return !state->pending(); |
|
Randy Smith (Not in Mondays)
2012/05/01 18:21:49
nit, suggestion: Naively, I'd expect this code not
benjhayden
2012/05/01 19:00:30
Done.
| |
| 248 } | |
| 204 | 249 |
| 205 // Begin the safe browsing download protection check. | 250 // Begin the safe browsing download protection check. |
| 206 DownloadProtectionService* service = GetDownloadProtectionService(); | 251 DownloadProtectionService* service = GetDownloadProtectionService(); |
| 207 if (service) { | 252 if (service) { |
| 208 VLOG(2) << __FUNCTION__ << "() Start SB download check for download = " | 253 VLOG(2) << __FUNCTION__ << "() Start SB download check for download = " |
| 209 << item->DebugString(false); | 254 << item->DebugString(false); |
| 210 state = new SafeBrowsingState(); | 255 state = new SafeBrowsingState(complete_cb); |
| 211 state->pending = true; | |
| 212 state->verdict = DownloadProtectionService::SAFE; | |
| 213 item->SetExternalData(&safe_browsing_id, state); | 256 item->SetExternalData(&safe_browsing_id, state); |
| 214 service->CheckClientDownload( | 257 service->CheckClientDownload( |
| 215 DownloadProtectionService::DownloadInfo::FromDownloadItem(*item), | 258 DownloadProtectionService::DownloadInfo::FromDownloadItem(*item), |
| 216 base::Bind( | 259 base::Bind( |
| 217 &ChromeDownloadManagerDelegate::CheckClientDownloadDone, | 260 &ChromeDownloadManagerDelegate::CheckClientDownloadDone, |
| 218 this, | 261 this, |
| 219 item->GetId())); | 262 item->GetId())); |
| 220 return false; | 263 return false; |
| 221 } | 264 } |
| 222 #endif | 265 #endif |
| 223 #if defined(OS_CHROMEOS) | 266 #if defined(OS_CHROMEOS) |
| 224 // If there's a GData upload associated with this download, we wait until that | 267 // If there's a GData upload associated with this download, we wait until that |
| 225 // is complete before allowing the download item to complete. | 268 // is complete before allowing the download item to complete. |
| 226 if (!gdata::GDataDownloadObserver::IsReadyToComplete(item)) | 269 if (!gdata::GDataDownloadObserver::IsReadyToComplete( |
| 270 item, complete_cb)) | |
| 227 return false; | 271 return false; |
| 228 #endif | 272 #endif |
| 229 return true; | 273 return true; |
| 230 } | 274 } |
| 231 | 275 |
| 232 bool ChromeDownloadManagerDelegate::ShouldOpenDownload(DownloadItem* item) { | 276 bool ChromeDownloadManagerDelegate::ShouldOpenDownload(DownloadItem* item) { |
| 233 if (IsExtensionDownload(item)) { | 277 if (IsExtensionDownload(item)) { |
| 234 scoped_refptr<CrxInstaller> crx_installer = | 278 scoped_refptr<CrxInstaller> crx_installer = |
| 235 download_crx_util::OpenChromeExtension(profile_, *item); | 279 download_crx_util::OpenChromeExtension(profile_, *item); |
| 236 | 280 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); | 484 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); |
| 441 break; | 485 break; |
| 442 case DownloadProtectionService::UNCOMMON: | 486 case DownloadProtectionService::UNCOMMON: |
| 443 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT); | 487 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT); |
| 444 break; | 488 break; |
| 445 } | 489 } |
| 446 } | 490 } |
| 447 | 491 |
| 448 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | 492 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
| 449 item->GetExternalData(&safe_browsing_id)); | 493 item->GetExternalData(&safe_browsing_id)); |
| 450 DCHECK(state); | 494 state->CompleteDownload(result); |
| 451 if (state) { | |
| 452 state->pending = false; | |
| 453 state->verdict = result; | |
| 454 } | |
| 455 item->MaybeCompleteDownload(); | |
| 456 } | 495 } |
| 457 | 496 |
| 458 // content::NotificationObserver implementation. | 497 // content::NotificationObserver implementation. |
| 459 void ChromeDownloadManagerDelegate::Observe( | 498 void ChromeDownloadManagerDelegate::Observe( |
| 460 int type, | 499 int type, |
| 461 const content::NotificationSource& source, | 500 const content::NotificationSource& source, |
| 462 const content::NotificationDetails& details) { | 501 const content::NotificationDetails& details) { |
| 463 DCHECK(type == chrome::NOTIFICATION_CRX_INSTALLER_DONE); | 502 DCHECK(type == chrome::NOTIFICATION_CRX_INSTALLER_DONE); |
| 464 | 503 |
| 465 registrar_.Remove(this, | 504 registrar_.Remove(this, |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 700 int32 download_id, int64 db_handle) { | 739 int32 download_id, int64 db_handle) { |
| 701 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 740 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
| 702 // call this function with an invalid |db_handle|. For instance, this can | 741 // call this function with an invalid |db_handle|. For instance, this can |
| 703 // happen when the history database is offline. We cannot have multiple | 742 // happen when the history database is offline. We cannot have multiple |
| 704 // DownloadItems with the same invalid db_handle, so we need to assign a | 743 // DownloadItems with the same invalid db_handle, so we need to assign a |
| 705 // unique |db_handle| here. | 744 // unique |db_handle| here. |
| 706 if (db_handle == DownloadItem::kUninitializedHandle) | 745 if (db_handle == DownloadItem::kUninitializedHandle) |
| 707 db_handle = download_history_->GetNextFakeDbHandle(); | 746 db_handle = download_history_->GetNextFakeDbHandle(); |
| 708 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); | 747 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); |
| 709 } | 748 } |
| OLD | NEW |