| 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_; } |
| 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_callback_ = cb; |
| 95 } |
| 96 |
| 97 void CompleteDownload(DownloadProtectionService::DownloadCheckResult result) { |
| 98 pending_ = false; |
| 99 verdict_ = result; |
| 100 if (!complete_callback_.is_null()) { |
| 101 complete_callback_.Run(); |
| 102 complete_callback_.Reset(); |
| 103 } |
| 104 } |
| 105 |
| 106 private: |
| 107 bool pending_; |
| 108 DownloadProtectionService::DownloadCheckResult verdict_; |
| 109 base::Closure complete_callback_; |
| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 CheckDownloadUrlDone(download_id, DownloadProtectionService::SAFE); | 188 CheckDownloadUrlDone(download_id, DownloadProtectionService::SAFE); |
| 152 return false; | 189 return false; |
| 153 } | 190 } |
| 154 | 191 |
| 155 void ChromeDownloadManagerDelegate::ChooseDownloadPath( | 192 void ChromeDownloadManagerDelegate::ChooseDownloadPath( |
| 156 WebContents* web_contents, | 193 WebContents* web_contents, |
| 157 const FilePath& suggested_path, | 194 const FilePath& suggested_path, |
| 158 int32 download_id) { | 195 int32 download_id) { |
| 159 // Deletes itself. | 196 // Deletes itself. |
| 160 #if defined(OS_CHROMEOS) | 197 #if defined(OS_CHROMEOS) |
| 161 new DownloadFilePickerChromeOS( | 198 new DownloadFilePickerChromeOS |
| 162 #else | 199 #else |
| 163 new DownloadFilePicker( | 200 new DownloadFilePicker |
| 164 #endif | 201 #endif |
| 165 download_manager_, web_contents, suggested_path, download_id); | 202 (download_manager_, web_contents, suggested_path, download_id); |
| 166 } | 203 } |
| 167 | 204 |
| 168 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( | 205 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( |
| 169 const FilePath& suggested_path) { | 206 const FilePath& suggested_path) { |
| 170 return download_util::GetCrDownloadPath(suggested_path); | 207 return download_util::GetCrDownloadPath(suggested_path); |
| 171 } | 208 } |
| 172 | 209 |
| 173 WebContents* ChromeDownloadManagerDelegate:: | 210 WebContents* ChromeDownloadManagerDelegate:: |
| 174 GetAlternativeWebContentsToNotifyForDownload() { | 211 GetAlternativeWebContentsToNotifyForDownload() { |
| 175 #if defined(OS_ANDROID) | 212 #if defined(OS_ANDROID) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 190 FilePath::StringType extension = path.Extension(); | 227 FilePath::StringType extension = path.Extension(); |
| 191 if (extension.empty()) | 228 if (extension.empty()) |
| 192 return false; | 229 return false; |
| 193 if (Extension::IsExtension(path)) | 230 if (Extension::IsExtension(path)) |
| 194 return false; | 231 return false; |
| 195 DCHECK(extension[0] == FilePath::kExtensionSeparator); | 232 DCHECK(extension[0] == FilePath::kExtensionSeparator); |
| 196 extension.erase(0, 1); | 233 extension.erase(0, 1); |
| 197 return download_prefs_->IsAutoOpenEnabledForExtension(extension); | 234 return download_prefs_->IsAutoOpenEnabledForExtension(extension); |
| 198 } | 235 } |
| 199 | 236 |
| 200 bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(DownloadItem* item) { | 237 void ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal( |
| 238 DownloadItem* item, |
| 239 const base::Closure& user_complete_callback) { |
| 240 bool run_cb = true; |
| 241 #if defined(ENABLE_SAFE_BROWSING) |
| 242 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
| 243 item->GetExternalData(&safe_browsing_id)); |
| 244 if (state && state->pending()) |
| 245 run_cb = false; |
| 246 #endif |
| 247 #if defined(OS_CHROMEOS) |
| 248 const base::Closure& internal_complete_callback = base::Bind( |
| 249 &ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal, this, |
| 250 item, user_complete_callback); |
| 251 if (!gdata::GDataDownloadObserver::IsReadyToComplete( |
| 252 item, internal_complete_callback)) |
| 253 run_cb = false; |
| 254 #endif |
| 255 if (run_cb) |
| 256 user_complete_callback.Run(); |
| 257 } |
| 258 |
| 259 bool ChromeDownloadManagerDelegate::ShouldCompleteDownload( |
| 260 DownloadItem* item, |
| 261 const base::Closure& user_complete_callback) { |
| 262 const base::Closure& internal_complete_callback = base::Bind( |
| 263 &ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal, this, |
| 264 item, user_complete_callback); |
| 201 #if defined(ENABLE_SAFE_BROWSING) | 265 #if defined(ENABLE_SAFE_BROWSING) |
| 202 // See if there is already a pending SafeBrowsing check for that download. | 266 // See if there is already a pending SafeBrowsing check for that download. |
| 203 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | 267 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
| 204 item->GetExternalData(&safe_browsing_id)); | 268 item->GetExternalData(&safe_browsing_id)); |
| 205 if (state) | 269 if (state) { |
| 206 // Don't complete the download until we have an answer. | 270 // Don't complete the download until we have an answer. |
| 207 return !state->pending; | 271 if (!state->pending()) |
| 272 return true; |
| 273 state->set_complete_callback(internal_complete_callback); |
| 274 return false; |
| 275 } |
| 208 | 276 |
| 209 // Begin the safe browsing download protection check. | 277 // Begin the safe browsing download protection check. |
| 210 DownloadProtectionService* service = GetDownloadProtectionService(); | 278 DownloadProtectionService* service = GetDownloadProtectionService(); |
| 211 if (service) { | 279 if (service) { |
| 212 VLOG(2) << __FUNCTION__ << "() Start SB download check for download = " | 280 VLOG(2) << __FUNCTION__ << "() Start SB download check for download = " |
| 213 << item->DebugString(false); | 281 << item->DebugString(false); |
| 214 state = new SafeBrowsingState(); | 282 state = new SafeBrowsingState(internal_complete_callback); |
| 215 state->pending = true; | |
| 216 state->verdict = DownloadProtectionService::SAFE; | |
| 217 item->SetExternalData(&safe_browsing_id, state); | 283 item->SetExternalData(&safe_browsing_id, state); |
| 218 service->CheckClientDownload( | 284 service->CheckClientDownload( |
| 219 DownloadProtectionService::DownloadInfo::FromDownloadItem(*item), | 285 DownloadProtectionService::DownloadInfo::FromDownloadItem(*item), |
| 220 base::Bind( | 286 base::Bind( |
| 221 &ChromeDownloadManagerDelegate::CheckClientDownloadDone, | 287 &ChromeDownloadManagerDelegate::CheckClientDownloadDone, |
| 222 this, | 288 this, |
| 223 item->GetId())); | 289 item->GetId())); |
| 224 return false; | 290 return false; |
| 225 } | 291 } |
| 226 #endif | 292 #endif |
| 227 #if defined(OS_CHROMEOS) | 293 #if defined(OS_CHROMEOS) |
| 228 // If there's a GData upload associated with this download, we wait until that | 294 // If there's a GData upload associated with this download, we wait until that |
| 229 // is complete before allowing the download item to complete. | 295 // is complete before allowing the download item to complete. |
| 230 if (!gdata::GDataDownloadObserver::IsReadyToComplete(item)) | 296 if (!gdata::GDataDownloadObserver::IsReadyToComplete( |
| 297 item, internal_complete_callback)) |
| 231 return false; | 298 return false; |
| 232 #endif | 299 #endif |
| 233 return true; | 300 return true; |
| 234 } | 301 } |
| 235 | 302 |
| 236 bool ChromeDownloadManagerDelegate::ShouldOpenDownload(DownloadItem* item) { | 303 bool ChromeDownloadManagerDelegate::ShouldOpenDownload(DownloadItem* item) { |
| 237 if (IsExtensionDownload(item)) { | 304 if (IsExtensionDownload(item)) { |
| 238 scoped_refptr<CrxInstaller> crx_installer = | 305 scoped_refptr<CrxInstaller> crx_installer = |
| 239 download_crx_util::OpenChromeExtension(profile_, *item); | 306 download_crx_util::OpenChromeExtension(profile_, *item); |
| 240 | 307 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); | 511 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); |
| 445 break; | 512 break; |
| 446 case DownloadProtectionService::UNCOMMON: | 513 case DownloadProtectionService::UNCOMMON: |
| 447 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT); | 514 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT); |
| 448 break; | 515 break; |
| 449 } | 516 } |
| 450 } | 517 } |
| 451 | 518 |
| 452 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | 519 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
| 453 item->GetExternalData(&safe_browsing_id)); | 520 item->GetExternalData(&safe_browsing_id)); |
| 454 DCHECK(state); | 521 state->CompleteDownload(result); |
| 455 if (state) { | |
| 456 state->pending = false; | |
| 457 state->verdict = result; | |
| 458 } | |
| 459 item->MaybeCompleteDownload(); | |
| 460 } | 522 } |
| 461 | 523 |
| 462 // content::NotificationObserver implementation. | 524 // content::NotificationObserver implementation. |
| 463 void ChromeDownloadManagerDelegate::Observe( | 525 void ChromeDownloadManagerDelegate::Observe( |
| 464 int type, | 526 int type, |
| 465 const content::NotificationSource& source, | 527 const content::NotificationSource& source, |
| 466 const content::NotificationDetails& details) { | 528 const content::NotificationDetails& details) { |
| 467 DCHECK(type == chrome::NOTIFICATION_CRX_INSTALLER_DONE); | 529 DCHECK(type == chrome::NOTIFICATION_CRX_INSTALLER_DONE); |
| 468 | 530 |
| 469 registrar_.Remove(this, | 531 registrar_.Remove(this, |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 int32 download_id, int64 db_handle) { | 766 int32 download_id, int64 db_handle) { |
| 705 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 767 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
| 706 // call this function with an invalid |db_handle|. For instance, this can | 768 // call this function with an invalid |db_handle|. For instance, this can |
| 707 // happen when the history database is offline. We cannot have multiple | 769 // happen when the history database is offline. We cannot have multiple |
| 708 // DownloadItems with the same invalid db_handle, so we need to assign a | 770 // DownloadItems with the same invalid db_handle, so we need to assign a |
| 709 // unique |db_handle| here. | 771 // unique |db_handle| here. |
| 710 if (db_handle == DownloadItem::kUninitializedHandle) | 772 if (db_handle == DownloadItem::kUninitializedHandle) |
| 711 db_handle = download_history_->GetNextFakeDbHandle(); | 773 db_handle = download_history_->GetNextFakeDbHandle(); |
| 712 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); | 774 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); |
| 713 } | 775 } |
| OLD | NEW |