Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / download / chrome_download_manager_delegate.cc
blob114277fb3fefd6c40f2f803067e0d1b4bb4abb23
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"
7 #include <string>
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"
59 #endif
61 using content::BrowserThread;
62 using content::DownloadItem;
63 using content::DownloadManager;
64 using safe_browsing::DownloadProtectionService;
66 namespace {
68 #if defined(FULL_SAFE_BROWSING)
70 // String pointer used for identifying safebrowing data associated with
71 // a download item.
72 const char kSafeBrowsingUserDataKey[] = "Safe Browsing ID";
74 // The state of a safebrowsing check.
75 class SafeBrowsingState : public DownloadCompletionBlocker {
76 public:
77 SafeBrowsingState()
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 {
86 return verdict_;
89 void SetVerdict(DownloadProtectionService::DownloadCheckResult result) {
90 verdict_ = result;
91 CompleteDownload();
94 private:
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
105 // return.
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);
135 #endif
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.
152 // * NOT_DANGEROUS.
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
161 // with scanning it.
162 if (is_content_check_supported)
163 danger_type = content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
164 else
165 danger_type = content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
166 } else {
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"))) {
203 return true;
205 #endif
206 return false;
209 } // namespace
211 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
212 : 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) {
249 ReturnNextId(*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);
259 return;
261 if (next_download_id_ == content::DownloadItem::kInvalidId) {
262 id_callbacks_.push_back(callback);
263 return;
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(),
282 download->GetId(),
283 callback);
284 DownloadTargetDeterminer::Start(
285 download,
286 GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH),
287 download_prefs_.get(),
288 this,
289 target_determined_callback);
290 return true;
293 bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension(
294 const base::FilePath& path) {
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
296 if (path.Extension().empty())
297 return false;
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))
302 return false;
303 return download_prefs_->IsAutoOpenEnabledBasedOnExtension(path);
306 // static
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));
312 if (!state) {
313 state = new SafeBrowsingState();
314 item->SetUserData(&kSafeBrowsingUserDataKey, state);
316 state->SetVerdict(DownloadProtectionService::SAFE);
317 #endif
320 bool ChromeDownloadManagerDelegate::IsDownloadReadyForCompletion(
321 DownloadItem* item,
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));
327 if (!state) {
328 // Begin the safe browsing download protection check.
329 DownloadProtectionService* service = GetDownloadProtectionService();
330 if (service) {
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(
337 item,
338 base::Bind(
339 &ChromeDownloadManagerDelegate::CheckClientDownloadDone,
340 weak_ptr_factory_.GetWeakPtr(),
341 item->GetId()));
342 return false;
344 } else if (!state->is_complete()) {
345 // Don't complete the download until we have an answer.
346 state->set_callback(internal_complete_callback);
347 return false;
349 #endif
350 return true;
353 void ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal(
354 uint32 download_id,
355 const base::Closure& user_complete_callback) {
356 DownloadItem* item = download_manager_->GetDownload(download_id);
357 if (!item)
358 return;
359 if (ShouldCompleteDownload(item, user_complete_callback))
360 user_complete_callback.Run();
363 bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(
364 DownloadItem* item,
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.
380 registrar_.Add(
381 this,
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
388 // up the change.
389 item->UpdateObservers();
390 return false;
393 return true;
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();
400 #else
401 return false;
402 #endif
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);
416 #endif
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) {
425 // Deletes itself.
426 new SavePackageFilePicker(
427 web_contents,
428 suggested_path,
429 default_extension,
430 can_save_as_complete,
431 download_prefs_.get(),
432 callback);
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())
447 return;
449 if (!DownloadItemModel(download).ShouldPreferOpeningInBrowser()) {
450 RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_PLATFORM);
451 OpenDownloadUsingPlatformHandler(download);
452 return;
455 #if !defined(OS_ANDROID)
456 content::WebContents* web_contents = download->GetWebContents();
457 Browser* browser =
458 web_contents ? chrome::FindBrowserWithWebContents(web_contents) : NULL;
459 scoped_ptr<chrome::ScopedTabbedBrowserDisplayer> browser_displayer;
460 if (!browser ||
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()),
468 content::Referrer(),
469 NEW_FOREGROUND_TAB,
470 content::PAGE_TRANSITION_LINK,
471 false);
472 browser->OpenURL(params);
473 RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER);
474 #else
475 // ShouldPreferOpeningInBrowser() should never be true on Android.
476 NOTREACHED();
477 #endif
480 void ChromeDownloadManagerDelegate::ShowDownloadInShell(
481 DownloadItem* download) {
482 if (!download->CanShowInFolder())
483 return;
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);
499 return;
501 #endif
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(
509 task_runner.get(),
510 FROM_HERE,
511 base::Bind(&base::PathExists, download->GetTargetFilePath()),
512 callback);
515 std::string
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();
529 #endif
530 return NULL;
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();
542 if (router) {
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,
548 callback);
549 return;
551 #endif
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);
568 return;
570 #endif
571 DownloadPathReservationTracker::GetReservedPath(
572 download,
573 virtual_path,
574 download_prefs_->DownloadPath(),
575 create_directory,
576 conflict_action,
577 callback);
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);
599 return;
601 #endif
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();
614 if (service) {
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,
621 callback,
622 is_content_check_supported));
623 return;
625 #endif
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(
633 FROM_HERE,
634 base::Bind(&GetMimeTypeAndReplyOnUIThread, path, callback));
637 #if defined(FULL_SAFE_BROWSING)
638 void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
639 uint32 download_id,
640 DownloadProtectionService::DownloadCheckResult result) {
641 DownloadItem* item = download_manager_->GetDownload(download_id);
642 if (!item || (item->GetState() != DownloadItem::IN_PROGRESS))
643 return;
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;
654 switch (result) {
655 case DownloadProtectionService::SAFE:
656 // Do nothing.
657 break;
658 case DownloadProtectionService::DANGEROUS:
659 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT;
660 break;
661 case DownloadProtectionService::UNCOMMON:
662 danger_type = content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT;
663 break;
664 case DownloadProtectionService::DANGEROUS_HOST:
665 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST;
666 break;
667 case DownloadProtectionService::POTENTIALLY_UNWANTED:
668 danger_type = content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED;
669 break;
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(
684 int type,
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,
691 source);
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(
702 int32 download_id,
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);