diff options
author | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-07 06:13:54 +0000 |
---|---|---|
committer | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-07 06:13:54 +0000 |
commit | 34d3d441d8a02cf9ec4c3586ee762e022ee6cbf5 (patch) | |
tree | 8022f145127b3147465885703300196cfd051821 | |
parent | 8246ed39313592547db84a47ca5b4ae6d65221d9 (diff) | |
download | chromium_src-34d3d441d8a02cf9ec4c3586ee762e022ee6cbf5.zip chromium_src-34d3d441d8a02cf9ec4c3586ee762e022ee6cbf5.tar.gz chromium_src-34d3d441d8a02cf9ec4c3586ee762e022ee6cbf5.tar.bz2 |
Revert 233460 "Prefer opening PDF downloads in the browser."
Caused "PluginPrefsTest.UnifiedPepperFlashState" failure on "Linux Clang (dbg)"
BUG=316017
> Prefer opening PDF downloads in the browser.
>
> PDFs in particular are safer to open in the browser. This patch changes
> the handling of downloads to open such files in the browser by default
> instead of the system handler for the file type. A "Open with system
> handler" menu item will be available so that users can still use the
> system application if needed.
>
> The determination that a file is safer to handle in the browser is done
> as follows:
>
> a) DownloadTargetDeterminer determines whether the MIME type
> corresponding to the target filename of the download is one which is
> handled by the renderer or one that is handled by a sandboxed pepper
> plugin. If so, then the file is considered safely handled by the
> browser.
>
> b) ChromeDownloadManagerDelegate determines whether opening in the
> browser is preferred for the file type assuming the browser is able
> to handle it safely. Currently this is true for .pdf files.
>
> Opening behavior for a download will default to opening in the browser
> if both results from a) and b) are true.
>
> BUG=148492
>
> TEST=(1) Make sure Chrome PDF Viewer is enabled in chrome://plugins.
> (2) Download a .pdf file.
> (3) Download shelf context menu should show "Open" and "Open with
> system handler" options.
> (4) "Open" as well as clicking on the shelf icon and clicking on
> the download in chrome://downloads should all result in opening
> the file within the browser.
> (5) "Open with system handler" should open the .pdf with the
> application that's set up as the default handler for .pdf files
> on the users' machine.
>
> Review URL: https://codereview.chromium.org/55063002
TBR=asanka@chromium.org
Review URL: https://codereview.chromium.org/61623006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@233497 0039d316-1c4b-4281-b951-d872f2087c98
16 files changed, 130 insertions, 920 deletions
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc index c562876..0e32cdf 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.cc +++ b/chrome/browser/download/chrome_download_manager_delegate.cc @@ -6,7 +6,6 @@ #include <string> -#include "base/basictypes.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" @@ -23,12 +22,10 @@ #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" @@ -36,19 +33,13 @@ #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" @@ -170,26 +161,6 @@ 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) @@ -249,17 +220,13 @@ 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, - target_determined_callback); + callback); return true; } @@ -404,49 +371,14 @@ void ChromeDownloadManagerDelegate::ChooseSavePath( callback); } -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 + base::FilePath platform_path( + GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH)); + DCHECK(!platform_path.empty()); + platform_util::OpenItem(platform_path); } void ChromeDownloadManagerDelegate::ShowDownloadInShell( @@ -591,14 +523,6 @@ 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, @@ -662,19 +586,3 @@ 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); -} diff --git a/chrome/browser/download/chrome_download_manager_delegate.h b/chrome/browser/download/chrome_download_manager_delegate.h index 7fd81d9..d23337d 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.h +++ b/chrome/browser/download/chrome_download_manager_delegate.h @@ -11,7 +11,6 @@ #include "base/memory/scoped_ptr.h" #include "chrome/browser/download/download_path_reservation_tracker.h" #include "chrome/browser/download/download_target_determiner_delegate.h" -#include "chrome/browser/download/download_target_info.h" #include "chrome/browser/safe_browsing/download_protection_service.h" #include "content/public/browser/download_danger_type.h" #include "content/public/browser/download_item.h" @@ -96,11 +95,6 @@ class ChromeDownloadManagerDelegate const content::CheckForFileExistenceCallback& callback) OVERRIDE; virtual std::string ApplicationClientIdForFileScanning() const OVERRIDE; - // Opens a download using the platform handler. DownloadItem::OpenDownload, - // which ends up being handled by OpenDownload(), will open a download in the - // browser if doing so is preferred. - void OpenDownloadUsingPlatformHandler(content::DownloadItem* download); - DownloadPrefs* download_prefs() { return download_prefs_.get(); } protected: @@ -137,9 +131,6 @@ class ChromeDownloadManagerDelegate content::DownloadItem* download, const base::FilePath& suggested_virtual_path, const CheckDownloadUrlCallback& callback) OVERRIDE; - virtual void GetFileMimeType( - const base::FilePath& path, - const GetFileMimeTypeCallback& callback) OVERRIDE; private: friend class base::RefCountedThreadSafe<ChromeDownloadManagerDelegate>; @@ -166,11 +157,6 @@ class ChromeDownloadManagerDelegate void ReturnNextId(const content::DownloadIdCallback& callback); - void OnDownloadTargetDetermined( - int32 download_id, - const content::DownloadTargetCallback& callback, - scoped_ptr<DownloadTargetInfo> target_info); - Profile* profile_; uint32 next_download_id_; IdCallbackVector id_callbacks_; diff --git a/chrome/browser/download/chrome_download_manager_delegate_unittest.cc b/chrome/browser/download/chrome_download_manager_delegate_unittest.cc index 3ea6afa..6470758 100644 --- a/chrome/browser/download/chrome_download_manager_delegate_unittest.cc +++ b/chrome/browser/download/chrome_download_manager_delegate_unittest.cc @@ -9,7 +9,6 @@ #include "base/run_loop.h" #include "chrome/browser/download/chrome_download_manager_delegate.h" #include "chrome/browser/download/download_prefs.h" -#include "chrome/browser/download/download_target_info.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_pref_service_syncable.h" @@ -66,6 +65,13 @@ ACTION_P2(ScheduleCallback2, result0, result1) { FROM_HERE, base::Bind(arg0, result0, result1)); } +struct DownloadTarget { + base::FilePath target_path; + base::FilePath intermediate_path; + DownloadItem::TargetDisposition target_disposition; + content::DownloadDangerType danger_type; +}; + // Subclass of the ChromeDownloadManagerDelegate that uses a mock // DownloadProtectionService. class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate { @@ -146,7 +152,7 @@ class ChromeDownloadManagerDelegateTest : void SetDefaultDownloadPath(const base::FilePath& path); void DetermineDownloadTarget(DownloadItem* download, - DownloadTargetInfo* result); + DownloadTarget* result); const base::FilePath& default_download_path() const; TestChromeDownloadManagerDelegate* delegate(); @@ -154,6 +160,12 @@ class ChromeDownloadManagerDelegateTest : DownloadPrefs* download_prefs(); private: + void OnDownloadTargetDone(DownloadTarget* result, + const base::FilePath& target_path, + DownloadItem::TargetDisposition disposition, + content::DownloadDangerType danger_type, + const base::FilePath& intermediate_path); + TestingPrefServiceSyncable* pref_service_; base::ScopedTempDir test_download_dir_; scoped_ptr<content::MockDownloadManager> download_manager_; @@ -240,27 +252,28 @@ void ChromeDownloadManagerDelegateTest::SetDefaultDownloadPath( pref_service_->SetFilePath(prefs::kSaveFileDefaultDirectory, path); } -void StoreDownloadTargetInfo(const base::Closure& closure, - DownloadTargetInfo* target_info, - const base::FilePath& target_path, - DownloadItem::TargetDisposition target_disposition, - content::DownloadDangerType danger_type, - const base::FilePath& intermediate_path) { - target_info->target_path = target_path; - target_info->target_disposition = target_disposition; - target_info->danger_type = danger_type; - target_info->intermediate_path = intermediate_path; - closure.Run(); -} - void ChromeDownloadManagerDelegateTest::DetermineDownloadTarget( DownloadItem* download_item, - DownloadTargetInfo* result) { - base::RunLoop loop_runner; + DownloadTarget* result) { + base::WeakPtrFactory<ChromeDownloadManagerDelegateTest> factory(this); delegate()->DetermineDownloadTarget( download_item, - base::Bind(&StoreDownloadTargetInfo, loop_runner.QuitClosure(), result)); - loop_runner.Run(); + base::Bind(&ChromeDownloadManagerDelegateTest::OnDownloadTargetDone, + factory.GetWeakPtr(), base::Unretained(result))); + base::RunLoop loop_runner; + loop_runner.RunUntilIdle(); +} + +void ChromeDownloadManagerDelegateTest::OnDownloadTargetDone( + DownloadTarget* result, + const base::FilePath& target_path, + DownloadItem::TargetDisposition target_disposition, + content::DownloadDangerType danger_type, + const base::FilePath& intermediate_path) { + result->target_path = target_path; + result->intermediate_path = intermediate_path; + result->target_disposition = target_disposition; + result->danger_type = danger_type; } const base::FilePath& ChromeDownloadManagerDelegateTest::default_download_path() @@ -308,7 +321,7 @@ TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_LastSavePath) { { // When the prompt is displayed for the first download, the user selects a // path in a different directory. - DownloadTargetInfo result; + DownloadTarget result; base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt")); base::FilePath user_selected_path(GetPathInDownloadDir("bar/baz.txt")); EXPECT_CALL(*delegate(), @@ -323,7 +336,7 @@ TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_LastSavePath) { { // The prompt path for the second download is the user selected directroy // from the previous download. - DownloadTargetInfo result; + DownloadTarget result; base::FilePath expected_prompt_path(GetPathInDownloadDir("bar/foo.txt")); EXPECT_CALL(*delegate(), MockPromptUserForDownloadPath(save_as_download.get(), @@ -336,7 +349,7 @@ TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_LastSavePath) { { // Start an automatic download. This one should get the default download // path since the last download path only affects Save As downloads. - DownloadTargetInfo result; + DownloadTarget result; base::FilePath expected_path(GetPathInDownloadDir("foo.txt")); DetermineDownloadTarget(automatic_download.get(), &result); EXPECT_EQ(expected_path, result.target_path); @@ -346,7 +359,7 @@ TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_LastSavePath) { { // The prompt path for the next download should be the default. download_prefs()->SetSaveFilePath(download_prefs()->DownloadPath()); - DownloadTargetInfo result; + DownloadTarget result; base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt")); EXPECT_CALL(*delegate(), MockPromptUserForDownloadPath(save_as_download.get(), diff --git a/chrome/browser/download/download_item_model.cc b/chrome/browser/download/download_item_model.cc index fc719aa..2913b0e 100644 --- a/chrome/browser/download/download_item_model.cc +++ b/chrome/browser/download/download_item_model.cc @@ -12,11 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/supports_user_data.h" #include "base/time/time.h" -#include "chrome/browser/download/chrome_download_manager_delegate.h" #include "chrome/browser/download/download_crx_util.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/safe_browsing/download_feedback_service.h" #include "content/public/browser/download_danger_type.h" #include "content/public/browser/download_interrupt_reasons.h" @@ -56,13 +52,6 @@ class DownloadItemModelData : public base::SupportsUserData::Data { should_notify_ui_ = should_notify_ui; } - bool should_prefer_opening_in_browser() const { - return should_prefer_opening_in_browser_; - } - void set_should_prefer_opening_in_browser(bool preference) { - should_prefer_opening_in_browser_ = preference; - } - private: DownloadItemModelData(); virtual ~DownloadItemModelData() {} @@ -76,10 +65,6 @@ class DownloadItemModelData : public base::SupportsUserData::Data { // Whether the UI should be notified when the download is ready to be // presented. bool should_notify_ui_; - - // Whether the download should be opened in the browser vs. the system handler - // for the file type. - bool should_prefer_opening_in_browser_; }; // static @@ -105,8 +90,7 @@ DownloadItemModelData* DownloadItemModelData::GetOrCreate( DownloadItemModelData::DownloadItemModelData() : should_show_in_shelf_(true), - should_notify_ui_(false), - should_prefer_opening_in_browser_(false) { + should_notify_ui_(false) { } string16 InterruptReasonStatusMessage(int reason) { @@ -548,16 +532,6 @@ void DownloadItemModel::SetShouldNotifyUI(bool should_notify) { data->set_should_notify_ui(should_notify); } -bool DownloadItemModel::ShouldPreferOpeningInBrowser() const { - const DownloadItemModelData* data = DownloadItemModelData::Get(download_); - return data && data->should_prefer_opening_in_browser(); -} - -void DownloadItemModel::SetShouldPreferOpeningInBrowser(bool preference) { - DownloadItemModelData* data = DownloadItemModelData::GetOrCreate(download_); - data->set_should_prefer_opening_in_browser(preference); -} - string16 DownloadItemModel::GetProgressSizesString() const { string16 size_ratio; int64 size = GetCompletedBytes(); @@ -631,18 +605,3 @@ string16 DownloadItemModel::GetInProgressStatusString() const { // Instead of displaying "0 B" we say "Starting..." return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING); } - -void DownloadItemModel::OpenUsingPlatformHandler() { - DownloadService* download_service = - DownloadServiceFactory::GetForBrowserContext( - download_->GetBrowserContext()); - if (!download_service) - return; - - ChromeDownloadManagerDelegate* delegate = - download_service->GetDownloadManagerDelegate(); - if (!delegate) - return; - delegate->OpenDownloadUsingPlatformHandler(download_); - RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_USER_PLATFORM); -} diff --git a/chrome/browser/download/download_item_model.h b/chrome/browser/download/download_item_model.h index 05a1023f..5a2c141 100644 --- a/chrome/browser/download/download_item_model.h +++ b/chrome/browser/download/download_item_model.h @@ -126,18 +126,6 @@ class DownloadItemModel { // Change what's returned by ShouldNotifyUI(). void SetShouldNotifyUI(bool should_notify); - // Returns |true| if opening in the browser is preferred for this download. If - // |false|, the download should be opened with the system default application. - bool ShouldPreferOpeningInBrowser() const; - - // Change what's returned by ShouldPreferOpeningInBrowser to |preference|. - void SetShouldPreferOpeningInBrowser(bool preference); - - // Open the download using the platform handler for the download. The behavior - // of this method will be different from DownloadItem::OpenDownload() if - // ShouldPreferOpeningInBrowser(). - void OpenUsingPlatformHandler(); - content::DownloadItem* download() { return download_; } private: diff --git a/chrome/browser/download/download_shelf_context_menu.cc b/chrome/browser/download/download_shelf_context_menu.cc index a665db3..d2fc256 100644 --- a/chrome/browser/download/download_shelf_context_menu.cc +++ b/chrome/browser/download/download_shelf_context_menu.cc @@ -79,7 +79,6 @@ bool DownloadShelfContextMenu::IsCommandIdEnabled(int command_id) const { case SHOW_IN_FOLDER: return download_item_->CanShowInFolder(); case OPEN_WHEN_COMPLETE: - case PLATFORM_OPEN: return download_item_->CanOpenDownload() && !download_crx_util::IsExtensionDownload(*download_item_); case ALWAYS_OPEN_TYPE: @@ -139,9 +138,6 @@ void DownloadShelfContextMenu::ExecuteCommand(int command_id, int event_flags) { prefs->DisableAutoOpenBasedOnExtension(path); break; } - case PLATFORM_OPEN: - DownloadItemModel(download_item_).OpenUsingPlatformHandler(); - break; case CANCEL: download_item_->Cancel(true /* Cancelled by user */); break; @@ -225,8 +221,6 @@ string16 DownloadShelfContextMenu::GetLabelForCommandId(int command_id) const { return l10n_util::GetStringUTF16(IDS_DOWNLOAD_MENU_OPEN); case ALWAYS_OPEN_TYPE: return l10n_util::GetStringUTF16(IDS_DOWNLOAD_MENU_ALWAYS_OPEN_TYPE); - case PLATFORM_OPEN: - return l10n_util::GetStringUTF16(IDS_DOWNLOAD_MENU_PLATFORM_OPEN); case CANCEL: return l10n_util::GetStringUTF16(IDS_DOWNLOAD_MENU_CANCEL); case TOGGLE_PAUSE: @@ -296,9 +290,6 @@ ui::SimpleMenuModel* DownloadShelfContextMenu::GetFinishedMenuModel() { OPEN_WHEN_COMPLETE, IDS_DOWNLOAD_MENU_OPEN); finished_download_menu_model_->AddCheckItemWithStringId( ALWAYS_OPEN_TYPE, IDS_DOWNLOAD_MENU_ALWAYS_OPEN_TYPE); - if (DownloadItemModel(download_item_).ShouldPreferOpeningInBrowser()) - finished_download_menu_model_->AddItemWithStringId( - PLATFORM_OPEN, IDS_DOWNLOAD_MENU_PLATFORM_OPEN); finished_download_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); finished_download_menu_model_->AddItemWithStringId( SHOW_IN_FOLDER, IDS_DOWNLOAD_MENU_SHOW); diff --git a/chrome/browser/download/download_shelf_context_menu.h b/chrome/browser/download/download_shelf_context_menu.h index 56a78bed..9541c56 100644 --- a/chrome/browser/download/download_shelf_context_menu.h +++ b/chrome/browser/download/download_shelf_context_menu.h @@ -28,7 +28,6 @@ class DownloadShelfContextMenu : public ui::SimpleMenuModel::Delegate, SHOW_IN_FOLDER = 1, // Open a folder view window with the item selected. OPEN_WHEN_COMPLETE, // Open the download when it's finished. ALWAYS_OPEN_TYPE, // Default this file extension to always open. - PLATFORM_OPEN, // Open using platform handler. CANCEL, // Cancel the download. TOGGLE_PAUSE, // Pause or resume a download. DISCARD, // Discard the malicious download. diff --git a/chrome/browser/download/download_stats.cc b/chrome/browser/download/download_stats.cc index 4c2fd68..9558756 100644 --- a/chrome/browser/download/download_stats.cc +++ b/chrome/browser/download/download_stats.cc @@ -37,9 +37,3 @@ void RecordOpenedDangerousConfirmDialog( danger_type, content::DOWNLOAD_DANGER_TYPE_MAX); } - -void RecordDownloadOpenMethod(ChromeDownloadOpenMethod open_method) { - UMA_HISTOGRAM_ENUMERATION("Download.OpenMethod", - open_method, - DOWNLOAD_OPEN_METHOD_LAST_ENTRY); -} diff --git a/chrome/browser/download/download_stats.h b/chrome/browser/download/download_stats.h index ece9243..b84091f 100644 --- a/chrome/browser/download/download_stats.h +++ b/chrome/browser/download/download_stats.h @@ -56,23 +56,6 @@ enum ChromeDownloadSource { CHROME_DOWNLOAD_SOURCE_LAST_ENTRY, }; -// How a download was opened. Note that a download could be opened multiple -// times. -enum ChromeDownloadOpenMethod { - // The download was opened using the platform handler. There was no special - // handling for this download. - DOWNLOAD_OPEN_METHOD_DEFAULT_PLATFORM = 0, - - // The download was opened using the browser bypassing the system handler. - DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER, - - // The user chose to open the download using the system handler even though - // the preferred method was to open the download using the browser. - DOWNLOAD_OPEN_METHOD_USER_PLATFORM, - - DOWNLOAD_OPEN_METHOD_LAST_ENTRY -}; - // Increment one of the above counts. void RecordDownloadCount(ChromeDownloadCountTypes type); @@ -83,7 +66,4 @@ void RecordDownloadSource(ChromeDownloadSource source); void RecordOpenedDangerousConfirmDialog( content::DownloadDangerType danger_type); -// Record how a download was opened. -void RecordDownloadOpenMethod(ChromeDownloadOpenMethod open_method); - #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_STATS_H_ diff --git a/chrome/browser/download/download_target_determiner.cc b/chrome/browser/download/download_target_determiner.cc index 6f34d40..7291336 100644 --- a/chrome/browser/download/download_target_determiner.cc +++ b/chrome/browser/download/download_target_determiner.cc @@ -23,16 +23,9 @@ #include "content/public/browser/download_interrupt_reasons.h" #include "extensions/common/constants.h" #include "grit/generated_resources.h" -#include "net/base/mime_util.h" #include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" -#if defined(ENABLE_PLUGINS) -#include "chrome/browser/plugins/plugin_prefs.h" -#include "content/public/browser/plugin_service.h" -#include "content/public/common/webplugininfo.h" -#endif - using content::BrowserThread; using content::DownloadItem; @@ -58,11 +51,6 @@ void VisitCountsToVisitedBefore( } // namespace -DownloadTargetInfo::DownloadTargetInfo() - : is_filetype_handled_securely(false) {} - -DownloadTargetInfo::~DownloadTargetInfo() {} - DownloadTargetDeterminerDelegate::~DownloadTargetDeterminerDelegate() { } @@ -71,7 +59,7 @@ DownloadTargetDeterminer::DownloadTargetDeterminer( const base::FilePath& initial_virtual_path, DownloadPrefs* download_prefs, DownloadTargetDeterminerDelegate* delegate, - const CompletionCallback& callback) + const content::DownloadTargetCallback& callback) : next_state_(STATE_GENERATE_TARGET_PATH), should_prompt_(false), should_notify_extensions_(false), @@ -79,7 +67,6 @@ DownloadTargetDeterminer::DownloadTargetDeterminer( conflict_action_(DownloadPathReservationTracker::OVERWRITE), danger_type_(download->GetDangerType()), virtual_path_(initial_virtual_path), - is_filetype_handled_securely_(false), download_(download), is_resumption_(download_->GetLastReason() != content::DOWNLOAD_INTERRUPT_REASON_NONE && @@ -125,12 +112,6 @@ void DownloadTargetDeterminer::DoLoop() { case STATE_DETERMINE_LOCAL_PATH: result = DoDetermineLocalPath(); break; - case STATE_DETERMINE_MIME_TYPE: - result = DoDetermineMimeType(); - break; - case STATE_DETERMINE_IF_HANDLED_BY_BROWSER: - result = DoDetermineIfHandledByBrowser(); - break; case STATE_CHECK_DOWNLOAD_URL: result = DoCheckDownloadUrl(); break; @@ -324,7 +305,7 @@ DownloadTargetDeterminer::Result DCHECK(!virtual_path_.empty()); DCHECK(local_path_.empty()); - next_state_ = STATE_DETERMINE_MIME_TYPE; + next_state_ = STATE_CHECK_DOWNLOAD_URL; delegate_->DetermineLocalPath( download_, @@ -348,126 +329,6 @@ void DownloadTargetDeterminer::DetermineLocalPathDone( } DownloadTargetDeterminer::Result - DownloadTargetDeterminer::DoDetermineMimeType() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(!virtual_path_.empty()); - DCHECK(!local_path_.empty()); - DCHECK(mime_type_.empty()); - - next_state_ = STATE_DETERMINE_IF_HANDLED_BY_BROWSER; - - if (virtual_path_ == local_path_) { - delegate_->GetFileMimeType( - local_path_, - base::Bind(&DownloadTargetDeterminer::DetermineMimeTypeDone, - weak_ptr_factory_.GetWeakPtr())); - return QUIT_DOLOOP; - } - return CONTINUE; -} - -void DownloadTargetDeterminer::DetermineMimeTypeDone( - const std::string& mime_type) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DVLOG(20) << "MIME type: " << mime_type; - mime_type_ = mime_type; - DoLoop(); -} - -#if defined(ENABLE_PLUGINS) -// The code below is used by DoDetermineIfHandledByBrowser to determine if the -// file type is handled by a sandboxed plugin. -namespace { - -typedef std::vector<content::WebPluginInfo> PluginVector; - -// Returns true if there is a plugin in |plugins| that is sandboxed and enabled -// for |profile|. -bool IsSafePluginAvailableForProfile(scoped_ptr<PluginVector> plugins, - Profile* profile) { - using content::WebPluginInfo; - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (plugins->size() == 0) - return false; - - scoped_refptr<PluginPrefs> plugin_prefs = PluginPrefs::GetForProfile(profile); - if (!plugin_prefs) - return false; - - for (PluginVector::iterator plugin = plugins->begin(); - plugin != plugins->end(); ++plugin) { - if (plugin_prefs->IsPluginEnabled(*plugin) && - (plugin->type == WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS || - plugin->type == WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS)) - return true; - } - return false; -} - -// Returns a callback that determines if a sandboxed plugin is available to -// handle |mime_type| for a specific profile. The returned callback must be -// invoked on the UI thread, while this function should be called on the IO -// thread. -base::Callback<bool(Profile*)> GetSafePluginChecker( - const GURL& url, - const std::string& mime_type) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(!mime_type.empty()); - - scoped_ptr<PluginVector> plugins(new PluginVector); - content::PluginService* plugin_service = - content::PluginService::GetInstance(); - if (plugin_service) - plugin_service->GetPluginInfoArray( - url, mime_type, false, plugins.get(), NULL); - return base::Bind(&IsSafePluginAvailableForProfile, base::Passed(&plugins)); -} - -} // namespace -#endif // ENABLE_PLUGINS - -DownloadTargetDeterminer::Result - DownloadTargetDeterminer::DoDetermineIfHandledByBrowser() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(!virtual_path_.empty()); - DCHECK(!local_path_.empty()); - DCHECK(!is_filetype_handled_securely_); - - next_state_ = STATE_CHECK_DOWNLOAD_URL; - - if (mime_type_.empty()) - return CONTINUE; - - if (net::IsSupportedMimeType(mime_type_)) { - is_filetype_handled_securely_ = true; - return CONTINUE; - } - -#if defined(ENABLE_PLUGINS) - BrowserThread::PostTaskAndReplyWithResult( - BrowserThread::IO, - FROM_HERE, - base::Bind(&GetSafePluginChecker, - net::FilePathToFileURL(local_path_), mime_type_), - base::Bind(&DownloadTargetDeterminer::DetermineIfHandledByBrowserDone, - weak_ptr_factory_.GetWeakPtr())); - return QUIT_DOLOOP; -#else - return CONTINUE; -#endif -} - -void DownloadTargetDeterminer::DetermineIfHandledByBrowserDone( - const base::Callback<bool(Profile*)>& callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - is_filetype_handled_securely_ = callback.Run(GetProfile()); - DVLOG(20) << "Is file type handled securely: " - << is_filetype_handled_securely_; - DoLoop(); -} - -DownloadTargetDeterminer::Result DownloadTargetDeterminer::DoCheckDownloadUrl() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(!virtual_path_.empty()); @@ -623,20 +484,15 @@ void DownloadTargetDeterminer::ScheduleCallbackAndDeleteSelf() { << " Intermediate:" << intermediate_path_.AsUTF8Unsafe() << " Should prompt:" << should_prompt_ << " Danger type:" << danger_type_; - scoped_ptr<DownloadTargetInfo> target_info(new DownloadTargetInfo); - - target_info->target_path = local_path_; - target_info->target_disposition = - (HasPromptedForPath() || should_prompt_ - ? DownloadItem::TARGET_DISPOSITION_PROMPT - : DownloadItem::TARGET_DISPOSITION_OVERWRITE); - target_info->danger_type = danger_type_; - target_info->intermediate_path = intermediate_path_; - target_info->mime_type = mime_type_; - target_info->is_filetype_handled_securely = is_filetype_handled_securely_; - base::MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(completion_callback_, base::Passed(&target_info))); + FROM_HERE, + base::Bind(completion_callback_, + local_path_, + (HasPromptedForPath() || should_prompt_ + ? DownloadItem::TARGET_DISPOSITION_PROMPT + : DownloadItem::TARGET_DISPOSITION_OVERWRITE), + danger_type_, + intermediate_path_)); completion_callback_.Reset(); delete this; } @@ -775,11 +631,12 @@ void DownloadTargetDeterminer::OnDownloadDestroyed( } // static -void DownloadTargetDeterminer::Start(content::DownloadItem* download, - const base::FilePath& initial_virtual_path, - DownloadPrefs* download_prefs, - DownloadTargetDeterminerDelegate* delegate, - const CompletionCallback& callback) { +void DownloadTargetDeterminer::Start( + content::DownloadItem* download, + const base::FilePath& initial_virtual_path, + DownloadPrefs* download_prefs, + DownloadTargetDeterminerDelegate* delegate, + const content::DownloadTargetCallback& callback) { // DownloadTargetDeterminer owns itself and will self destruct when the job is // complete or the download item is destroyed. The callback is always invoked // asynchronously. diff --git a/chrome/browser/download/download_target_determiner.h b/chrome/browser/download/download_target_determiner.h index 73593e4..8367c99 100644 --- a/chrome/browser/download/download_target_determiner.h +++ b/chrome/browser/download/download_target_determiner.h @@ -12,7 +12,6 @@ #include "chrome/browser/common/cancelable_request.h" #include "chrome/browser/download/download_path_reservation_tracker.h" #include "chrome/browser/download/download_target_determiner_delegate.h" -#include "chrome/browser/download/download_target_info.h" #include "content/public/browser/download_danger_type.h" #include "content/public/browser/download_item.h" #include "content/public/browser/download_manager_delegate.h" @@ -51,9 +50,6 @@ enum DownloadDangerType; class DownloadTargetDeterminer : public content::DownloadItem::Observer { public: - typedef base::Callback<void(scoped_ptr<DownloadTargetInfo>)> - CompletionCallback; - // Start the process of determing the target of |download|. // // |initial_virtual_path| if non-empty, defines the initial virtual path for @@ -74,7 +70,7 @@ class DownloadTargetDeterminer const base::FilePath& initial_virtual_path, DownloadPrefs* download_prefs, DownloadTargetDeterminerDelegate* delegate, - const CompletionCallback& callback); + const content::DownloadTargetCallback& callback); // Returns a .crdownload intermediate path for the |suggested_path|. static base::FilePath GetCrDownloadPath(const base::FilePath& suggested_path); @@ -91,8 +87,6 @@ class DownloadTargetDeterminer STATE_RESERVE_VIRTUAL_PATH, STATE_PROMPT_USER_FOR_DOWNLOAD_PATH, STATE_DETERMINE_LOCAL_PATH, - STATE_DETERMINE_MIME_TYPE, - STATE_DETERMINE_IF_HANDLED_BY_BROWSER, STATE_CHECK_DOWNLOAD_URL, STATE_CHECK_VISITED_REFERRER_BEFORE, STATE_DETERMINE_INTERMEDIATE_PATH, @@ -125,11 +119,12 @@ class DownloadTargetDeterminer // Construct a DownloadTargetDeterminer object. Constraints on the arguments // are as per Start() above. - DownloadTargetDeterminer(content::DownloadItem* download, - const base::FilePath& initial_virtual_path, - DownloadPrefs* download_prefs, - DownloadTargetDeterminerDelegate* delegate, - const CompletionCallback& callback); + DownloadTargetDeterminer( + content::DownloadItem* download, + const base::FilePath& initial_virtual_path, + DownloadPrefs* download_prefs, + DownloadTargetDeterminerDelegate* delegate, + const content::DownloadTargetCallback& callback); virtual ~DownloadTargetDeterminer(); @@ -183,39 +178,12 @@ class DownloadTargetDeterminer // virtual path. The translation is done by invoking the DetermineLocalPath() // method on the delegate. // Next state: - // - STATE_DETERMINE_MIME_TYPE. + // - STATE_CHECK_DOWNLOAD_URL. Result DoDetermineLocalPath(); // Callback invoked when the delegate has determined local path. void DetermineLocalPathDone(const base::FilePath& local_path); - // Determine the MIME type corresponding to the local file path. This is only - // done if the local path and the virtual path was the same. I.e. The file is - // intended for the local file system. This restriction is there because the - // resulting MIME type is only valid for determining whether the browser can - // handle the download if it were opened via a file:// URL. - // Next state: - // - STATE_DETERMINE_IF_HANDLED_BY_BROWSER. - Result DoDetermineMimeType(); - - // Callback invoked when the MIME type is available. Since determination of - // the MIME type can involve disk access, it is done in the blocking pool. - void DetermineMimeTypeDone(const std::string& mime_type); - - // Determine if the file type can be handled by the browser if it were to be - // opened via a file:// URL. - // Next state: - // - STATE_CHECK_DOWNLOAD_URL. - Result DoDetermineIfHandledByBrowser(); - - // Callback invoked when a decision is available about whether the file type - // can be handled by the browser. The actual decision depends on the profile - // and has to be made on the UI thread. Therefore this method receives a - // callback that can determine whether the download is handled by the browser - // based on a passed-in Profile* parameter. - void DetermineIfHandledByBrowserDone( - const base::Callback<bool(Profile*)>& per_profile_handler_checker); - // Checks whether the downloaded URL is malicious. Invokes the // DownloadProtectionService via the delegate. // Next state: @@ -289,14 +257,12 @@ class DownloadTargetDeterminer base::FilePath virtual_path_; base::FilePath local_path_; base::FilePath intermediate_path_; - std::string mime_type_; - bool is_filetype_handled_securely_; content::DownloadItem* download_; const bool is_resumption_; DownloadPrefs* download_prefs_; DownloadTargetDeterminerDelegate* delegate_; - CompletionCallback completion_callback_; + content::DownloadTargetCallback completion_callback_; CancelableRequestConsumer history_consumer_; base::WeakPtrFactory<DownloadTargetDeterminer> weak_ptr_factory_; diff --git a/chrome/browser/download/download_target_determiner_delegate.h b/chrome/browser/download/download_target_determiner_delegate.h index f2aeec6..68271ff 100644 --- a/chrome/browser/download/download_target_determiner_delegate.h +++ b/chrome/browser/download/download_target_determiner_delegate.h @@ -62,11 +62,6 @@ class DownloadTargetDeterminerDelegate { typedef base::Callback<void(content::DownloadDangerType danger_type)> CheckDownloadUrlCallback; - // Callback to be invoked after GetFileMimeType() completes. The parameter - // should be the MIME type of the requested file. If no MIME type can be - // determined, it should be set to the empty string. - typedef base::Callback<void(const std::string&)> GetFileMimeTypeCallback; - // Notifies extensions of the impending filename determination. |virtual_path| // is the current suggested virtual path. The |callback| should be invoked to // indicate whether any extensions wish to override the path. @@ -115,9 +110,6 @@ class DownloadTargetDeterminerDelegate { const base::FilePath& virtual_path, const CheckDownloadUrlCallback& callback) = 0; - // Get the MIME type for the given file. - virtual void GetFileMimeType(const base::FilePath& path, - const GetFileMimeTypeCallback& callback) = 0; protected: virtual ~DownloadTargetDeterminerDelegate(); }; diff --git a/chrome/browser/download/download_target_determiner_unittest.cc b/chrome/browser/download/download_target_determiner_unittest.cc index 0253334..aca0720 100644 --- a/chrome/browser/download/download_target_determiner_unittest.cc +++ b/chrome/browser/download/download_target_determiner_unittest.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/at_exit.h" #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "base/message_loop/message_loop.h" @@ -16,7 +15,6 @@ #include "chrome/browser/download/download_extensions.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/download/download_target_determiner.h" -#include "chrome/browser/download/download_target_info.h" #include "chrome/browser/history/history_service.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/history/history_types.h" @@ -26,23 +24,15 @@ #include "chrome/test/base/testing_pref_service_syncable.h" #include "chrome/test/base/testing_profile.h" #include "content/public/browser/download_interrupt_reasons.h" -#include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/test/mock_download_item.h" #include "content/public/test/test_browser_thread.h" #include "content/public/test/test_renderer_host.h" #include "content/public/test/web_contents_tester.h" -#include "net/base/mime_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(ENABLE_PLUGINS) -#include "chrome/browser/plugins/plugin_prefs.h" -#include "content/public/browser/plugin_service.h" -#include "content/public/common/webplugininfo.h" -#endif - using ::testing::AnyNumber; using ::testing::Invoke; using ::testing::Ref; @@ -153,9 +143,6 @@ class MockDownloadTargetDeterminerDelegate void(DownloadItem*, const base::FilePath&, bool, DownloadPathReservationTracker::FilenameConflictAction, const ReservedPathCallback&)); - MOCK_METHOD2(GetFileMimeType, - void(const base::FilePath&, - const GetFileMimeTypeCallback&)); void SetupDefaults() { ON_CALL(*this, CheckDownloadUrl(_, _, _)) @@ -174,9 +161,6 @@ class MockDownloadTargetDeterminerDelegate ON_CALL(*this, DetermineLocalPath(_, _, _)) .WillByDefault(Invoke( &MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath)); - ON_CALL(*this, GetFileMimeType(_, _)) - .WillByDefault(WithArg<1>( - ScheduleCallback(""))); } private: static void NullReserveVirtualPath( @@ -222,12 +206,6 @@ class DownloadTargetDeterminerTest : public ChromeRenderViewHostTestHarness { const base::FilePath& initial_virtual_path, content::MockDownloadItem* item); - // Runs |test_case| with |item|. When the DownloadTargetDeterminer is done, - // returns the resulting DownloadTargetInfo. - scoped_ptr<DownloadTargetInfo> RunDownloadTargetDeterminer( - const base::FilePath& initial_virtual_path, - content::MockDownloadItem* item); - // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem // will be created for each test case and destroyed when the test case is // complete. @@ -237,8 +215,12 @@ class DownloadTargetDeterminerTest : public ChromeRenderViewHostTestHarness { // Verifies that |target_path|, |disposition|, |expected_danger_type| and // |intermediate_path| matches the expectations of |test_case|. Posts // |closure| to the current message loop when done. - void VerifyDownloadTarget(const DownloadTestCase& test_case, - const DownloadTargetInfo* target_info); + void DownloadTargetVerifier(const base::Closure& closure, + const DownloadTestCase& test_case, + const base::FilePath& local_path, + DownloadItem::TargetDisposition disposition, + content::DownloadDangerType danger_type, + const base::FilePath& intermediate_path); const base::FilePath& test_download_dir() const { return test_download_dir_.path(); @@ -265,7 +247,6 @@ class DownloadTargetDeterminerTest : public ChromeRenderViewHostTestHarness { }; void DownloadTargetDeterminerTest::SetUp() { - SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD); ChromeRenderViewHostTestHarness::SetUp(); CHECK(profile()); download_prefs_.reset(new DownloadPrefs(profile())); @@ -274,10 +255,6 @@ void DownloadTargetDeterminerTest::SetUp() { test_virtual_dir_ = test_download_dir().Append(FILE_PATH_LITERAL("virtual")); download_prefs_->SetDownloadPath(test_download_dir()); delegate_.SetupDefaults(); -#if defined(ENABLE_PLUGINS) - content::PluginService::GetInstance()->Init(); - content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting(); -#endif } void DownloadTargetDeterminerTest::TearDown() { @@ -373,33 +350,15 @@ void DownloadTargetDeterminerTest::RunTestCase( const DownloadTestCase& test_case, const base::FilePath& initial_virtual_path, content::MockDownloadItem* item) { - scoped_ptr<DownloadTargetInfo> target_info = - RunDownloadTargetDeterminer(initial_virtual_path, item); - VerifyDownloadTarget(test_case, target_info.get()); -} - -void CompletionCallbackWrapper( - const base::Closure& closure, - scoped_ptr<DownloadTargetInfo>* target_info_receiver, - scoped_ptr<DownloadTargetInfo> target_info) { - target_info_receiver->swap(target_info); - base::MessageLoop::current()->PostTask(FROM_HERE, closure); -} - -scoped_ptr<DownloadTargetInfo> -DownloadTargetDeterminerTest::RunDownloadTargetDeterminer( - const base::FilePath& initial_virtual_path, - content::MockDownloadItem* item) { - scoped_ptr<DownloadTargetInfo> target_info; + // Kick off the test. + base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this); base::RunLoop run_loop; DownloadTargetDeterminer::Start( item, initial_virtual_path, download_prefs_.get(), delegate(), - base::Bind(&CompletionCallbackWrapper, - run_loop.QuitClosure(), - &target_info)); + base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier, + factory.GetWeakPtr(), run_loop.QuitClosure(), test_case)); run_loop.Run(); ::testing::Mock::VerifyAndClearExpectations(delegate()); - return target_info.Pass(); } void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem( @@ -413,20 +372,23 @@ void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem( } } -void DownloadTargetDeterminerTest::VerifyDownloadTarget( +void DownloadTargetDeterminerTest::DownloadTargetVerifier( + const base::Closure& closure, const DownloadTestCase& test_case, - const DownloadTargetInfo* target_info) { + const base::FilePath& local_path, + DownloadItem::TargetDisposition disposition, + content::DownloadDangerType danger_type, + const base::FilePath& intermediate_path) { base::FilePath expected_local_path( GetPathInDownloadDir(test_case.expected_local_path)); - EXPECT_EQ(expected_local_path.value(), target_info->target_path.value()); - EXPECT_EQ(test_case.expected_disposition, target_info->target_disposition); - EXPECT_EQ(test_case.expected_danger_type, target_info->danger_type); + EXPECT_EQ(expected_local_path.value(), local_path.value()); + EXPECT_EQ(test_case.expected_disposition, disposition); + EXPECT_EQ(test_case.expected_danger_type, danger_type); switch (test_case.expected_intermediate) { case EXPECT_CRDOWNLOAD: - EXPECT_EQ(DownloadTargetDeterminer::GetCrDownloadPath( - target_info->target_path).value(), - target_info->intermediate_path.value()); + EXPECT_EQ(DownloadTargetDeterminer::GetCrDownloadPath(local_path).value(), + intermediate_path.value()); break; case EXPECT_UNCONFIRMED: @@ -438,21 +400,20 @@ void DownloadTargetDeterminerTest::VerifyDownloadTarget( // 4. Basename starts with "Unconfirmed ". EXPECT_NE(DownloadTargetDeterminer::GetCrDownloadPath(expected_local_path) .value(), - target_info->intermediate_path.value()); + intermediate_path.value()); EXPECT_EQ(expected_local_path.DirName().value(), - target_info->intermediate_path.DirName().value()); - EXPECT_TRUE(target_info->intermediate_path.MatchesExtension( + intermediate_path.DirName().value()); + EXPECT_TRUE(intermediate_path.MatchesExtension( FILE_PATH_LITERAL(".crdownload"))); - EXPECT_EQ(0u, - target_info->intermediate_path.BaseName().value().find( - FILE_PATH_LITERAL("Unconfirmed "))); + EXPECT_EQ(0u, intermediate_path.BaseName().value().find( + FILE_PATH_LITERAL("Unconfirmed "))); break; case EXPECT_LOCAL_PATH: - EXPECT_EQ(expected_local_path.value(), - target_info->intermediate_path.value()); + EXPECT_EQ(expected_local_path.value(), intermediate_path.value()); break; } + base::MessageLoop::current()->PostTask(FROM_HERE, closure); } // static @@ -1743,6 +1704,21 @@ TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedWithPrompt) { } } +// Used with TargetDeterminer_IntermediateNameForResumed test. Verifies that +// |intermediate_path| == |expected_intermediate_path| if the latter is +// non-empty. +void IntermediatePathVerifier( + const base::FilePath& expected_intermediate_path, + const content::DownloadTargetCallback& callback, + const base::FilePath& target_path, + content::DownloadItem::TargetDisposition disposition, + content::DownloadDangerType danger_type, + const base::FilePath& intermediate_path) { + if (!expected_intermediate_path.empty()) + EXPECT_EQ(expected_intermediate_path, intermediate_path); + callback.Run(target_path, disposition, danger_type, intermediate_path); +} + // Test intermediate filename generation for resumed downloads. TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_IntermediateNameForResumed) { @@ -1879,362 +1855,25 @@ TEST_F(DownloadTargetDeterminerTest, ON_CALL(*item.get(), GetDangerType()) .WillByDefault(Return(test_case.general.expected_danger_type)); - scoped_ptr<DownloadTargetInfo> target_info = - RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), - item.get()); - VerifyDownloadTarget(test_case.general, target_info.get()); - base::FilePath expected_intermediate_path = - GetPathInDownloadDir(test_case.expected_intermediate_path); - if (!expected_intermediate_path.empty()) - EXPECT_EQ(expected_intermediate_path, target_info->intermediate_path); - } -} - -// Test MIME type determination based on the target filename. -TEST_F(DownloadTargetDeterminerTest, - TargetDeterminer_MIMETypeDetermination) { - // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital - // path. - const base::FilePath::CharType kInitialPath[] = - FILE_PATH_LITERAL("some_path/bar.txt"); - - struct MIMETypeTestCase { - // General test case settings. - DownloadTestCase general; - - // Expected MIME type for test case. - const char* expected_mime_type; - } kMIMETypeTestCases[] = { - { - { - // 0: - AUTOMATIC, - content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - "http://example.com/foo.png", "image/png", - FILE_PATH_LITERAL(""), - - FILE_PATH_LITERAL(""), - FILE_PATH_LITERAL("foo.png"), - DownloadItem::TARGET_DISPOSITION_OVERWRITE, - - EXPECT_CRDOWNLOAD - }, - "image/png" - }, - { - { - // 1: Empty MIME type in response. - AUTOMATIC, - content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - "http://example.com/foo.png", "", - FILE_PATH_LITERAL(""), - - FILE_PATH_LITERAL(""), - FILE_PATH_LITERAL("foo.png"), - DownloadItem::TARGET_DISPOSITION_OVERWRITE, - - EXPECT_CRDOWNLOAD - }, - "image/png" - }, - { - { - // 2: Forced path. - FORCED, - content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - "http://example.com/foo.abc", "", - FILE_PATH_LITERAL("foo.png"), - - FILE_PATH_LITERAL(""), - FILE_PATH_LITERAL("foo.png"), - DownloadItem::TARGET_DISPOSITION_OVERWRITE, - - EXPECT_CRDOWNLOAD - }, - "image/png" - }, - { - { - // 3: Unknown file type. - AUTOMATIC, - content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - "http://example.com/foo.notarealext", "", - FILE_PATH_LITERAL(""), - - FILE_PATH_LITERAL(""), - FILE_PATH_LITERAL("foo.notarealext"), - DownloadItem::TARGET_DISPOSITION_OVERWRITE, - - EXPECT_CRDOWNLOAD - }, - "" - }, - { - { - // 4: Unknown file type. - AUTOMATIC, - content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - "http://example.com/foo.notarealext", "image/png", - FILE_PATH_LITERAL(""), - - FILE_PATH_LITERAL(""), - FILE_PATH_LITERAL("foo.notarealext"), - DownloadItem::TARGET_DISPOSITION_OVERWRITE, - - EXPECT_CRDOWNLOAD - }, - "" - }, - }; - - ON_CALL(*delegate(), GetFileMimeType( - GetPathInDownloadDir(FILE_PATH_LITERAL("foo.png")), _)) - .WillByDefault(WithArg<1>( - ScheduleCallback("image/png"))); - - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kMIMETypeTestCases); ++i) { - SCOPED_TRACE(testing::Message() << "Running test case " << i); - const MIMETypeTestCase& test_case = kMIMETypeTestCases[i]; - scoped_ptr<content::MockDownloadItem> item( - CreateActiveDownloadItem(i, test_case.general)); - scoped_ptr<DownloadTargetInfo> target_info = - RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), - item.get()); - EXPECT_EQ(test_case.expected_mime_type, target_info->mime_type); - } -} - -#if defined(ENABLE_PLUGINS) - -void DummyGetPluginsCallback( - const base::Closure& closure, - const std::vector<content::WebPluginInfo>& plugins) { - closure.Run(); -} - -void ForceRefreshOfPlugins() { -#if !defined(OS_WIN) - // Prevent creation of a utility process for loading plugins. Doing so breaks - // unit_tests since /proc/self/exe can't be run as a utility process. - content::RenderProcessHost::SetRunRendererInProcess(true); -#endif - base::RunLoop run_loop; - content::PluginService::GetInstance()->GetPlugins( - base::Bind(&DummyGetPluginsCallback, run_loop.QuitClosure())); - run_loop.Run(); -#if !defined(OS_WIN) - content::RenderProcessHost::SetRunRendererInProcess(false); -#endif -} - -void PluginEnabledCallback(const base::Closure& closure, - bool result) { - EXPECT_TRUE(result); - closure.Run(); -} - -void EnablePlugin(bool enable, PluginPrefs* prefs, const base::FilePath& path) { - base::RunLoop run_loop; - prefs->EnablePlugin(enable, path, - base::Bind(&PluginEnabledCallback, - run_loop.QuitClosure())); - run_loop.Run(); -} - -class ScopedRegisterInternalPlugin { - public: - ScopedRegisterInternalPlugin(content::PluginService* plugin_service, - content::WebPluginInfo::PluginType type, - const base::FilePath& path, - const char* mime_type, - const char* extension) - : plugin_service_(plugin_service), - plugin_path_(path) { - content::WebPluginMimeType plugin_mime_type(mime_type, - extension, - "Test file"); - content::WebPluginInfo plugin_info(base::string16(), - path, - base::string16(), - base::string16()); - plugin_info.mime_types.push_back(plugin_mime_type); - plugin_info.type = type; - - plugin_service->RegisterInternalPlugin(plugin_info, true); - plugin_service->RefreshPlugins(); - ForceRefreshOfPlugins(); - } - - ~ScopedRegisterInternalPlugin() { - plugin_service_->UnregisterInternalPlugin(plugin_path_); - plugin_service_->RefreshPlugins(); - ForceRefreshOfPlugins(); - } - - const base::FilePath& path() { return plugin_path_; } - - private: - content::PluginService* plugin_service_; - base::FilePath plugin_path_; -}; - -// Check if secure handling of filetypes is determined correctly for PPAPI -// plugins. -TEST_F(DownloadTargetDeterminerTest, - TargetDeterminer_CheckForSecureHandling_PPAPI) { - // The ShadowingAtExitManager destroys the tainted PluginService instance. - base::ShadowingAtExitManager at_exit_manager; - - // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital - // path. - const base::FilePath::CharType kInitialPath[] = - FILE_PATH_LITERAL("some_path/bar.txt"); - const char kTestMIMEType[] = "application/x-example-should-not-exist"; - - DownloadTestCase kSecureHandlingTestCase = { - AUTOMATIC, - content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - "http://example.com/foo.fakeext", "", - FILE_PATH_LITERAL(""), - - FILE_PATH_LITERAL(""), - FILE_PATH_LITERAL("foo.fakeext"), - DownloadItem::TARGET_DISPOSITION_OVERWRITE, - - EXPECT_CRDOWNLOAD - }; - - content::PluginService* plugin_service = - content::PluginService::GetInstance(); - // This creates a PluginPrefs for our TestingProfile. - scoped_refptr<PluginPrefs> plugin_prefs = - PluginPrefs::GetForTestingProfile(profile()); - - // Verify our test assumptions. - { - ForceRefreshOfPlugins(); - std::vector<content::WebPluginInfo> info; - ASSERT_FALSE(plugin_service->GetPluginInfoArray( - GURL(), kTestMIMEType, false, &info, NULL)); - ASSERT_EQ(0u, info.size()) - << "Name: " << info[0].name << ", Path: " << info[0].path.value(); - } - - ON_CALL(*delegate(), GetFileMimeType( - GetPathInDownloadDir(FILE_PATH_LITERAL("foo.fakeext")), _)) - .WillByDefault(WithArg<1>( - ScheduleCallback(kTestMIMEType))); - scoped_ptr<content::MockDownloadItem> item( - CreateActiveDownloadItem(1, kSecureHandlingTestCase)); - scoped_ptr<DownloadTargetInfo> target_info = - RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), - item.get()); - EXPECT_FALSE(target_info->is_filetype_handled_securely); - - // Register a PPAPI plugin. This should count as handling the filetype - // securely. - ScopedRegisterInternalPlugin ppapi_plugin( - plugin_service, - content::WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS, - test_download_dir().AppendASCII("ppapi"), - kTestMIMEType, - "fakeext"); - - target_info = RunDownloadTargetDeterminer( - GetPathInDownloadDir(kInitialPath), item.get()); - EXPECT_TRUE(target_info->is_filetype_handled_securely); - - // Try disabling the plugin. Handling should no longer be considered secure. - EnablePlugin(false, plugin_prefs, ppapi_plugin.path()); - target_info = RunDownloadTargetDeterminer( - GetPathInDownloadDir(kInitialPath), item.get()); - EXPECT_FALSE(target_info->is_filetype_handled_securely); - - // Now register an unsandboxed PPAPI plug-in. This plugin should not be - // considered secure. - ScopedRegisterInternalPlugin ppapi_unsandboxed_plugin( - plugin_service, - content::WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED, - test_download_dir().AppendASCII("ppapi-nosandbox"), - kTestMIMEType, - "fakeext"); - - target_info = RunDownloadTargetDeterminer( - GetPathInDownloadDir(kInitialPath), item.get()); - EXPECT_FALSE(target_info->is_filetype_handled_securely); -} - -// Check if secure handling of filetypes is determined correctly for NPAPI -// plugins. -TEST_F(DownloadTargetDeterminerTest, - TargetDeterminer_CheckForSecureHandling_NPAPI) { - // The ShadowingAtExitManager destroys the tainted PluginService instance. - base::ShadowingAtExitManager at_exit_manager; - - // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital - // path. - const base::FilePath::CharType kInitialPath[] = - FILE_PATH_LITERAL("some_path/bar.txt"); - const char kTestMIMEType[] = "application/x-example-should-not-exist"; - - DownloadTestCase kSecureHandlingTestCase = { - AUTOMATIC, - content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - "http://example.com/foo.fakeext", "", - FILE_PATH_LITERAL(""), - - FILE_PATH_LITERAL(""), - FILE_PATH_LITERAL("foo.fakeext"), - DownloadItem::TARGET_DISPOSITION_OVERWRITE, - - EXPECT_CRDOWNLOAD - }; - - content::PluginService* plugin_service = - content::PluginService::GetInstance(); - - // Can't run this test if NPAPI isn't supported. - if (!plugin_service->NPAPIPluginsSupported()) - return; - - // This creates a PluginPrefs for our TestingProfile. - scoped_refptr<PluginPrefs> plugin_prefs = - PluginPrefs::GetForTestingProfile(profile()); - - // Verify our test assumptions. - { - ForceRefreshOfPlugins(); - std::vector<content::WebPluginInfo> info; - ASSERT_FALSE(plugin_service->GetPluginInfoArray( - GURL(), kTestMIMEType, false, &info, NULL)); - ASSERT_EQ(0u, info.size()) - << "Name: " << info[0].name << ", Path: " << info[0].path.value(); + base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this); + base::RunLoop run_loop; + content::DownloadTargetCallback verifier_callback = + base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier, + factory.GetWeakPtr(), + run_loop.QuitClosure(), + test_case.general); + content::DownloadTargetCallback test_callback = + base::Bind(&IntermediatePathVerifier, + GetPathInDownloadDir(test_case.expected_intermediate_path), + verifier_callback); + DownloadTargetDeterminer::Start(item.get(), + GetPathInDownloadDir(kInitialPath), + download_prefs(), + delegate(), + test_callback); + run_loop.Run(); + ::testing::Mock::VerifyAndClearExpectations(delegate()); } - - ON_CALL(*delegate(), GetFileMimeType( - GetPathInDownloadDir(FILE_PATH_LITERAL("foo.fakeext")), _)) - .WillByDefault(WithArg<1>( - ScheduleCallback(kTestMIMEType))); - scoped_ptr<content::MockDownloadItem> item( - CreateActiveDownloadItem(1, kSecureHandlingTestCase)); - scoped_ptr<DownloadTargetInfo> target_info = - RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), - item.get()); - EXPECT_FALSE(target_info->is_filetype_handled_securely); - - // Register a NPAPI plugin. This should not count as handling the filetype - // securely. - ScopedRegisterInternalPlugin npapi_plugin( - plugin_service, - content::WebPluginInfo::PLUGIN_TYPE_NPAPI, - test_download_dir().AppendASCII("npapi"), - kTestMIMEType, - "fakeext"); - - target_info = RunDownloadTargetDeterminer( - GetPathInDownloadDir(kInitialPath), item.get()); - EXPECT_FALSE(target_info->is_filetype_handled_securely); } -#endif // ENABLE_PLUGINS } // namespace diff --git a/chrome/browser/download/download_target_info.h b/chrome/browser/download/download_target_info.h deleted file mode 100644 index 9a7a63b..0000000 --- a/chrome/browser/download/download_target_info.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TARGET_INFO_H_ -#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TARGET_INFO_H_ - -#include "base/files/file_path.h" -#include "content/public/browser/download_danger_type.h" -#include "content/public/browser/download_item.h" - -struct DownloadTargetInfo { - DownloadTargetInfo(); - ~DownloadTargetInfo(); - - // Final full target path of the download. Must be non-empty for the remaining - // fields to be considered valid. The path is a local file system path. Any - // existing file at this path should be overwritten. - base::FilePath target_path; - - // Disposition. This will be TARGET_DISPOSITION_PROMPT if the user was - // prompted during the process of determining the download target. Otherwise - // it will be TARGET_DISPOSITION_OVERWRITE. - content::DownloadItem::TargetDisposition target_disposition; - - // Danger type of the download. - content::DownloadDangerType danger_type; - - // Suggested intermediate path. The downloaded bytes should be written to this - // path until all the bytes are available and the user has accepted a - // dangerous download. At that point, the download can be renamed to - // |target_path|. - base::FilePath intermediate_path; - - // MIME type based on the file type of the download. This may be different - // from DownloadItem::GetMimeType() since the latter is based on the server - // response, and this one is based on the filename. - std::string mime_type; - - // Whether the |target_path| would be handled safely by the browser if it were - // to be opened with a file:// URL. This can be used later to decide how file - // opens should be handled. The file is considered to be handled safely if the - // filetype is supported by the renderer or a sandboxed plug-in. - bool is_filetype_handled_securely; -}; - -#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TARGET_INFO_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 67efa26..67df355 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -558,7 +558,6 @@ 'browser/download/download_target_determiner.cc', 'browser/download/download_target_determiner.h', 'browser/download/download_target_determiner_delegate.h', - 'browser/download/download_target_info.h', 'browser/download/download_ui_controller.cc', 'browser/download/download_ui_controller.h', 'browser/download/drag_download_item.h', diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index e4ad3d9..e436151 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -3060,14 +3060,6 @@ other types of suffix sets. </summary> </histogram> -<histogram name="Download.OpenMethod" enum="DownloadOpenMethod"> - <summary> - Invocation count for methods of opening a download. For some file types, - Chrome defaults to opening the file in the browser instead of invoking the - system handler. The user has the option of overriding this behavior. - </summary> -</histogram> - <histogram name="Download.OpensOutstanding"> <summary>The number of unopened downloads, when one is opened.</summary> </histogram> @@ -21417,12 +21409,6 @@ other types of suffix sets. <int value="8" label="POTENTIALLY_UNWANTED"/> </enum> -<enum name="DownloadOpenMethod" type="int"> - <int value="0" label="Opened with plaform handler by default"/> - <int value="1" label="Opened in browser by default"/> - <int value="2" label="Opened with plaform handler by user choice"/> -</enum> - <enum name="DownloadSavePackageEvent" type="int"> <int value="0" label="Started"/> <int value="1" label="Cancelled"/> |