| 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..1725f23e47862809501e127d30cab5f12f8ee4c8 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,6 +23,7 @@
|
| #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"
|
| @@ -33,13 +35,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 +169,31 @@ 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,
|
| + const std::string& mime_type) {
|
| + // On Android, always prefer opening with an external app.
|
| +#if !defined(OS_ANDROID)
|
| + if (net::IsSupportedImageMimeType(mime_type))
|
| + return true;
|
| +
|
| +#if defined(ENABLE_PLUGINS)
|
| + if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf")))
|
| + return true;
|
| +#endif // ENABLE_PLUGINS
|
| +#endif // !OS_ANDROID
|
| + return false;
|
| +}
|
| +
|
| } // namespace
|
|
|
| ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
|
| @@ -220,13 +253,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 +408,44 @@ 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()) {
|
| + OpenDownloadUsingPlatformHandler(download);
|
| + return;
|
| + }
|
| +
|
| + 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);
|
| +}
|
| +
|
| void ChromeDownloadManagerDelegate::ShowDownloadInShell(
|
| DownloadItem* download) {
|
| if (!download->CanShowInFolder())
|
| @@ -523,6 +588,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 +659,20 @@ 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->mime_type) &&
|
| + 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);
|
| +}
|
|
|