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. |
Randy Smith (Not in Mondays)
2012/05/09 00:50:56
nit, suggestion: Add "Only valid to call if |!pend
benjhayden
2012/05/14 15:35:05
Done.
| |
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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 return download_prefs_->IsAutoOpenEnabledForExtension(extension); | 234 return download_prefs_->IsAutoOpenEnabledForExtension(extension); |
198 } | 235 } |
199 | 236 |
200 // static | 237 // static |
201 void ChromeDownloadManagerDelegate::DisableSafeBrowsing(DownloadItem* item) { | 238 void ChromeDownloadManagerDelegate::DisableSafeBrowsing(DownloadItem* item) { |
202 #if defined(ENABLE_SAFE_BROWSING) | 239 #if defined(ENABLE_SAFE_BROWSING) |
203 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | 240 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
204 item->GetExternalData(&safe_browsing_id)); | 241 item->GetExternalData(&safe_browsing_id)); |
205 DCHECK(state == NULL); | 242 DCHECK(state == NULL); |
206 if (state == NULL) { | 243 if (state == NULL) { |
207 state = new SafeBrowsingState(); | 244 state = new SafeBrowsingState(base::Closure()); |
208 item->SetExternalData(&safe_browsing_id, state); | |
209 } | 245 } |
210 state->pending = false; | 246 state->CompleteDownload(DownloadProtectionService::SAFE); |
211 state->verdict = DownloadProtectionService::SAFE; | |
212 #endif | 247 #endif |
213 } | 248 } |
214 | 249 |
215 bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(DownloadItem* item) { | 250 void ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal( |
Randy Smith (Not in Mondays)
2012/05/09 00:50:56
The splits of callback setup code for the subsyste
benjhayden
2012/05/14 15:35:05
Sorry, I don't see how that's different from what'
| |
251 DownloadItem* item, | |
252 const base::Closure& user_complete_callback) { | |
216 #if defined(ENABLE_SAFE_BROWSING) | 253 #if defined(ENABLE_SAFE_BROWSING) |
217 // See if there is already a pending SafeBrowsing check for that download. | |
218 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | 254 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
219 item->GetExternalData(&safe_browsing_id)); | 255 item->GetExternalData(&safe_browsing_id)); |
220 // Don't complete the download until we have an answer. | 256 if (state && state->pending()) |
221 if (state && state->pending) | 257 return; |
258 #endif | |
259 #if defined(OS_CHROMEOS) | |
260 const base::Closure& internal_complete_callback = base::Bind( | |
261 &ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal, this, | |
262 item, user_complete_callback); | |
263 if (!gdata::GDataDownloadObserver::IsReadyToComplete( | |
264 item, internal_complete_callback)) | |
265 return; | |
266 #endif | |
267 user_complete_callback.Run(); | |
268 } | |
269 | |
270 bool ChromeDownloadManagerDelegate::ShouldCompleteDownload( | |
271 DownloadItem* item, | |
272 const base::Closure& user_complete_callback) { | |
273 const base::Closure& internal_complete_callback = base::Bind( | |
274 &ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal, this, | |
275 item, user_complete_callback); | |
276 #if defined(ENABLE_SAFE_BROWSING) | |
277 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | |
278 item->GetExternalData(&safe_browsing_id)); | |
279 if (state) { | |
280 // Don't complete the download until we have an answer. | |
281 if (!state->pending()) | |
282 return true; | |
283 state->set_complete_callback(internal_complete_callback); | |
222 return false; | 284 return false; |
285 } | |
223 | 286 |
224 if (state == NULL) { | 287 // Begin the safe browsing download protection check. |
225 // Begin the safe browsing download protection check. | 288 DownloadProtectionService* service = GetDownloadProtectionService(); |
226 DownloadProtectionService* service = GetDownloadProtectionService(); | 289 if (service) { |
227 if (service) { | 290 VLOG(2) << __FUNCTION__ << "() Start SB download check for download = " |
228 VLOG(2) << __FUNCTION__ << "() Start SB download check for download = " | 291 << item->DebugString(false); |
229 << item->DebugString(false); | 292 state = new SafeBrowsingState(internal_complete_callback); |
230 state = new SafeBrowsingState(); | 293 item->SetExternalData(&safe_browsing_id, state); |
231 state->pending = true; | 294 service->CheckClientDownload( |
232 state->verdict = DownloadProtectionService::SAFE; | 295 DownloadProtectionService::DownloadInfo::FromDownloadItem(*item), |
233 item->SetExternalData(&safe_browsing_id, state); | 296 base::Bind( |
234 service->CheckClientDownload( | 297 &ChromeDownloadManagerDelegate::CheckClientDownloadDone, |
235 DownloadProtectionService::DownloadInfo::FromDownloadItem(*item), | 298 this, |
236 base::Bind( | 299 item->GetId())); |
237 &ChromeDownloadManagerDelegate::CheckClientDownloadDone, | 300 return false; |
238 this, | |
239 item->GetId())); | |
240 return false; | |
241 } | |
242 } | 301 } |
243 #endif | 302 #endif |
244 | 303 |
245 #if defined(OS_CHROMEOS) | 304 #if defined(OS_CHROMEOS) |
246 // If there's a GData upload associated with this download, we wait until that | 305 // If there's a GData upload associated with this download, we wait until that |
247 // is complete before allowing the download item to complete. | 306 // is complete before allowing the download item to complete. |
248 if (!gdata::GDataDownloadObserver::IsReadyToComplete(item)) | 307 if (!gdata::GDataDownloadObserver::IsReadyToComplete( |
308 item, internal_complete_callback)) | |
249 return false; | 309 return false; |
250 #endif | 310 #endif |
251 return true; | 311 return true; |
252 } | 312 } |
253 | 313 |
254 bool ChromeDownloadManagerDelegate::ShouldOpenDownload(DownloadItem* item) { | 314 bool ChromeDownloadManagerDelegate::ShouldOpenDownload(DownloadItem* item) { |
255 if (IsExtensionDownload(item)) { | 315 if (IsExtensionDownload(item)) { |
256 scoped_refptr<CrxInstaller> crx_installer = | 316 scoped_refptr<CrxInstaller> crx_installer = |
257 download_crx_util::OpenChromeExtension(profile_, *item); | 317 download_crx_util::OpenChromeExtension(profile_, *item); |
258 | 318 |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); | 519 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); |
460 break; | 520 break; |
461 case DownloadProtectionService::UNCOMMON: | 521 case DownloadProtectionService::UNCOMMON: |
462 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT); | 522 item->SetDangerType(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT); |
463 break; | 523 break; |
464 } | 524 } |
465 } | 525 } |
466 | 526 |
467 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( | 527 SafeBrowsingState* state = static_cast<SafeBrowsingState*>( |
468 item->GetExternalData(&safe_browsing_id)); | 528 item->GetExternalData(&safe_browsing_id)); |
469 DCHECK(state); | 529 state->CompleteDownload(result); |
470 if (state) { | |
471 state->pending = false; | |
472 state->verdict = result; | |
473 } | |
474 item->MaybeCompleteDownload(); | |
475 } | 530 } |
476 | 531 |
477 // content::NotificationObserver implementation. | 532 // content::NotificationObserver implementation. |
478 void ChromeDownloadManagerDelegate::Observe( | 533 void ChromeDownloadManagerDelegate::Observe( |
479 int type, | 534 int type, |
480 const content::NotificationSource& source, | 535 const content::NotificationSource& source, |
481 const content::NotificationDetails& details) { | 536 const content::NotificationDetails& details) { |
482 DCHECK(type == chrome::NOTIFICATION_CRX_INSTALLER_DONE); | 537 DCHECK(type == chrome::NOTIFICATION_CRX_INSTALLER_DONE); |
483 | 538 |
484 registrar_.Remove(this, | 539 registrar_.Remove(this, |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
719 int32 download_id, int64 db_handle) { | 774 int32 download_id, int64 db_handle) { |
720 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 775 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
721 // call this function with an invalid |db_handle|. For instance, this can | 776 // call this function with an invalid |db_handle|. For instance, this can |
722 // happen when the history database is offline. We cannot have multiple | 777 // 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 | 778 // DownloadItems with the same invalid db_handle, so we need to assign a |
724 // unique |db_handle| here. | 779 // unique |db_handle| here. |
725 if (db_handle == DownloadItem::kUninitializedHandle) | 780 if (db_handle == DownloadItem::kUninitializedHandle) |
726 db_handle = download_history_->GetNextFakeDbHandle(); | 781 db_handle = download_history_->GetNextFakeDbHandle(); |
727 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); | 782 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); |
728 } | 783 } |
OLD | NEW |