Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: chrome/browser/download/chrome_download_manager_delegate.cc

Issue 55063002: Prefer opening PDF downloads in the browser. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Destroy PluginService once we are done with our plugin tests. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/basictypes.h"
9 #include "base/bind.h" 10 #include "base/bind.h"
10 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
11 #include "base/callback.h" 12 #include "base/callback.h"
12 #include "base/file_util.h" 13 #include "base/file_util.h"
13 #include "base/prefs/pref_member.h" 14 #include "base/prefs/pref_member.h"
14 #include "base/prefs/pref_service.h" 15 #include "base/prefs/pref_service.h"
15 #include "base/rand_util.h" 16 #include "base/rand_util.h"
16 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
18 #include "base/time/time.h" 19 #include "base/time/time.h"
19 #include "chrome/browser/browser_process.h" 20 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/chrome_notification_types.h" 21 #include "chrome/browser/chrome_notification_types.h"
21 #include "chrome/browser/download/download_completion_blocker.h" 22 #include "chrome/browser/download/download_completion_blocker.h"
22 #include "chrome/browser/download/download_crx_util.h" 23 #include "chrome/browser/download/download_crx_util.h"
23 #include "chrome/browser/download/download_file_picker.h" 24 #include "chrome/browser/download/download_file_picker.h"
24 #include "chrome/browser/download/download_history.h" 25 #include "chrome/browser/download/download_history.h"
26 #include "chrome/browser/download/download_item_model.h"
25 #include "chrome/browser/download/download_path_reservation_tracker.h" 27 #include "chrome/browser/download/download_path_reservation_tracker.h"
26 #include "chrome/browser/download/download_prefs.h" 28 #include "chrome/browser/download/download_prefs.h"
27 #include "chrome/browser/download/download_service.h" 29 #include "chrome/browser/download/download_service.h"
28 #include "chrome/browser/download/download_service_factory.h" 30 #include "chrome/browser/download/download_service_factory.h"
31 #include "chrome/browser/download/download_stats.h"
29 #include "chrome/browser/download/download_target_determiner.h" 32 #include "chrome/browser/download/download_target_determiner.h"
30 #include "chrome/browser/download/save_package_file_picker.h" 33 #include "chrome/browser/download/save_package_file_picker.h"
31 #include "chrome/browser/extensions/api/downloads/downloads_api.h" 34 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
32 #include "chrome/browser/extensions/crx_installer.h" 35 #include "chrome/browser/extensions/crx_installer.h"
33 #include "chrome/browser/platform_util.h" 36 #include "chrome/browser/platform_util.h"
34 #include "chrome/browser/profiles/profile.h" 37 #include "chrome/browser/profiles/profile.h"
35 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 38 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
39 #include "chrome/browser/ui/browser.h"
40 #include "chrome/browser/ui/browser_finder.h"
41 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
36 #include "chrome/common/chrome_constants.h" 42 #include "chrome/common/chrome_constants.h"
37 #include "chrome/common/pref_names.h" 43 #include "chrome/common/pref_names.h"
38 #include "components/user_prefs/pref_registry_syncable.h" 44 #include "components/user_prefs/pref_registry_syncable.h"
39 #include "content/public/browser/download_item.h" 45 #include "content/public/browser/download_item.h"
40 #include "content/public/browser/download_manager.h" 46 #include "content/public/browser/download_manager.h"
41 #include "content/public/browser/notification_source.h" 47 #include "content/public/browser/notification_source.h"
48 #include "content/public/browser/page_navigator.h"
42 #include "extensions/common/constants.h" 49 #include "extensions/common/constants.h"
50 #include "net/base/mime_util.h"
51 #include "net/base/net_util.h"
43 52
44 #if defined(OS_CHROMEOS) 53 #if defined(OS_CHROMEOS)
45 #include "chrome/browser/chromeos/drive/download_handler.h" 54 #include "chrome/browser/chromeos/drive/download_handler.h"
46 #include "chrome/browser/chromeos/drive/file_system_util.h" 55 #include "chrome/browser/chromeos/drive/file_system_util.h"
47 #endif 56 #endif
48 57
49 using content::BrowserThread; 58 using content::BrowserThread;
50 using content::DownloadItem; 59 using content::DownloadItem;
51 using content::DownloadManager; 60 using content::DownloadManager;
52 using safe_browsing::DownloadProtectionService; 61 using safe_browsing::DownloadProtectionService;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 } else { 163 } else {
155 // If the URL is malicious, we'll use that as the danger type. The results 164 // If the URL is malicious, we'll use that as the danger type. The results
156 // of the content check, if one is performed, will be ignored. 165 // of the content check, if one is performed, will be ignored.
157 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; 166 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL;
158 } 167 }
159 callback.Run(danger_type); 168 callback.Run(danger_type);
160 } 169 }
161 170
162 #endif // FULL_SAFE_BROWSING 171 #endif // FULL_SAFE_BROWSING
163 172
173 // Called on the blocking pool to determine the MIME type for |path|.
174 void GetMimeTypeAndReplyOnUIThread(
175 const base::FilePath& path,
176 const base::Callback<void(const std::string&)>& callback) {
177 std::string mime_type;
178 net::GetMimeTypeFromFile(path, &mime_type);
179 BrowserThread::PostTask(
180 BrowserThread::UI, FROM_HERE, base::Bind(callback, mime_type));
181 }
182
183 bool IsOpenInBrowserPreferreredForFile(const base::FilePath& path) {
184 // On Android, always prefer opening with an external app.
185 #if !defined(OS_ANDROID) && defined(ENABLE_PLUGINS)
186 // TODO(asanka): Consider other file types and MIME types.
187 if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf")))
188 return true;
189 #endif
190 return false;
191 }
192
164 } // namespace 193 } // namespace
165 194
166 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile) 195 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
167 : profile_(profile), 196 : profile_(profile),
168 next_download_id_(content::DownloadItem::kInvalidId), 197 next_download_id_(content::DownloadItem::kInvalidId),
169 download_prefs_(new DownloadPrefs(profile)) { 198 download_prefs_(new DownloadPrefs(profile)) {
170 } 199 }
171 200
172 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { 201 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {
173 } 202 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 const content::DownloadIdCallback& callback) { 242 const content::DownloadIdCallback& callback) {
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
215 DCHECK(!profile_->IsOffTheRecord()); 244 DCHECK(!profile_->IsOffTheRecord());
216 DCHECK_NE(content::DownloadItem::kInvalidId, next_download_id_); 245 DCHECK_NE(content::DownloadItem::kInvalidId, next_download_id_);
217 callback.Run(next_download_id_++); 246 callback.Run(next_download_id_++);
218 } 247 }
219 248
220 bool ChromeDownloadManagerDelegate::DetermineDownloadTarget( 249 bool ChromeDownloadManagerDelegate::DetermineDownloadTarget(
221 DownloadItem* download, 250 DownloadItem* download,
222 const content::DownloadTargetCallback& callback) { 251 const content::DownloadTargetCallback& callback) {
252 DownloadTargetDeterminer::CompletionCallback target_determined_callback =
253 base::Bind(&ChromeDownloadManagerDelegate::OnDownloadTargetDetermined,
254 this,
255 download->GetId(),
256 callback);
223 DownloadTargetDeterminer::Start( 257 DownloadTargetDeterminer::Start(
224 download, 258 download,
225 GetPlatformDownloadPath( 259 GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH),
226 profile_, download, PLATFORM_TARGET_PATH),
227 download_prefs_.get(), 260 download_prefs_.get(),
228 this, 261 this,
229 callback); 262 target_determined_callback);
230 return true; 263 return true;
231 } 264 }
232 265
233 bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension( 266 bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension(
234 const base::FilePath& path) { 267 const base::FilePath& path) {
235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
236 if (path.Extension().empty()) 269 if (path.Extension().empty())
237 return false; 270 return false;
238 // TODO(asanka): This determination is done based on |path|, while 271 // TODO(asanka): This determination is done based on |path|, while
239 // ShouldOpenDownload() detects extension downloads based on the 272 // ShouldOpenDownload() detects extension downloads based on the
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 // Deletes itself. 397 // Deletes itself.
365 new SavePackageFilePicker( 398 new SavePackageFilePicker(
366 web_contents, 399 web_contents,
367 suggested_path, 400 suggested_path,
368 default_extension, 401 default_extension,
369 can_save_as_complete, 402 can_save_as_complete,
370 download_prefs_.get(), 403 download_prefs_.get(),
371 callback); 404 callback);
372 } 405 }
373 406
374 void ChromeDownloadManagerDelegate::OpenDownload(DownloadItem* download) { 407 void ChromeDownloadManagerDelegate::OpenDownloadUsingPlatformHandler(
375 DCHECK_EQ(DownloadItem::COMPLETE, download->GetState()); 408 DownloadItem* download) {
376 if (!download->CanOpenDownload())
377 return;
378 base::FilePath platform_path( 409 base::FilePath platform_path(
379 GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH)); 410 GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH));
380 DCHECK(!platform_path.empty()); 411 DCHECK(!platform_path.empty());
381 platform_util::OpenItem(platform_path); 412 platform_util::OpenItem(platform_path);
382 } 413 }
383 414
415 void ChromeDownloadManagerDelegate::OpenDownload(DownloadItem* download) {
416 DCHECK_EQ(DownloadItem::COMPLETE, download->GetState());
417 DCHECK(!download->GetTargetFilePath().empty());
418 if (!download->CanOpenDownload())
419 return;
420
421 if (!DownloadItemModel(download).ShouldPreferOpeningInBrowser()) {
422 RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_PLATFORM);
423 OpenDownloadUsingPlatformHandler(download);
424 return;
425 }
426
427 #if !defined(OS_ANDROID)
428 content::WebContents* web_contents = download->GetWebContents();
429 Browser* browser =
430 web_contents ? chrome::FindBrowserWithWebContents(web_contents) : NULL;
431 scoped_ptr<chrome::ScopedTabbedBrowserDisplayer> browser_displayer;
432 if (!browser ||
433 !browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
434 browser_displayer.reset(new chrome::ScopedTabbedBrowserDisplayer(
435 profile_, chrome::GetActiveDesktop()));
436 browser = browser_displayer->browser();
437 }
438 content::OpenURLParams params(
439 net::FilePathToFileURL(download->GetTargetFilePath()),
440 content::Referrer(),
441 NEW_FOREGROUND_TAB,
442 content::PAGE_TRANSITION_LINK,
443 false);
444 browser->OpenURL(params);
445 RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER);
446 #else
447 // ShouldPreferOpeningInBrowser() should never be true on Android.
448 NOTREACHED();
449 #endif
450 }
451
384 void ChromeDownloadManagerDelegate::ShowDownloadInShell( 452 void ChromeDownloadManagerDelegate::ShowDownloadInShell(
385 DownloadItem* download) { 453 DownloadItem* download) {
386 if (!download->CanShowInFolder()) 454 if (!download->CanShowInFolder())
387 return; 455 return;
388 base::FilePath platform_path( 456 base::FilePath platform_path(
389 GetPlatformDownloadPath(profile_, download, PLATFORM_CURRENT_PATH)); 457 GetPlatformDownloadPath(profile_, download, PLATFORM_CURRENT_PATH));
390 DCHECK(!platform_path.empty()); 458 DCHECK(!platform_path.empty());
391 platform_util::ShowItemInFolder(platform_path); 459 platform_util::ShowItemInFolder(platform_path);
392 } 460 }
393 461
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 service->CheckDownloadUrl(*download, 584 service->CheckDownloadUrl(*download,
517 base::Bind(&CheckDownloadUrlDone, 585 base::Bind(&CheckDownloadUrlDone,
518 callback, 586 callback,
519 is_content_check_supported)); 587 is_content_check_supported));
520 return; 588 return;
521 } 589 }
522 #endif 590 #endif
523 callback.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 591 callback.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
524 } 592 }
525 593
594 void ChromeDownloadManagerDelegate::GetFileMimeType(
595 const base::FilePath& path,
596 const GetFileMimeTypeCallback& callback) {
597 BrowserThread::PostBlockingPoolTask(
598 FROM_HERE,
599 base::Bind(&GetMimeTypeAndReplyOnUIThread, path, callback));
600 }
601
526 #if defined(FULL_SAFE_BROWSING) 602 #if defined(FULL_SAFE_BROWSING)
527 void ChromeDownloadManagerDelegate::CheckClientDownloadDone( 603 void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
528 uint32 download_id, 604 uint32 download_id,
529 DownloadProtectionService::DownloadCheckResult result) { 605 DownloadProtectionService::DownloadCheckResult result) {
530 DownloadItem* item = download_manager_->GetDownload(download_id); 606 DownloadItem* item = download_manager_->GetDownload(download_id);
531 if (!item || (item->GetState() != DownloadItem::IN_PROGRESS)) 607 if (!item || (item->GetState() != DownloadItem::IN_PROGRESS))
532 return; 608 return;
533 609
534 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false) 610 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false)
535 << " verdict = " << result; 611 << " verdict = " << result;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 655 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
580 source); 656 source);
581 657
582 scoped_refptr<extensions::CrxInstaller> installer = 658 scoped_refptr<extensions::CrxInstaller> installer =
583 content::Source<extensions::CrxInstaller>(source).ptr(); 659 content::Source<extensions::CrxInstaller>(source).ptr();
584 content::DownloadOpenDelayedCallback callback = 660 content::DownloadOpenDelayedCallback callback =
585 crx_installers_[installer.get()]; 661 crx_installers_[installer.get()];
586 crx_installers_.erase(installer.get()); 662 crx_installers_.erase(installer.get());
587 callback.Run(installer->did_handle_successfully()); 663 callback.Run(installer->did_handle_successfully());
588 } 664 }
665
666 void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined(
667 int32 download_id,
668 const content::DownloadTargetCallback& callback,
669 scoped_ptr<DownloadTargetInfo> target_info) {
670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
671 DownloadItem* item = download_manager_->GetDownload(download_id);
672 if (!target_info->target_path.empty() && item &&
673 IsOpenInBrowserPreferreredForFile(target_info->target_path) &&
674 target_info->is_filetype_handled_securely)
675 DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true);
676 callback.Run(target_info->target_path,
677 target_info->target_disposition,
678 target_info->danger_type,
679 target_info->intermediate_path);
680 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698