Index: chrome/browser/download/chrome_download_manager_delegate.cc |
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc |
index 0e32cdfae90f971ee66965a55f84482e2bc607dc..c562876bd1900d8a994f143367774bccd4e066f1 100644 |
--- a/chrome/browser/download/chrome_download_manager_delegate.cc |
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc |
@@ -6,6 +6,7 @@ |
#include <string> |
+#include "base/basictypes.h" |
#include "base/bind.h" |
#include "base/bind_helpers.h" |
#include "base/callback.h" |
@@ -22,10 +23,12 @@ |
#include "chrome/browser/download/download_crx_util.h" |
#include "chrome/browser/download/download_file_picker.h" |
#include "chrome/browser/download/download_history.h" |
+#include "chrome/browser/download/download_item_model.h" |
#include "chrome/browser/download/download_path_reservation_tracker.h" |
#include "chrome/browser/download/download_prefs.h" |
#include "chrome/browser/download/download_service.h" |
#include "chrome/browser/download/download_service_factory.h" |
+#include "chrome/browser/download/download_stats.h" |
#include "chrome/browser/download/download_target_determiner.h" |
#include "chrome/browser/download/save_package_file_picker.h" |
#include "chrome/browser/extensions/api/downloads/downloads_api.h" |
@@ -33,13 +36,19 @@ |
#include "chrome/browser/platform_util.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/safe_browsing/safe_browsing_service.h" |
+#include "chrome/browser/ui/browser.h" |
+#include "chrome/browser/ui/browser_finder.h" |
+#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" |
#include "chrome/common/chrome_constants.h" |
#include "chrome/common/pref_names.h" |
#include "components/user_prefs/pref_registry_syncable.h" |
#include "content/public/browser/download_item.h" |
#include "content/public/browser/download_manager.h" |
#include "content/public/browser/notification_source.h" |
+#include "content/public/browser/page_navigator.h" |
#include "extensions/common/constants.h" |
+#include "net/base/mime_util.h" |
+#include "net/base/net_util.h" |
#if defined(OS_CHROMEOS) |
#include "chrome/browser/chromeos/drive/download_handler.h" |
@@ -161,6 +170,26 @@ void CheckDownloadUrlDone( |
#endif // FULL_SAFE_BROWSING |
+// Called on the blocking pool to determine the MIME type for |path|. |
+void GetMimeTypeAndReplyOnUIThread( |
+ const base::FilePath& path, |
+ const base::Callback<void(const std::string&)>& callback) { |
+ std::string mime_type; |
+ net::GetMimeTypeFromFile(path, &mime_type); |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, base::Bind(callback, mime_type)); |
+} |
+ |
+bool IsOpenInBrowserPreferreredForFile(const base::FilePath& path) { |
+ // On Android, always prefer opening with an external app. |
+#if !defined(OS_ANDROID) && defined(ENABLE_PLUGINS) |
+ // TODO(asanka): Consider other file types and MIME types. |
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf"))) |
+ return true; |
+#endif |
+ return false; |
+} |
+ |
} // namespace |
ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile) |
@@ -220,13 +249,17 @@ void ChromeDownloadManagerDelegate::ReturnNextId( |
bool ChromeDownloadManagerDelegate::DetermineDownloadTarget( |
DownloadItem* download, |
const content::DownloadTargetCallback& callback) { |
+ DownloadTargetDeterminer::CompletionCallback target_determined_callback = |
+ base::Bind(&ChromeDownloadManagerDelegate::OnDownloadTargetDetermined, |
+ this, |
+ download->GetId(), |
+ callback); |
DownloadTargetDeterminer::Start( |
download, |
- GetPlatformDownloadPath( |
- profile_, download, PLATFORM_TARGET_PATH), |
+ GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH), |
download_prefs_.get(), |
this, |
- callback); |
+ target_determined_callback); |
return true; |
} |
@@ -371,16 +404,51 @@ void ChromeDownloadManagerDelegate::ChooseSavePath( |
callback); |
} |
-void ChromeDownloadManagerDelegate::OpenDownload(DownloadItem* download) { |
- DCHECK_EQ(DownloadItem::COMPLETE, download->GetState()); |
- if (!download->CanOpenDownload()) |
- return; |
+void ChromeDownloadManagerDelegate::OpenDownloadUsingPlatformHandler( |
+ DownloadItem* download) { |
base::FilePath platform_path( |
GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH)); |
DCHECK(!platform_path.empty()); |
platform_util::OpenItem(platform_path); |
} |
+void ChromeDownloadManagerDelegate::OpenDownload(DownloadItem* download) { |
+ DCHECK_EQ(DownloadItem::COMPLETE, download->GetState()); |
+ DCHECK(!download->GetTargetFilePath().empty()); |
+ if (!download->CanOpenDownload()) |
+ return; |
+ |
+ if (!DownloadItemModel(download).ShouldPreferOpeningInBrowser()) { |
+ RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_PLATFORM); |
+ OpenDownloadUsingPlatformHandler(download); |
+ return; |
+ } |
+ |
+#if !defined(OS_ANDROID) |
+ content::WebContents* web_contents = download->GetWebContents(); |
+ Browser* browser = |
+ web_contents ? chrome::FindBrowserWithWebContents(web_contents) : NULL; |
+ scoped_ptr<chrome::ScopedTabbedBrowserDisplayer> browser_displayer; |
+ if (!browser || |
+ !browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) { |
+ browser_displayer.reset(new chrome::ScopedTabbedBrowserDisplayer( |
+ profile_, chrome::GetActiveDesktop())); |
+ browser = browser_displayer->browser(); |
+ } |
+ content::OpenURLParams params( |
+ net::FilePathToFileURL(download->GetTargetFilePath()), |
+ content::Referrer(), |
+ NEW_FOREGROUND_TAB, |
+ content::PAGE_TRANSITION_LINK, |
+ false); |
+ browser->OpenURL(params); |
+ RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER); |
+#else |
+ // ShouldPreferOpeningInBrowser() should never be true on Android. |
+ NOTREACHED(); |
+#endif |
+} |
+ |
void ChromeDownloadManagerDelegate::ShowDownloadInShell( |
DownloadItem* download) { |
if (!download->CanShowInFolder()) |
@@ -523,6 +591,14 @@ void ChromeDownloadManagerDelegate::CheckDownloadUrl( |
callback.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
} |
+void ChromeDownloadManagerDelegate::GetFileMimeType( |
+ const base::FilePath& path, |
+ const GetFileMimeTypeCallback& callback) { |
+ BrowserThread::PostBlockingPoolTask( |
+ FROM_HERE, |
+ base::Bind(&GetMimeTypeAndReplyOnUIThread, path, callback)); |
+} |
+ |
#if defined(FULL_SAFE_BROWSING) |
void ChromeDownloadManagerDelegate::CheckClientDownloadDone( |
uint32 download_id, |
@@ -586,3 +662,19 @@ void ChromeDownloadManagerDelegate::Observe( |
crx_installers_.erase(installer.get()); |
callback.Run(installer->did_handle_successfully()); |
} |
+ |
+void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined( |
+ int32 download_id, |
+ const content::DownloadTargetCallback& callback, |
+ scoped_ptr<DownloadTargetInfo> target_info) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DownloadItem* item = download_manager_->GetDownload(download_id); |
+ if (!target_info->target_path.empty() && item && |
+ IsOpenInBrowserPreferreredForFile(target_info->target_path) && |
+ target_info->is_filetype_handled_securely) |
+ DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true); |
+ callback.Run(target_info->target_path, |
+ target_info->target_disposition, |
+ target_info->danger_type, |
+ target_info->intermediate_path); |
+} |