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

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

Powered by Google App Engine
This is Rietveld 408576698