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
3 // found in the LICENSE file.
5 #include "chrome/browser/download/chrome_download_manager_delegate.h"
9 #include "base/basictypes.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback.h"
13 #include "base/file_util.h"
14 #include "base/prefs/pref_member.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/rand_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/task_runner.h"
20 #include "base/threading/sequenced_worker_pool.h"
21 #include "base/time/time.h"
22 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/chrome_notification_types.h"
24 #include "chrome/browser/download/download_completion_blocker.h"
25 #include "chrome/browser/download/download_crx_util.h"
26 #include "chrome/browser/download/download_file_picker.h"
27 #include "chrome/browser/download/download_history.h"
28 #include "chrome/browser/download/download_item_model.h"
29 #include "chrome/browser/download/download_path_reservation_tracker.h"
30 #include "chrome/browser/download/download_prefs.h"
31 #include "chrome/browser/download/download_service.h"
32 #include "chrome/browser/download/download_service_factory.h"
33 #include "chrome/browser/download/download_stats.h"
34 #include "chrome/browser/download/download_target_determiner.h"
35 #include "chrome/browser/download/save_package_file_picker.h"
36 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
37 #include "chrome/browser/extensions/crx_installer.h"
38 #include "chrome/browser/extensions/webstore_installer.h"
39 #include "chrome/browser/platform_util.h"
40 #include "chrome/browser/profiles/profile.h"
41 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
42 #include "chrome/browser/ui/browser.h"
43 #include "chrome/browser/ui/browser_finder.h"
44 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
45 #include "chrome/common/chrome_constants.h"
46 #include "chrome/common/pref_names.h"
47 #include "components/user_prefs/pref_registry_syncable.h"
48 #include "content/public/browser/download_item.h"
49 #include "content/public/browser/download_manager.h"
50 #include "content/public/browser/notification_source.h"
51 #include "content/public/browser/page_navigator.h"
52 #include "extensions/common/constants.h"
53 #include "net/base/filename_util.h"
54 #include "net/base/mime_util.h"
56 #if defined(OS_CHROMEOS)
57 #include "chrome/browser/chromeos/drive/download_handler.h"
58 #include "chrome/browser/chromeos/drive/file_system_util.h"
61 using content::BrowserThread
;
62 using content::DownloadItem
;
63 using content::DownloadManager
;
64 using safe_browsing::DownloadProtectionService
;
68 #if defined(FULL_SAFE_BROWSING)
70 // String pointer used for identifying safebrowing data associated with
72 const char kSafeBrowsingUserDataKey
[] = "Safe Browsing ID";
74 // The state of a safebrowsing check.
75 class SafeBrowsingState
: public DownloadCompletionBlocker
{
78 : verdict_(DownloadProtectionService::SAFE
) {
81 virtual ~SafeBrowsingState();
83 // The verdict that we got from calling CheckClientDownload. Only valid to
84 // call if |is_complete()|.
85 DownloadProtectionService::DownloadCheckResult
verdict() const {
89 void SetVerdict(DownloadProtectionService::DownloadCheckResult result
) {
95 DownloadProtectionService::DownloadCheckResult verdict_
;
97 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingState
);
100 SafeBrowsingState::~SafeBrowsingState() {}
102 #endif // FULL_SAFE_BROWSING
104 // Used with GetPlatformDownloadPath() to indicate which platform path to
106 enum PlatformDownloadPathType
{
107 // Return the platform specific target path.
108 PLATFORM_TARGET_PATH
,
110 // Return the platform specific current path. If the download is in-progress
111 // and the download location is a local filesystem path, then
112 // GetPlatformDownloadPath will return the path to the intermediate file.
113 PLATFORM_CURRENT_PATH
116 // Returns a path in the form that that is expected by platform_util::OpenItem /
117 // platform_util::ShowItemInFolder / DownloadTargetDeterminer.
119 // DownloadItems corresponding to Drive downloads use a temporary file as the
120 // target path. The paths returned by DownloadItem::GetFullPath() /
121 // GetTargetFilePath() refer to this temporary file. This function looks up the
122 // corresponding path in Drive for these downloads.
124 // How the platform path is determined is based on PlatformDownloadPathType.
125 base::FilePath
GetPlatformDownloadPath(Profile
* profile
,
126 const DownloadItem
* download
,
127 PlatformDownloadPathType path_type
) {
128 #if defined(OS_CHROMEOS)
129 // Drive downloads always return the target path for all types.
130 drive::DownloadHandler
* drive_download_handler
=
131 drive::DownloadHandler::GetForProfile(profile
);
132 if (drive_download_handler
&&
133 drive_download_handler
->IsDriveDownload(download
))
134 return drive_download_handler
->GetTargetPath(download
);
137 if (path_type
== PLATFORM_TARGET_PATH
)
138 return download
->GetTargetFilePath();
139 return download
->GetFullPath();
142 #if defined(FULL_SAFE_BROWSING)
143 // Callback invoked by DownloadProtectionService::CheckClientDownload.
144 // |is_content_check_supported| is true if the SB service supports scanning the
145 // download for malicious content.
146 // |callback| is invoked with a danger type determined as follows:
148 // Danger type is (in order of preference):
149 // * DANGEROUS_URL, if the URL is a known malware site.
150 // * MAYBE_DANGEROUS_CONTENT, if the content will be scanned for
151 // malware. I.e. |is_content_check_supported| is true.
153 void CheckDownloadUrlDone(
154 const DownloadTargetDeterminerDelegate::CheckDownloadUrlCallback
& callback
,
155 bool is_content_check_supported
,
156 DownloadProtectionService::DownloadCheckResult result
) {
157 content::DownloadDangerType danger_type
;
158 if (result
== DownloadProtectionService::SAFE
) {
159 // If this type of files is handled by the enhanced SafeBrowsing download
160 // protection, mark it as potentially dangerous content until we are done
162 if (is_content_check_supported
)
163 danger_type
= content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT
;
165 danger_type
= content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
;
167 // If the URL is malicious, we'll use that as the danger type. The results
168 // of the content check, if one is performed, will be ignored.
169 danger_type
= content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL
;
171 callback
.Run(danger_type
);
174 #endif // FULL_SAFE_BROWSING
176 // Called on the blocking pool to determine the MIME type for |path|.
177 void GetMimeTypeAndReplyOnUIThread(
178 const base::FilePath
& path
,
179 const base::Callback
<void(const std::string
&)>& callback
) {
180 std::string mime_type
;
181 net::GetMimeTypeFromFile(path
, &mime_type
);
182 BrowserThread::PostTask(
183 BrowserThread::UI
, FROM_HERE
, base::Bind(callback
, mime_type
));
186 bool IsOpenInBrowserPreferreredForFile(const base::FilePath
& path
) {
187 // On Android, always prefer opening with an external app. On ChromeOS, there
188 // are no external apps so just allow all opens to be handled by the "System."
189 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) && defined(ENABLE_PLUGINS)
190 // TODO(asanka): Consider other file types and MIME types.
191 // http://crbug.com/323561
192 if (path
.MatchesExtension(FILE_PATH_LITERAL(".pdf")) ||
193 path
.MatchesExtension(FILE_PATH_LITERAL(".htm")) ||
194 path
.MatchesExtension(FILE_PATH_LITERAL(".html")) ||
195 path
.MatchesExtension(FILE_PATH_LITERAL(".shtm")) ||
196 path
.MatchesExtension(FILE_PATH_LITERAL(".shtml")) ||
197 path
.MatchesExtension(FILE_PATH_LITERAL(".svg")) ||
198 path
.MatchesExtension(FILE_PATH_LITERAL(".xht")) ||
199 path
.MatchesExtension(FILE_PATH_LITERAL(".xhtm")) ||
200 path
.MatchesExtension(FILE_PATH_LITERAL(".xhtml")) ||
201 path
.MatchesExtension(FILE_PATH_LITERAL(".xsl")) ||
202 path
.MatchesExtension(FILE_PATH_LITERAL(".xslt"))) {
211 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile
* profile
)
213 next_download_id_(content::DownloadItem::kInvalidId
),
214 download_prefs_(new DownloadPrefs(profile
)),
215 weak_ptr_factory_(this) {
218 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {
219 // If a DownloadManager was set for this, Shutdown() must be called.
220 DCHECK(!download_manager_
);
223 void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager
* dm
) {
224 download_manager_
= dm
;
227 void ChromeDownloadManagerDelegate::Shutdown() {
228 download_prefs_
.reset();
229 weak_ptr_factory_
.InvalidateWeakPtrs();
230 download_manager_
= NULL
;
233 content::DownloadIdCallback
234 ChromeDownloadManagerDelegate::GetDownloadIdReceiverCallback() {
235 return base::Bind(&ChromeDownloadManagerDelegate::SetNextId
,
236 weak_ptr_factory_
.GetWeakPtr());
239 void ChromeDownloadManagerDelegate::SetNextId(uint32 next_id
) {
240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
241 DCHECK(!profile_
->IsOffTheRecord());
242 DCHECK_NE(content::DownloadItem::kInvalidId
, next_id
);
243 next_download_id_
= next_id
;
245 IdCallbackVector callbacks
;
246 id_callbacks_
.swap(callbacks
);
247 for (IdCallbackVector::const_iterator it
= callbacks
.begin();
248 it
!= callbacks
.end(); ++it
) {
253 void ChromeDownloadManagerDelegate::GetNextId(
254 const content::DownloadIdCallback
& callback
) {
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
256 if (profile_
->IsOffTheRecord()) {
257 content::BrowserContext::GetDownloadManager(
258 profile_
->GetOriginalProfile())->GetDelegate()->GetNextId(callback
);
261 if (next_download_id_
== content::DownloadItem::kInvalidId
) {
262 id_callbacks_
.push_back(callback
);
265 ReturnNextId(callback
);
268 void ChromeDownloadManagerDelegate::ReturnNextId(
269 const content::DownloadIdCallback
& callback
) {
270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
271 DCHECK(!profile_
->IsOffTheRecord());
272 DCHECK_NE(content::DownloadItem::kInvalidId
, next_download_id_
);
273 callback
.Run(next_download_id_
++);
276 bool ChromeDownloadManagerDelegate::DetermineDownloadTarget(
277 DownloadItem
* download
,
278 const content::DownloadTargetCallback
& callback
) {
279 DownloadTargetDeterminer::CompletionCallback target_determined_callback
=
280 base::Bind(&ChromeDownloadManagerDelegate::OnDownloadTargetDetermined
,
281 weak_ptr_factory_
.GetWeakPtr(),
284 DownloadTargetDeterminer::Start(
286 GetPlatformDownloadPath(profile_
, download
, PLATFORM_TARGET_PATH
),
287 download_prefs_
.get(),
289 target_determined_callback
);
293 bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension(
294 const base::FilePath
& path
) {
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
296 if (path
.Extension().empty())
298 // TODO(asanka): This determination is done based on |path|, while
299 // ShouldOpenDownload() detects extension downloads based on the
300 // characteristics of the download. Reconcile this. http://crbug.com/167702
301 if (path
.MatchesExtension(extensions::kExtensionFileExtension
))
303 return download_prefs_
->IsAutoOpenEnabledBasedOnExtension(path
);
307 void ChromeDownloadManagerDelegate::DisableSafeBrowsing(DownloadItem
* item
) {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
309 #if defined(FULL_SAFE_BROWSING)
310 SafeBrowsingState
* state
= static_cast<SafeBrowsingState
*>(
311 item
->GetUserData(&kSafeBrowsingUserDataKey
));
313 state
= new SafeBrowsingState();
314 item
->SetUserData(&kSafeBrowsingUserDataKey
, state
);
316 state
->SetVerdict(DownloadProtectionService::SAFE
);
320 bool ChromeDownloadManagerDelegate::IsDownloadReadyForCompletion(
322 const base::Closure
& internal_complete_callback
) {
323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
324 #if defined(FULL_SAFE_BROWSING)
325 SafeBrowsingState
* state
= static_cast<SafeBrowsingState
*>(
326 item
->GetUserData(&kSafeBrowsingUserDataKey
));
328 // Begin the safe browsing download protection check.
329 DownloadProtectionService
* service
= GetDownloadProtectionService();
331 VLOG(2) << __FUNCTION__
<< "() Start SB download check for download = "
332 << item
->DebugString(false);
333 state
= new SafeBrowsingState();
334 state
->set_callback(internal_complete_callback
);
335 item
->SetUserData(&kSafeBrowsingUserDataKey
, state
);
336 service
->CheckClientDownload(
339 &ChromeDownloadManagerDelegate::CheckClientDownloadDone
,
340 weak_ptr_factory_
.GetWeakPtr(),
344 } else if (!state
->is_complete()) {
345 // Don't complete the download until we have an answer.
346 state
->set_callback(internal_complete_callback
);
353 void ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal(
355 const base::Closure
& user_complete_callback
) {
356 DownloadItem
* item
= download_manager_
->GetDownload(download_id
);
359 if (ShouldCompleteDownload(item
, user_complete_callback
))
360 user_complete_callback
.Run();
363 bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(
365 const base::Closure
& user_complete_callback
) {
366 return IsDownloadReadyForCompletion(item
, base::Bind(
367 &ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal
,
368 weak_ptr_factory_
.GetWeakPtr(), item
->GetId(), user_complete_callback
));
371 bool ChromeDownloadManagerDelegate::ShouldOpenDownload(
372 DownloadItem
* item
, const content::DownloadOpenDelayedCallback
& callback
) {
373 if (download_crx_util::IsExtensionDownload(*item
) &&
374 !extensions::WebstoreInstaller::GetAssociatedApproval(*item
)) {
375 scoped_refptr
<extensions::CrxInstaller
> crx_installer
=
376 download_crx_util::OpenChromeExtension(profile_
, *item
);
378 // CRX_INSTALLER_DONE will fire when the install completes. At that
379 // time, Observe() will call the passed callback.
382 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
383 content::Source
<extensions::CrxInstaller
>(crx_installer
.get()));
385 crx_installers_
[crx_installer
.get()] = callback
;
386 // The status text and percent complete indicator will change now
387 // that we are installing a CRX. Update observers so that they pick
389 item
->UpdateObservers();
396 bool ChromeDownloadManagerDelegate::GenerateFileHash() {
397 #if defined(FULL_SAFE_BROWSING)
398 return profile_
->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled
) &&
399 g_browser_process
->safe_browsing_service()->DownloadBinHashNeeded();
405 void ChromeDownloadManagerDelegate::GetSaveDir(
406 content::BrowserContext
* browser_context
,
407 base::FilePath
* website_save_dir
,
408 base::FilePath
* download_save_dir
,
409 bool* skip_dir_check
) {
410 *website_save_dir
= download_prefs_
->SaveFilePath();
411 DCHECK(!website_save_dir
->empty());
412 *download_save_dir
= download_prefs_
->DownloadPath();
413 *skip_dir_check
= false;
414 #if defined(OS_CHROMEOS)
415 *skip_dir_check
= drive::util::IsUnderDriveMountPoint(*website_save_dir
);
419 void ChromeDownloadManagerDelegate::ChooseSavePath(
420 content::WebContents
* web_contents
,
421 const base::FilePath
& suggested_path
,
422 const base::FilePath::StringType
& default_extension
,
423 bool can_save_as_complete
,
424 const content::SavePackagePathPickedCallback
& callback
) {
426 new SavePackageFilePicker(
430 can_save_as_complete
,
431 download_prefs_
.get(),
435 void ChromeDownloadManagerDelegate::OpenDownloadUsingPlatformHandler(
436 DownloadItem
* download
) {
437 base::FilePath
platform_path(
438 GetPlatformDownloadPath(profile_
, download
, PLATFORM_TARGET_PATH
));
439 DCHECK(!platform_path
.empty());
440 platform_util::OpenItem(profile_
, platform_path
);
443 void ChromeDownloadManagerDelegate::OpenDownload(DownloadItem
* download
) {
444 DCHECK_EQ(DownloadItem::COMPLETE
, download
->GetState());
445 DCHECK(!download
->GetTargetFilePath().empty());
446 if (!download
->CanOpenDownload())
449 if (!DownloadItemModel(download
).ShouldPreferOpeningInBrowser()) {
450 RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_PLATFORM
);
451 OpenDownloadUsingPlatformHandler(download
);
455 #if !defined(OS_ANDROID)
456 content::WebContents
* web_contents
= download
->GetWebContents();
458 web_contents
? chrome::FindBrowserWithWebContents(web_contents
) : NULL
;
459 scoped_ptr
<chrome::ScopedTabbedBrowserDisplayer
> browser_displayer
;
461 !browser
->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP
)) {
462 browser_displayer
.reset(new chrome::ScopedTabbedBrowserDisplayer(
463 profile_
, chrome::GetActiveDesktop()));
464 browser
= browser_displayer
->browser();
466 content::OpenURLParams
params(
467 net::FilePathToFileURL(download
->GetTargetFilePath()),
470 content::PAGE_TRANSITION_LINK
,
472 browser
->OpenURL(params
);
473 RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER
);
475 // ShouldPreferOpeningInBrowser() should never be true on Android.
480 void ChromeDownloadManagerDelegate::ShowDownloadInShell(
481 DownloadItem
* download
) {
482 if (!download
->CanShowInFolder())
484 base::FilePath
platform_path(
485 GetPlatformDownloadPath(profile_
, download
, PLATFORM_CURRENT_PATH
));
486 DCHECK(!platform_path
.empty());
487 platform_util::ShowItemInFolder(profile_
, platform_path
);
490 void ChromeDownloadManagerDelegate::CheckForFileExistence(
491 DownloadItem
* download
,
492 const content::CheckForFileExistenceCallback
& callback
) {
493 #if defined(OS_CHROMEOS)
494 drive::DownloadHandler
* drive_download_handler
=
495 drive::DownloadHandler::GetForProfile(profile_
);
496 if (drive_download_handler
&&
497 drive_download_handler
->IsDriveDownload(download
)) {
498 drive_download_handler
->CheckForFileExistence(download
, callback
);
502 static const char kSequenceToken
[] = "ChromeDMD-FileExistenceChecker";
503 base::SequencedWorkerPool
* worker_pool
= BrowserThread::GetBlockingPool();
504 scoped_refptr
<base::SequencedTaskRunner
> task_runner
=
505 worker_pool
->GetSequencedTaskRunnerWithShutdownBehavior(
506 worker_pool
->GetNamedSequenceToken(kSequenceToken
),
507 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
);
508 base::PostTaskAndReplyWithResult(
511 base::Bind(&base::PathExists
, download
->GetTargetFilePath()),
516 ChromeDownloadManagerDelegate::ApplicationClientIdForFileScanning() const {
517 return std::string(chrome::kApplicationClientIDStringForAVScanning
);
520 DownloadProtectionService
*
521 ChromeDownloadManagerDelegate::GetDownloadProtectionService() {
522 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
523 #if defined(FULL_SAFE_BROWSING)
524 SafeBrowsingService
* sb_service
= g_browser_process
->safe_browsing_service();
525 if (sb_service
&& sb_service
->download_protection_service() &&
526 profile_
->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled
)) {
527 return sb_service
->download_protection_service();
533 void ChromeDownloadManagerDelegate::NotifyExtensions(
534 DownloadItem
* download
,
535 const base::FilePath
& virtual_path
,
536 const NotifyExtensionsCallback
& callback
) {
537 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
538 #if !defined(OS_ANDROID)
539 extensions::ExtensionDownloadsEventRouter
* router
=
540 DownloadServiceFactory::GetForBrowserContext(profile_
)
541 ->GetExtensionEventRouter();
543 base::Closure original_path_callback
=
544 base::Bind(callback
, base::FilePath(),
545 DownloadPathReservationTracker::UNIQUIFY
);
546 router
->OnDeterminingFilename(download
, virtual_path
.BaseName(),
547 original_path_callback
,
552 callback
.Run(base::FilePath(), DownloadPathReservationTracker::UNIQUIFY
);
555 void ChromeDownloadManagerDelegate::ReserveVirtualPath(
556 content::DownloadItem
* download
,
557 const base::FilePath
& virtual_path
,
558 bool create_directory
,
559 DownloadPathReservationTracker::FilenameConflictAction conflict_action
,
560 const DownloadTargetDeterminerDelegate::ReservedPathCallback
& callback
) {
561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
562 DCHECK(!virtual_path
.empty());
563 #if defined(OS_CHROMEOS)
564 // TODO(asanka): Handle path reservations for virtual paths as well.
565 // http://crbug.com/151618
566 if (drive::util::IsUnderDriveMountPoint(virtual_path
)) {
567 callback
.Run(virtual_path
, true);
571 DownloadPathReservationTracker::GetReservedPath(
574 download_prefs_
->DownloadPath(),
580 void ChromeDownloadManagerDelegate::PromptUserForDownloadPath(
581 DownloadItem
* download
,
582 const base::FilePath
& suggested_path
,
583 const DownloadTargetDeterminerDelegate::FileSelectedCallback
& callback
) {
584 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
585 DownloadFilePicker::ShowFilePicker(download
, suggested_path
, callback
);
588 void ChromeDownloadManagerDelegate::DetermineLocalPath(
589 DownloadItem
* download
,
590 const base::FilePath
& virtual_path
,
591 const DownloadTargetDeterminerDelegate::LocalPathCallback
& callback
) {
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
593 #if defined(OS_CHROMEOS)
594 drive::DownloadHandler
* drive_download_handler
=
595 drive::DownloadHandler::GetForProfile(profile_
);
596 if (drive_download_handler
) {
597 drive_download_handler
->SubstituteDriveDownloadPath(
598 virtual_path
, download
, callback
);
602 callback
.Run(virtual_path
);
605 void ChromeDownloadManagerDelegate::CheckDownloadUrl(
606 DownloadItem
* download
,
607 const base::FilePath
& suggested_path
,
608 const CheckDownloadUrlCallback
& callback
) {
609 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
611 #if defined(FULL_SAFE_BROWSING)
612 safe_browsing::DownloadProtectionService
* service
=
613 GetDownloadProtectionService();
615 bool is_content_check_supported
=
616 service
->IsSupportedDownload(*download
, suggested_path
);
617 VLOG(2) << __FUNCTION__
<< "() Start SB URL check for download = "
618 << download
->DebugString(false);
619 service
->CheckDownloadUrl(*download
,
620 base::Bind(&CheckDownloadUrlDone
,
622 is_content_check_supported
));
626 callback
.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
);
629 void ChromeDownloadManagerDelegate::GetFileMimeType(
630 const base::FilePath
& path
,
631 const GetFileMimeTypeCallback
& callback
) {
632 BrowserThread::PostBlockingPoolTask(
634 base::Bind(&GetMimeTypeAndReplyOnUIThread
, path
, callback
));
637 #if defined(FULL_SAFE_BROWSING)
638 void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
640 DownloadProtectionService::DownloadCheckResult result
) {
641 DownloadItem
* item
= download_manager_
->GetDownload(download_id
);
642 if (!item
|| (item
->GetState() != DownloadItem::IN_PROGRESS
))
645 VLOG(2) << __FUNCTION__
<< "() download = " << item
->DebugString(false)
646 << " verdict = " << result
;
647 // We only mark the content as being dangerous if the download's safety state
648 // has not been set to DANGEROUS yet. We don't want to show two warnings.
649 if (item
->GetDangerType() == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
||
650 item
->GetDangerType() ==
651 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT
) {
652 content::DownloadDangerType danger_type
=
653 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
;
655 case DownloadProtectionService::SAFE
:
658 case DownloadProtectionService::DANGEROUS
:
659 danger_type
= content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
;
661 case DownloadProtectionService::UNCOMMON
:
662 danger_type
= content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT
;
664 case DownloadProtectionService::DANGEROUS_HOST
:
665 danger_type
= content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST
;
667 case DownloadProtectionService::POTENTIALLY_UNWANTED
:
668 danger_type
= content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED
;
672 if (danger_type
!= content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
)
673 item
->OnContentCheckCompleted(danger_type
);
676 SafeBrowsingState
* state
= static_cast<SafeBrowsingState
*>(
677 item
->GetUserData(&kSafeBrowsingUserDataKey
));
678 state
->SetVerdict(result
);
680 #endif // FULL_SAFE_BROWSING
682 // content::NotificationObserver implementation.
683 void ChromeDownloadManagerDelegate::Observe(
685 const content::NotificationSource
& source
,
686 const content::NotificationDetails
& details
) {
687 DCHECK(type
== chrome::NOTIFICATION_CRX_INSTALLER_DONE
);
689 registrar_
.Remove(this,
690 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
693 scoped_refptr
<extensions::CrxInstaller
> installer
=
694 content::Source
<extensions::CrxInstaller
>(source
).ptr();
695 content::DownloadOpenDelayedCallback callback
=
696 crx_installers_
[installer
.get()];
697 crx_installers_
.erase(installer
.get());
698 callback
.Run(installer
->did_handle_successfully());
701 void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined(
703 const content::DownloadTargetCallback
& callback
,
704 scoped_ptr
<DownloadTargetInfo
> target_info
) {
705 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
706 DownloadItem
* item
= download_manager_
->GetDownload(download_id
);
707 if (!target_info
->target_path
.empty() && item
&&
708 IsOpenInBrowserPreferreredForFile(target_info
->target_path
) &&
709 target_info
->is_filetype_handled_safely
)
710 DownloadItemModel(item
).SetShouldPreferOpeningInBrowser(true);
711 callback
.Run(target_info
->target_path
,
712 target_info
->target_disposition
,
713 target_info
->danger_type
,
714 target_info
->intermediate_path
);