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_callback) | |
| 75 : pending_(true), | |
| 76 verdict_(DownloadProtectionService::SAFE), | |
| 77 complete_callback_(complete_callback) { | |
| 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_; } |
| 75 // The verdict that we got from calling CheckClientDownload. | 84 |
| 76 safe_browsing::DownloadProtectionService::DownloadCheckResult verdict; | 85 // The verdict that we got from calling CheckClientDownload. Only valid to |
| 86 // call if |!pending()|. | |
| 87 DownloadProtectionService::DownloadCheckResult verdict() const { | |
| 88 return verdict_; | |
| 89 } | |
| 90 | |
| 91 // |cb| will be run when CompleteDownload() is called. | |
| 92 void set_complete_callback(const base::Closure& cb) { | |
| 93 // Be very careful to avoid calling cb twice, or more than one cb! | |
| 94 if (pending()) | |
| 95 complete_callback_ = cb; | |
| 96 } | |
| 97 | |
| 98 void CompleteDownload(DownloadProtectionService::DownloadCheckResult result) { | |
| 99 pending_ = false; | |
| 100 verdict_ = result; | |
| 101 if (!complete_callback_.is_null()) { | |
| 102 complete_callback_.Run(); | |
| 103 complete_callback_.Reset(); | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 private: | |
| 108 bool pending_; | |
| 109 DownloadProtectionService::DownloadCheckResult verdict_; | |
| 110 base::Closure complete_callback_; | |
| 111 | |
| 112 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingState); | |
| 77 }; | 113 }; |
| 78 | 114 |
| 115 SafeBrowsingState::~SafeBrowsingState() {} | |
| 116 | |
| 79 } // namespace | 117 } // namespace |
| 80 | 118 |
| 81 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile) | 119 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile) |
| 82 : profile_(profile), | 120 : profile_(profile), |
| 83 next_download_id_(0), | 121 next_download_id_(0), |
| 84 download_prefs_(new DownloadPrefs(profile->GetPrefs())) { | 122 download_prefs_(new DownloadPrefs(profile->GetPrefs())) { |
| 85 } | 123 } |
| 86 | 124 |
| 87 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { | 125 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { |
| 88 } | 126 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 return download_prefs_->IsAutoOpenEnabledForExtension(extension); | 235 return download_prefs_->IsAutoOpenEnabledForExtension(extension); |
| 198 } | 236 } |
| 199 | 237 |
| 200 // static | 238 // static |
| 201 void ChromeDownloadManagerDelegate::DisableSafeBrowsing(DownloadItem* item) { | 239 void ChromeDownloadManagerDelegate::DisableSafeBrowsing(DownloadItem* item) { |
| 202 #if defined(ENABLE_SAFE_BROWSING) | 240 #if defined(ENABLE_SAFE_BROWSING) |
| 203 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | 241 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
| 204 item->GetExternalData(&safe_browsing_id)); | 242 item->GetExternalData(&safe_browsing_id)); |
| 205 DCHECK(state == NULL); | 243 DCHECK(state == NULL); |
| 206 if (state == NULL) { | 244 if (state == NULL) { |
| 207 state = new SafeBrowsingState(); | 245 state = new SafeBrowsingState(base::Closure()); |
| 208 item->SetExternalData(&safe_browsing_id, state); | |
| 209 } | 246 } |
| 210 state->pending = false; | 247 state->CompleteDownload(DownloadProtectionService::SAFE); |
| 211 state->verdict = DownloadProtectionService::SAFE; | |
| 212 #endif | 248 #endif |
| 213 } | 249 } |
| 214 | 250 |
| 215 bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(DownloadItem* item) { | 251 void ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal( |
| 252 DownloadItem* item, | |
| 253 const base::Closure& user_complete_callback) { | |
| 216 #if defined(ENABLE_SAFE_BROWSING) | 254 #if defined(ENABLE_SAFE_BROWSING) |
| 217 // See if there is already a pending SafeBrowsing check for that download. | |
| 218 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | 255 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
| 219 item->GetExternalData(&safe_browsing_id)); | 256 item->GetExternalData(&safe_browsing_id)); |
| 220 // Don't complete the download until we have an answer. | 257 if (state && state->pending()) |
| 221 if (state && state->pending) | 258 return; |
| 259 #endif | |
| 260 #if defined(OS_CHROMEOS) | |
| 261 const base::Closure& internal_complete_callback = base::Bind( | |
| 262 &ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal, this, | |
| 263 item, user_complete_callback); | |
| 264 if (!gdata::GDataDownloadObserver::IsReadyToComplete( | |
| 265 item, internal_complete_callback)) | |
| 266 return; | |
| 267 #endif | |
| 268 user_complete_callback.Run(); | |
| 269 } | |
| 270 | |
| 271 bool ChromeDownloadManagerDelegate::ShouldCompleteDownload( | |
| 272 DownloadItem* item, | |
| 273 const base::Closure& user_complete_callback) { | |
| 274 const base::Closure& internal_complete_callback = base::Bind( | |
| 275 &ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal, this, | |
| 276 item, user_complete_callback); | |
| 277 #if defined(ENABLE_SAFE_BROWSING) | |
| 278 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | |
| 279 item->GetExternalData(&safe_browsing_id)); | |
| 280 if (state) { | |
| 281 // Don't complete the download until we have an answer. | |
| 282 if (!state->pending()) | |
| 283 return true; | |
|
Randy Smith (Not in Mondays)
2012/05/14 18:30:31
Isn't this a bug, if a not currently important one
benjhayden
2012/05/15 21:25:28
Done.
| |
| 284 state->set_complete_callback(internal_complete_callback); | |
| 222 return false; | 285 return false; |
| 286 } | |
| 223 | 287 |
| 224 if (state == NULL) { | 288 // Begin the safe browsing download protection check. |
| 225 // Begin the safe browsing download protection check. | 289 DownloadProtectionService* service = GetDownloadProtectionService(); |
| 226 DownloadProtectionService* service = GetDownloadProtectionService(); | 290 if (service) { |
| 227 if (service) { | 291 VLOG(2) << __FUNCTION__ << "() Start SB download check for download = " |
| 228 VLOG(2) << __FUNCTION__ << "() Start SB download check for download = " | 292 << item->DebugString(false); |
| 229 << item->DebugString(false); | 293 state = new SafeBrowsingState(internal_complete_callback); |
| 230 state = new SafeBrowsingState(); | 294 item->SetExternalData(&safe_browsing_id, state); |
| 231 state->pending = true; | 295 service->CheckClientDownload( |
| 232 state->verdict = DownloadProtectionService::SAFE; | 296 DownloadProtectionService::DownloadInfo::FromDownloadItem(*item), |
| 233 item->SetExternalData(&safe_browsing_id, state); | 297 base::Bind( |
| 234 service->CheckClientDownload( | 298 &ChromeDownloadManagerDelegate::CheckClientDownloadDone, |
| 235 DownloadProtectionService::DownloadInfo::FromDownloadItem(*item), | 299 this, |
| 236 base::Bind( | 300 item->GetId())); |
| 237 &ChromeDownloadManagerDelegate::CheckClientDownloadDone, | 301 return false; |
| 238 this, | |
| 239 item->GetId())); | |
| 240 return false; | |
| 241 } | |
| 242 } | 302 } |
| 243 #endif | 303 #endif |
| 244 | 304 |
| 245 #if defined(OS_CHROMEOS) | 305 #if defined(OS_CHROMEOS) |
| 246 // If there's a GData upload associated with this download, we wait until that | 306 // If there's a GData upload associated with this download, we wait until that |
| 247 // is complete before allowing the download item to complete. | 307 // is complete before allowing the download item to complete. |
| 248 if (!gdata::GDataDownloadObserver::IsReadyToComplete(item)) | 308 if (!gdata::GDataDownloadObserver::IsReadyToComplete( |
| 309 item, internal_complete_callback)) | |
| 249 return false; | 310 return false; |
| 250 #endif | 311 #endif |
| 251 return true; | 312 return true; |
| 252 } | 313 } |
| 253 | 314 |
| 254 bool ChromeDownloadManagerDelegate::ShouldOpenDownload(DownloadItem* item) { | 315 bool ChromeDownloadManagerDelegate::ShouldOpenDownload(DownloadItem* item) { |
| 255 if (IsExtensionDownload(item)) { | 316 if (IsExtensionDownload(item)) { |
| 256 scoped_refptr<CrxInstaller> crx_installer = | 317 scoped_refptr<CrxInstaller> crx_installer = |
| 257 download_crx_util::OpenChromeExtension(profile_, *item); | 318 download_crx_util::OpenChromeExtension(profile_, *item); |
| 258 | 319 |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 459 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); | 520 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); |
| 460 break; | 521 break; |
| 461 case DownloadProtectionService::UNCOMMON: | 522 case DownloadProtectionService::UNCOMMON: |
| 462 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT); | 523 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT); |
| 463 break; | 524 break; |
| 464 } | 525 } |
| 465 } | 526 } |
| 466 | 527 |
| 467 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | 528 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
| 468 item->GetExternalData(&safe_browsing_id)); | 529 item->GetExternalData(&safe_browsing_id)); |
| 469 DCHECK(state); | 530 state->CompleteDownload(result); |
| 470 if (state) { | |
| 471 state->pending = false; | |
| 472 state->verdict = result; | |
| 473 } | |
| 474 item->MaybeCompleteDownload(); | |
| 475 } | 531 } |
| 476 | 532 |
| 477 // content::NotificationObserver implementation. | 533 // content::NotificationObserver implementation. |
| 478 void ChromeDownloadManagerDelegate::Observe( | 534 void ChromeDownloadManagerDelegate::Observe( |
| 479 int type, | 535 int type, |
| 480 const content::NotificationSource& source, | 536 const content::NotificationSource& source, |
| 481 const content::NotificationDetails& details) { | 537 const content::NotificationDetails& details) { |
| 482 DCHECK(type == chrome::NOTIFICATION_CRX_INSTALLER_DONE); | 538 DCHECK(type == chrome::NOTIFICATION_CRX_INSTALLER_DONE); |
| 483 | 539 |
| 484 registrar_.Remove(this, | 540 registrar_.Remove(this, |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 719 int32 download_id, int64 db_handle) { | 775 int32 download_id, int64 db_handle) { |
| 720 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 776 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
| 721 // call this function with an invalid |db_handle|. For instance, this can | 777 // call this function with an invalid |db_handle|. For instance, this can |
| 722 // happen when the history database is offline. We cannot have multiple | 778 // happen when the history database is offline. We cannot have multiple |
| 723 // DownloadItems with the same invalid db_handle, so we need to assign a | 779 // DownloadItems with the same invalid db_handle, so we need to assign a |
| 724 // unique |db_handle| here. | 780 // unique |db_handle| here. |
| 725 if (db_handle == DownloadItem::kUninitializedHandle) | 781 if (db_handle == DownloadItem::kUninitializedHandle) |
| 726 db_handle = download_history_->GetNextFakeDbHandle(); | 782 db_handle = download_history_->GetNextFakeDbHandle(); |
| 727 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); | 783 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); |
| 728 } | 784 } |
| OLD | NEW |