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 |