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/platform_util.h"
39 #include "chrome/browser/profiles/profile.h"
40 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
41 #include "chrome/browser/ui/browser.h"
42 #include "chrome/browser/ui/browser_finder.h"
43 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
44 #include "chrome/common/chrome_constants.h"
45 #include "chrome/common/pref_names.h"
46 #include "components/user_prefs/pref_registry_syncable.h"
47 #include "content/public/browser/download_item.h"
48 #include "content/public/browser/download_manager.h"
49 #include "content/public/browser/notification_source.h"
50 #include "content/public/browser/page_navigator.h"
51 #include "extensions/common/constants.h"
52 #include "net/base/mime_util.h"
53 #include "net/base/net_util.h"
55 #if defined(OS_CHROMEOS)
56 #include "chrome/browser/chromeos/drive/download_handler.h"
57 #include "chrome/browser/chromeos/drive/file_system_util.h"
60 using content::BrowserThread
;
61 using content::DownloadItem
;
62 using content::DownloadManager
;
63 using safe_browsing::DownloadProtectionService
;
67 #if defined(FULL_SAFE_BROWSING)
69 // String pointer used for identifying safebrowing data associated with
71 const char kSafeBrowsingUserDataKey
[] = "Safe Browsing ID";
73 // The state of a safebrowsing check.
74 class SafeBrowsingState
: public DownloadCompletionBlocker
{
77 : verdict_(DownloadProtectionService::SAFE
) {
80 virtual ~SafeBrowsingState();
82 // The verdict that we got from calling CheckClientDownload. Only valid to
83 // call if |is_complete()|.
84 DownloadProtectionService::DownloadCheckResult
verdict() const {
88 void SetVerdict(DownloadProtectionService::DownloadCheckResult result
) {
94 DownloadProtectionService::DownloadCheckResult verdict_
;
96 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingState
);
99 SafeBrowsingState::~SafeBrowsingState() {}
101 #endif // FULL_SAFE_BROWSING
103 // Used with GetPlatformDownloadPath() to indicate which platform path to
105 enum PlatformDownloadPathType
{
106 // Return the platform specific target path.
107 PLATFORM_TARGET_PATH
,
109 // Return the platform specific current path. If the download is in-progress
110 // and the download location is a local filesystem path, then
111 // GetPlatformDownloadPath will return the path to the intermediate file.
112 PLATFORM_CURRENT_PATH
115 // Returns a path in the form that that is expected by platform_util::OpenItem /
116 // platform_util::ShowItemInFolder / DownloadTargetDeterminer.
118 // DownloadItems corresponding to Drive downloads use a temporary file as the
119 // target path. The paths returned by DownloadItem::GetFullPath() /
120 // GetTargetFilePath() refer to this temporary file. This function looks up the
121 // corresponding path in Drive for these downloads.
123 // How the platform path is determined is based on PlatformDownloadPathType.
124 base::FilePath
GetPlatformDownloadPath(Profile
* profile
,
125 const DownloadItem
* download
,
126 PlatformDownloadPathType path_type
) {
127 #if defined(OS_CHROMEOS)
128 // Drive downloads always return the target path for all types.
129 drive::DownloadHandler
* drive_download_handler
=
130 drive::DownloadHandler::GetForProfile(profile
);
131 if (drive_download_handler
&&
132 drive_download_handler
->IsDriveDownload(download
))
133 return drive_download_handler
->GetTargetPath(download
);
136 if (path_type
== PLATFORM_TARGET_PATH
)
137 return download
->GetTargetFilePath();
138 return download
->GetFullPath();
141 #if defined(FULL_SAFE_BROWSING)
142 // Callback invoked by DownloadProtectionService::CheckClientDownload.
143 // |is_content_check_supported| is true if the SB service supports scanning the
144 // download for malicious content.
145 // |callback| is invoked with a danger type determined as follows:
147 // Danger type is (in order of preference):
148 // * DANGEROUS_URL, if the URL is a known malware site.
149 // * MAYBE_DANGEROUS_CONTENT, if the content will be scanned for
150 // malware. I.e. |is_content_check_supported| is true.
152 void CheckDownloadUrlDone(
153 const DownloadTargetDeterminerDelegate::CheckDownloadUrlCallback
& callback
,
154 bool is_content_check_supported
,
155 DownloadProtectionService::DownloadCheckResult result
) {
156 content::DownloadDangerType danger_type
;
157 if (result
== DownloadProtectionService::SAFE
) {
158 // If this type of files is handled by the enhanced SafeBrowsing download
159 // protection, mark it as potentially dangerous content until we are done
161 if (is_content_check_supported
)
162 danger_type
= content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT
;
164 danger_type
= content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
;
166 // If the URL is malicious, we'll use that as the danger type. The results
167 // of the content check, if one is performed, will be ignored.
168 danger_type
= content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL
;
170 callback
.Run(danger_type
);
173 #endif // FULL_SAFE_BROWSING
175 // Called on the blocking pool to determine the MIME type for |path|.
176 void GetMimeTypeAndReplyOnUIThread(
177 const base::FilePath
& path
,
178 const base::Callback
<void(const std::string
&)>& callback
) {
179 std::string mime_type
;
180 net::GetMimeTypeFromFile(path
, &mime_type
);
181 BrowserThread::PostTask(
182 BrowserThread::UI
, FROM_HERE
, base::Bind(callback
, mime_type
));
185 bool IsOpenInBrowserPreferreredForFile(const base::FilePath
& path
) {
186 // On Android, always prefer opening with an external app. On ChromeOS, there
187 // are no external apps so just allow all opens to be handled by the "System."
188 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) && defined(ENABLE_PLUGINS)
189 // TODO(asanka): Consider other file types and MIME types.
190 // http://crbug.com/323561
191 if (path
.MatchesExtension(FILE_PATH_LITERAL(".pdf")) ||
192 path
.MatchesExtension(FILE_PATH_LITERAL(".htm")) ||
193 path
.MatchesExtension(FILE_PATH_LITERAL(".html")) ||
194 path
.MatchesExtension(FILE_PATH_LITERAL(".shtm")) ||
195 path
.MatchesExtension(FILE_PATH_LITERAL(".shtml")) ||
196 path
.MatchesExtension(FILE_PATH_LITERAL(".svg")) ||
197 path
.MatchesExtension(FILE_PATH_LITERAL(".xht")) ||
198 path
.MatchesExtension(FILE_PATH_LITERAL(".xhtm")) ||
199 path
.MatchesExtension(FILE_PATH_LITERAL(".xhtml")) ||
200 path
.MatchesExtension(FILE_PATH_LITERAL(".xml")) ||
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 scoped_refptr
<extensions::CrxInstaller
> crx_installer
=
375 download_crx_util::OpenChromeExtension(profile_
, *item
);
377 // CRX_INSTALLER_DONE will fire when the install completes. At that
378 // time, Observe() will call the passed callback.
381 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
382 content::Source
<extensions::CrxInstaller
>(crx_installer
.get()));
384 crx_installers_
[crx_installer
.get()] = callback
;
385 // The status text and percent complete indicator will change now
386 // that we are installing a CRX. Update observers so that they pick
388 item
->UpdateObservers();
395 bool ChromeDownloadManagerDelegate::GenerateFileHash() {
396 #if defined(FULL_SAFE_BROWSING)
397 return profile_
->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled
) &&
398 g_browser_process
->safe_browsing_service()->DownloadBinHashNeeded();
404 void ChromeDownloadManagerDelegate::GetSaveDir(
405 content::BrowserContext
* browser_context
,
406 base::FilePath
* website_save_dir
,
407 base::FilePath
* download_save_dir
,
408 bool* skip_dir_check
) {
409 *website_save_dir
= download_prefs_
->SaveFilePath();
410 DCHECK(!website_save_dir
->empty());
411 *download_save_dir
= download_prefs_
->DownloadPath();
412 *skip_dir_check
= false;
413 #if defined(OS_CHROMEOS)
414 *skip_dir_check
= drive::util::IsUnderDriveMountPoint(*website_save_dir
);
418 void ChromeDownloadManagerDelegate::ChooseSavePath(
419 content::WebContents
* web_contents
,
420 const base::FilePath
& suggested_path
,
421 const base::FilePath::StringType
& default_extension
,
422 bool can_save_as_complete
,
423 const content::SavePackagePathPickedCallback
& callback
) {
425 new SavePackageFilePicker(
429 can_save_as_complete
,
430 download_prefs_
.get(),
434 void ChromeDownloadManagerDelegate::OpenDownloadUsingPlatformHandler(
435 DownloadItem
* download
) {
436 base::FilePath
platform_path(
437 GetPlatformDownloadPath(profile_
, download
, PLATFORM_TARGET_PATH
));
438 DCHECK(!platform_path
.empty());
439 platform_util::OpenItem(profile_
, platform_path
);
442 void ChromeDownloadManagerDelegate::OpenDownload(DownloadItem
* download
) {
443 DCHECK_EQ(DownloadItem::COMPLETE
, download
->GetState());
444 DCHECK(!download
->GetTargetFilePath().empty());
445 if (!download
->CanOpenDownload())
448 if (!DownloadItemModel(download
).ShouldPreferOpeningInBrowser()) {
449 RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_PLATFORM
);
450 OpenDownloadUsingPlatformHandler(download
);
454 #if !defined(OS_ANDROID)
455 content::WebContents
* web_contents
= download
->GetWebContents();
457 web_contents
? chrome::FindBrowserWithWebContents(web_contents
) : NULL
;
458 scoped_ptr
<chrome::ScopedTabbedBrowserDisplayer
> browser_displayer
;
460 !browser
->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP
)) {
461 browser_displayer
.reset(new chrome::ScopedTabbedBrowserDisplayer(
462 profile_
, chrome::GetActiveDesktop()));
463 browser
= browser_displayer
->browser();
465 content::OpenURLParams
params(
466 net::FilePathToFileURL(download
->GetTargetFilePath()),
469 content::PAGE_TRANSITION_LINK
,
471 browser
->OpenURL(params
);
472 RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER
);
474 // ShouldPreferOpeningInBrowser() should never be true on Android.
479 void ChromeDownloadManagerDelegate::ShowDownloadInShell(
480 DownloadItem
* download
) {
481 if (!download
->CanShowInFolder())
483 base::FilePath
platform_path(
484 GetPlatformDownloadPath(profile_
, download
, PLATFORM_CURRENT_PATH
));
485 DCHECK(!platform_path
.empty());
486 platform_util::ShowItemInFolder(profile_
, platform_path
);
489 void ChromeDownloadManagerDelegate::CheckForFileExistence(
490 DownloadItem
* download
,
491 const content::CheckForFileExistenceCallback
& callback
) {
492 #if defined(OS_CHROMEOS)
493 drive::DownloadHandler
* drive_download_handler
=
494 drive::DownloadHandler::GetForProfile(profile_
);
495 if (drive_download_handler
&&
496 drive_download_handler
->IsDriveDownload(download
)) {
497 drive_download_handler
->CheckForFileExistence(download
, callback
);
501 static const char kSequenceToken
[] = "ChromeDMD-FileExistenceChecker";
502 base::SequencedWorkerPool
* worker_pool
= BrowserThread::GetBlockingPool();
503 scoped_refptr
<base::SequencedTaskRunner
> task_runner
=
504 worker_pool
->GetSequencedTaskRunnerWithShutdownBehavior(
505 worker_pool
->GetNamedSequenceToken(kSequenceToken
),
506 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
);
507 base::PostTaskAndReplyWithResult(
510 base::Bind(&base::PathExists
, download
->GetTargetFilePath()),
515 ChromeDownloadManagerDelegate::ApplicationClientIdForFileScanning() const {
516 return std::string(chrome::kApplicationClientIDStringForAVScanning
);
519 DownloadProtectionService
*
520 ChromeDownloadManagerDelegate::GetDownloadProtectionService() {
521 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
522 #if defined(FULL_SAFE_BROWSING)
523 SafeBrowsingService
* sb_service
= g_browser_process
->safe_browsing_service();
524 if (sb_service
&& sb_service
->download_protection_service() &&
525 profile_
->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled
)) {
526 return sb_service
->download_protection_service();
532 void ChromeDownloadManagerDelegate::NotifyExtensions(
533 DownloadItem
* download
,
534 const base::FilePath
& virtual_path
,
535 const NotifyExtensionsCallback
& callback
) {
536 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
537 #if !defined(OS_ANDROID)
538 ExtensionDownloadsEventRouter
* router
=
539 DownloadServiceFactory::GetForBrowserContext(profile_
)->
540 GetExtensionEventRouter();
542 base::Closure original_path_callback
=
543 base::Bind(callback
, base::FilePath(),
544 DownloadPathReservationTracker::UNIQUIFY
);
545 router
->OnDeterminingFilename(download
, virtual_path
.BaseName(),
546 original_path_callback
,
551 callback
.Run(base::FilePath(), DownloadPathReservationTracker::UNIQUIFY
);
554 void ChromeDownloadManagerDelegate::ReserveVirtualPath(
555 content::DownloadItem
* download
,
556 const base::FilePath
& virtual_path
,
557 bool create_directory
,
558 DownloadPathReservationTracker::FilenameConflictAction conflict_action
,
559 const DownloadTargetDeterminerDelegate::ReservedPathCallback
& callback
) {
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
561 DCHECK(!virtual_path
.empty());
562 #if defined(OS_CHROMEOS)
563 // TODO(asanka): Handle path reservations for virtual paths as well.
564 // http://crbug.com/151618
565 if (drive::util::IsUnderDriveMountPoint(virtual_path
)) {
566 callback
.Run(virtual_path
, true);
570 DownloadPathReservationTracker::GetReservedPath(
573 download_prefs_
->DownloadPath(),
579 void ChromeDownloadManagerDelegate::PromptUserForDownloadPath(
580 DownloadItem
* download
,
581 const base::FilePath
& suggested_path
,
582 const DownloadTargetDeterminerDelegate::FileSelectedCallback
& callback
) {
583 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
584 DownloadFilePicker::ShowFilePicker(download
, suggested_path
, callback
);
587 void ChromeDownloadManagerDelegate::DetermineLocalPath(
588 DownloadItem
* download
,
589 const base::FilePath
& virtual_path
,
590 const DownloadTargetDeterminerDelegate::LocalPathCallback
& callback
) {
591 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
592 #if defined(OS_CHROMEOS)
593 drive::DownloadHandler
* drive_download_handler
=
594 drive::DownloadHandler::GetForProfile(profile_
);
595 if (drive_download_handler
) {
596 drive_download_handler
->SubstituteDriveDownloadPath(
597 virtual_path
, download
, callback
);
601 callback
.Run(virtual_path
);
604 void ChromeDownloadManagerDelegate::CheckDownloadUrl(
605 DownloadItem
* download
,
606 const base::FilePath
& suggested_path
,
607 const CheckDownloadUrlCallback
& callback
) {
608 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
610 #if defined(FULL_SAFE_BROWSING)
611 safe_browsing::DownloadProtectionService
* service
=
612 GetDownloadProtectionService();
614 bool is_content_check_supported
=
615 service
->IsSupportedDownload(*download
, suggested_path
);
616 VLOG(2) << __FUNCTION__
<< "() Start SB URL check for download = "
617 << download
->DebugString(false);
618 service
->CheckDownloadUrl(*download
,
619 base::Bind(&CheckDownloadUrlDone
,
621 is_content_check_supported
));
625 callback
.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
);
628 void ChromeDownloadManagerDelegate::GetFileMimeType(
629 const base::FilePath
& path
,
630 const GetFileMimeTypeCallback
& callback
) {
631 BrowserThread::PostBlockingPoolTask(
633 base::Bind(&GetMimeTypeAndReplyOnUIThread
, path
, callback
));
636 #if defined(FULL_SAFE_BROWSING)
637 void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
639 DownloadProtectionService::DownloadCheckResult result
) {
640 DownloadItem
* item
= download_manager_
->GetDownload(download_id
);
641 if (!item
|| (item
->GetState() != DownloadItem::IN_PROGRESS
))
644 VLOG(2) << __FUNCTION__
<< "() download = " << item
->DebugString(false)
645 << " verdict = " << result
;
646 // We only mark the content as being dangerous if the download's safety state
647 // has not been set to DANGEROUS yet. We don't want to show two warnings.
648 if (item
->GetDangerType() == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
||
649 item
->GetDangerType() ==
650 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT
) {
651 content::DownloadDangerType danger_type
=
652 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
;
654 case DownloadProtectionService::SAFE
:
657 case DownloadProtectionService::DANGEROUS
:
658 danger_type
= content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
;
660 case DownloadProtectionService::UNCOMMON
:
661 danger_type
= content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT
;
663 case DownloadProtectionService::DANGEROUS_HOST
:
664 danger_type
= content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST
;
666 case DownloadProtectionService::POTENTIALLY_UNWANTED
:
667 danger_type
= content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED
;
671 if (danger_type
!= content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
)
672 item
->OnContentCheckCompleted(danger_type
);
675 SafeBrowsingState
* state
= static_cast<SafeBrowsingState
*>(
676 item
->GetUserData(&kSafeBrowsingUserDataKey
));
677 state
->SetVerdict(result
);
679 #endif // FULL_SAFE_BROWSING
681 // content::NotificationObserver implementation.
682 void ChromeDownloadManagerDelegate::Observe(
684 const content::NotificationSource
& source
,
685 const content::NotificationDetails
& details
) {
686 DCHECK(type
== chrome::NOTIFICATION_CRX_INSTALLER_DONE
);
688 registrar_
.Remove(this,
689 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
692 scoped_refptr
<extensions::CrxInstaller
> installer
=
693 content::Source
<extensions::CrxInstaller
>(source
).ptr();
694 content::DownloadOpenDelayedCallback callback
=
695 crx_installers_
[installer
.get()];
696 crx_installers_
.erase(installer
.get());
697 callback
.Run(installer
->did_handle_successfully());
700 void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined(
702 const content::DownloadTargetCallback
& callback
,
703 scoped_ptr
<DownloadTargetInfo
> target_info
) {
704 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
705 DownloadItem
* item
= download_manager_
->GetDownload(download_id
);
706 if (!target_info
->target_path
.empty() && item
&&
707 IsOpenInBrowserPreferreredForFile(target_info
->target_path
) &&
708 target_info
->is_filetype_handled_safely
)
709 DownloadItemModel(item
).SetShouldPreferOpeningInBrowser(true);
710 callback
.Run(target_info
->target_path
,
711 target_info
->target_disposition
,
712 target_info
->danger_type
,
713 target_info
->intermediate_path
);