summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/download/chrome_download_manager_delegate.cc55
-rw-r--r--chrome/browser/download/chrome_download_manager_delegate.h3
-rw-r--r--chrome/browser/download/download_prefs.cc45
-rw-r--r--chrome/browser/download/download_prefs.h13
-rw-r--r--chrome/browser/download/download_shelf_context_menu.cc84
-rw-r--r--chrome/browser/download/download_shelf_context_menu.h12
-rw-r--r--chrome/browser/download/download_target_determiner.cc66
-rw-r--r--chrome/browser/download/download_target_determiner.h24
-rw-r--r--chrome/browser/ui/pdf/adobe_reader_info_win.cc184
-rw-r--r--chrome/browser/ui/pdf/adobe_reader_info_win.h48
-rw-r--r--chrome/browser/ui/pdf/pdf_unsupported_feature.cc144
-rw-r--r--chrome/chrome_browser_ui.gypi2
-rw-r--r--chrome/common/pref_names.cc6
-rw-r--r--chrome/common/pref_names.h3
14 files changed, 552 insertions, 137 deletions
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
index 2a8d6c6..8e81539 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -184,29 +184,6 @@ std::string GetMimeType(const base::FilePath& path) {
return mime_type;
}
-bool IsOpenInBrowserPreferreredForFile(const base::FilePath& path) {
- // On Android, always prefer opening with an external app. On ChromeOS, there
- // are no external apps so just allow all opens to be handled by the "System."
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) && defined(ENABLE_PLUGINS)
- // TODO(asanka): Consider other file types and MIME types.
- // http://crbug.com/323561
- if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf")) ||
- path.MatchesExtension(FILE_PATH_LITERAL(".htm")) ||
- path.MatchesExtension(FILE_PATH_LITERAL(".html")) ||
- path.MatchesExtension(FILE_PATH_LITERAL(".shtm")) ||
- path.MatchesExtension(FILE_PATH_LITERAL(".shtml")) ||
- path.MatchesExtension(FILE_PATH_LITERAL(".svg")) ||
- path.MatchesExtension(FILE_PATH_LITERAL(".xht")) ||
- path.MatchesExtension(FILE_PATH_LITERAL(".xhtm")) ||
- path.MatchesExtension(FILE_PATH_LITERAL(".xhtml")) ||
- path.MatchesExtension(FILE_PATH_LITERAL(".xsl")) ||
- path.MatchesExtension(FILE_PATH_LITERAL(".xslt"))) {
- return true;
- }
-#endif
- return false;
-}
-
} // namespace
ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
@@ -722,3 +699,35 @@ void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined(
target_info->danger_type,
target_info->intermediate_path);
}
+
+bool ChromeDownloadManagerDelegate::IsOpenInBrowserPreferreredForFile(
+ const base::FilePath& path) {
+ // On Windows, PDFs should open in Acrobat Reader if the user chooses.
+#if defined(OS_WIN)
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf")) &&
+ DownloadTargetDeterminer::IsAdobeReaderUpToDate()) {
+ return !download_prefs_->ShouldOpenPdfInAdobeReader();
+ }
+#endif
+
+ // On Android, always prefer opening with an external app. On ChromeOS, there
+ // are no external apps so just allow all opens to be handled by the "System."
+#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) && defined(ENABLE_PLUGINS)
+ // TODO(asanka): Consider other file types and MIME types.
+ // http://crbug.com/323561
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".htm")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".html")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".shtm")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".shtml")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".svg")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".xht")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".xhtm")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".xhtml")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".xsl")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".xslt"))) {
+ return true;
+ }
+#endif
+ return false;
+}
diff --git a/chrome/browser/download/chrome_download_manager_delegate.h b/chrome/browser/download/chrome_download_manager_delegate.h
index 7cf2c45..ff89300 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.h
+++ b/chrome/browser/download/chrome_download_manager_delegate.h
@@ -170,6 +170,9 @@ class ChromeDownloadManagerDelegate
const content::DownloadTargetCallback& callback,
scoped_ptr<DownloadTargetInfo> target_info);
+ // Returns true if |path| should open in the browser.
+ bool IsOpenInBrowserPreferreredForFile(const base::FilePath& path);
+
Profile* profile_;
uint32 next_download_id_;
IdCallbackVector id_callbacks_;
diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc
index 750e11b..99abc2c 100644
--- a/chrome/browser/download/download_prefs.cc
+++ b/chrome/browser/download/download_prefs.cc
@@ -22,6 +22,7 @@
#include "chrome/browser/download/download_extensions.h"
#include "chrome/browser/download/download_service.h"
#include "chrome/browser/download/download_service_factory.h"
+#include "chrome/browser/download/download_target_determiner.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_paths.h"
@@ -37,6 +38,10 @@
#include "chrome/browser/chromeos/file_manager/path_util.h"
#endif
+#if defined(OS_WIN)
+#include "chrome/browser/ui/pdf/adobe_reader_info_win.h"
+#endif
+
using content::BrowserContext;
using content::BrowserThread;
using content::DownloadManager;
@@ -91,7 +96,7 @@ class DefaultDownloadDirectory {
DISALLOW_COPY_AND_ASSIGN(DefaultDownloadDirectory);
};
-static base::LazyInstance<DefaultDownloadDirectory>
+base::LazyInstance<DefaultDownloadDirectory>
g_default_download_directory = LAZY_INSTANCE_INITIALIZER;
} // namespace
@@ -126,6 +131,11 @@ DownloadPrefs::DownloadPrefs(Profile* profile) : profile_(profile) {
GetDefaultDownloadDirectoryForProfile()));
#endif // defined(OS_CHROMEOS)
+#if defined(OS_WIN)
+ should_open_pdf_in_adobe_reader_ =
+ prefs->GetBoolean(prefs::kOpenPdfDownloadInAdobeReader);
+#endif
+
// If the download path is dangerous we forcefully reset it. But if we do
// so we set a flag to make sure we only do it once, to avoid fighting
// the user if he really wants it on an unsafe place such as the desktop.
@@ -194,6 +204,12 @@ void DownloadPrefs::RegisterProfilePrefs(
prefs::kSaveFileDefaultDirectory,
default_download_path,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+#if defined(OS_WIN)
+ registry->RegisterBooleanPref(
+ prefs::kOpenPdfDownloadInAdobeReader,
+ false,
+ user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+#endif
}
base::FilePath DownloadPrefs::GetDefaultDownloadDirectoryForProfile() const {
@@ -268,6 +284,10 @@ bool DownloadPrefs::IsDownloadPathManaged() const {
}
bool DownloadPrefs::IsAutoOpenUsed() const {
+#if defined(OS_WIN)
+ if (ShouldOpenPdfInAdobeReader())
+ return true;
+#endif
return !auto_open_.empty();
}
@@ -278,6 +298,12 @@ bool DownloadPrefs::IsAutoOpenEnabledBasedOnExtension(
return false;
DCHECK(extension[0] == base::FilePath::kExtensionSeparator);
extension.erase(0, 1);
+#if defined(OS_WIN)
+ if (extension == FILE_PATH_LITERAL("pdf") &&
+ DownloadTargetDeterminer::IsAdobeReaderUpToDate() &&
+ ShouldOpenPdfInAdobeReader())
+ return true;
+#endif
return auto_open_.find(extension) != auto_open_.end();
}
@@ -305,7 +331,24 @@ void DownloadPrefs::DisableAutoOpenBasedOnExtension(
SaveAutoOpenState();
}
+#if defined(OS_WIN)
+void DownloadPrefs::SetShouldOpenPdfInAdobeReader(bool should_open) {
+ if (should_open_pdf_in_adobe_reader_ == should_open)
+ return;
+ should_open_pdf_in_adobe_reader_ = should_open;
+ profile_->GetPrefs()->SetBoolean(prefs::kOpenPdfDownloadInAdobeReader,
+ should_open);
+}
+
+bool DownloadPrefs::ShouldOpenPdfInAdobeReader() const {
+ return should_open_pdf_in_adobe_reader_;
+}
+#endif
+
void DownloadPrefs::ResetAutoOpen() {
+#if defined(OS_WIN)
+ SetShouldOpenPdfInAdobeReader(false);
+#endif
auto_open_.clear();
SaveAutoOpenState();
}
diff --git a/chrome/browser/download/download_prefs.h b/chrome/browser/download/download_prefs.h
index eca19d3..8d3db57 100644
--- a/chrome/browser/download/download_prefs.h
+++ b/chrome/browser/download/download_prefs.h
@@ -73,6 +73,15 @@ class DownloadPrefs {
// Disables auto-open based on file extension.
void DisableAutoOpenBasedOnExtension(const base::FilePath& file_name);
+#if defined(OS_WIN)
+ // Store the user preference to disk. If |should_open| is true, also disable
+ // the built-in PDF plugin. If |should_open| is false, enable the PDF plugin.
+ void SetShouldOpenPdfInAdobeReader(bool should_open);
+
+ // Return whether the user prefers to open PDF downloads in Adobe Reader.
+ bool ShouldOpenPdfInAdobeReader() const;
+#endif
+
void ResetAutoOpen();
private:
@@ -94,6 +103,10 @@ class DownloadPrefs {
AutoOpenCompareFunctor> AutoOpenSet;
AutoOpenSet auto_open_;
+#if defined(OS_WIN)
+ bool should_open_pdf_in_adobe_reader_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(DownloadPrefs);
};
diff --git a/chrome/browser/download/download_shelf_context_menu.cc b/chrome/browser/download/download_shelf_context_menu.cc
index b7f0858..55704c9 100644
--- a/chrome/browser/download/download_shelf_context_menu.cc
+++ b/chrome/browser/download/download_shelf_context_menu.cc
@@ -9,6 +9,7 @@
#include "chrome/browser/download/download_crx_util.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_prefs.h"
+#include "chrome/browser/download/download_target_determiner.h"
#include "chrome/browser/safe_browsing/download_protection_service.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/common/url_constants.h"
@@ -20,15 +21,18 @@
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
+#if defined(OS_WIN)
+#include "chrome/browser/ui/pdf/adobe_reader_info_win.h"
+#endif
+
using content::DownloadItem;
-using extensions::Extension;
namespace {
// Returns true if downloads resumption is enabled.
bool IsDownloadResumptionEnabled() {
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- return command_line.HasSwitch(switches::kEnableDownloadResumption);
+ return base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableDownloadResumption);
}
} // namespace
@@ -44,6 +48,14 @@ DownloadShelfContextMenu::DownloadShelfContextMenu(
navigator_(navigator) {
DCHECK(download_item_);
download_item_->AddObserver(this);
+
+#if defined(OS_WIN)
+ is_pdf_reader_up_to_date_ = false;
+ if (IsDownloadPdf() && IsAdobeReaderDefaultPDFViewer()) {
+ is_pdf_reader_up_to_date_ =
+ DownloadTargetDeterminer::IsAdobeReaderUpToDate();
+ }
+#endif // defined(OS_WIN)
}
ui::SimpleMenuModel* DownloadShelfContextMenu::GetMenuModel() {
@@ -97,6 +109,7 @@ bool DownloadShelfContextMenu::IsCommandIdEnabled(int command_id) const {
case LEARN_MORE_INTERRUPTED:
return true;
}
+ NOTREACHED();
return false;
}
@@ -109,6 +122,13 @@ bool DownloadShelfContextMenu::IsCommandIdChecked(int command_id) const {
return download_item_->GetOpenWhenComplete() ||
download_crx_util::IsExtensionDownload(*download_item_);
case ALWAYS_OPEN_TYPE:
+#if defined(OS_WIN)
+ if (CanOpenPdfInReader()) {
+ DownloadPrefs* prefs = DownloadPrefs::FromBrowserContext(
+ download_item_->GetBrowserContext());
+ return prefs->ShouldOpenPdfInAdobeReader();
+ }
+#endif
return download_item_->ShouldOpenFileBasedOnExtension();
case TOGGLE_PAUSE:
return download_item_->IsPaused();
@@ -116,6 +136,16 @@ bool DownloadShelfContextMenu::IsCommandIdChecked(int command_id) const {
return false;
}
+bool DownloadShelfContextMenu::IsCommandIdVisible(int command_id) const {
+ if (!download_item_)
+ return false;
+
+ if (command_id == PLATFORM_OPEN)
+ return (DownloadItemModel(download_item_).ShouldPreferOpeningInBrowser());
+
+ return true;
+}
+
void DownloadShelfContextMenu::ExecuteCommand(int command_id, int event_flags) {
if (!download_item_)
return;
@@ -128,13 +158,22 @@ void DownloadShelfContextMenu::ExecuteCommand(int command_id, int event_flags) {
download_item_->OpenDownload();
break;
case ALWAYS_OPEN_TYPE: {
+ bool is_checked = IsCommandIdChecked(ALWAYS_OPEN_TYPE);
DownloadPrefs* prefs = DownloadPrefs::FromBrowserContext(
download_item_->GetBrowserContext());
+#if defined(OS_WIN)
+ if (CanOpenPdfInReader()) {
+ prefs->SetShouldOpenPdfInAdobeReader(!is_checked);
+ DownloadItemModel(download_item_).SetShouldPreferOpeningInBrowser(
+ is_checked);
+ break;
+ }
+#endif
base::FilePath path = download_item_->GetTargetFilePath();
- if (!IsCommandIdChecked(ALWAYS_OPEN_TYPE))
- prefs->EnableAutoOpenBasedOnExtension(path);
- else
+ if (is_checked)
prefs->DisableAutoOpenBasedOnExtension(path);
+ else
+ prefs->EnableAutoOpenBasedOnExtension(path);
break;
}
case PLATFORM_OPEN:
@@ -203,7 +242,7 @@ base::string16 DownloadShelfContextMenu::GetLabelForCommandId(
return l10n_util::GetStringUTF16(IDS_DOWNLOAD_MENU_OPEN_WHEN_COMPLETE);
return l10n_util::GetStringUTF16(IDS_DOWNLOAD_MENU_OPEN);
case ALWAYS_OPEN_TYPE:
- return l10n_util::GetStringUTF16(IDS_DOWNLOAD_MENU_ALWAYS_OPEN_TYPE);
+ return l10n_util::GetStringUTF16(GetAlwaysOpenStringId());
case PLATFORM_OPEN:
return l10n_util::GetStringUTF16(IDS_DOWNLOAD_MENU_PLATFORM_OPEN);
case CANCEL:
@@ -250,7 +289,7 @@ ui::SimpleMenuModel* DownloadShelfContextMenu::GetInProgressMenuModel() {
in_progress_download_menu_model_->AddCheckItemWithStringId(
OPEN_WHEN_COMPLETE, IDS_DOWNLOAD_MENU_OPEN_WHEN_COMPLETE);
in_progress_download_menu_model_->AddCheckItemWithStringId(
- ALWAYS_OPEN_TYPE, IDS_DOWNLOAD_MENU_ALWAYS_OPEN_TYPE);
+ ALWAYS_OPEN_TYPE, GetAlwaysOpenStringId());
in_progress_download_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
in_progress_download_menu_model_->AddItemWithStringId(
TOGGLE_PAUSE, IDS_DOWNLOAD_MENU_PAUSE_ITEM);
@@ -272,10 +311,9 @@ ui::SimpleMenuModel* DownloadShelfContextMenu::GetFinishedMenuModel() {
finished_download_menu_model_->AddItemWithStringId(
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);
+ ALWAYS_OPEN_TYPE, GetAlwaysOpenStringId());
+ 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);
@@ -333,8 +371,7 @@ ui::SimpleMenuModel* DownloadShelfContextMenu::GetMaybeMaliciousMenuModel() {
return maybe_malicious_download_menu_model_.get();
}
-ui::SimpleMenuModel*
-DownloadShelfContextMenu::GetMaliciousMenuModel() {
+ui::SimpleMenuModel* DownloadShelfContextMenu::GetMaliciousMenuModel() {
if (malicious_download_menu_model_)
return malicious_download_menu_model_.get();
@@ -346,3 +383,22 @@ DownloadShelfContextMenu::GetMaliciousMenuModel() {
return malicious_download_menu_model_.get();
}
+
+int DownloadShelfContextMenu::GetAlwaysOpenStringId() const {
+#if defined(OS_WIN)
+ if (CanOpenPdfInReader())
+ return IDS_DOWNLOAD_MENU_ALWAYS_OPEN_PDF_IN_READER;
+#endif
+ return IDS_DOWNLOAD_MENU_ALWAYS_OPEN_TYPE;
+}
+
+#if defined(OS_WIN)
+bool DownloadShelfContextMenu::IsDownloadPdf() const {
+ base::FilePath path = download_item_->GetTargetFilePath();
+ return path.MatchesExtension(FILE_PATH_LITERAL(".pdf"));
+}
+
+bool DownloadShelfContextMenu::CanOpenPdfInReader() const {
+ return (is_pdf_reader_up_to_date_ && IsDownloadPdf());
+}
+#endif
diff --git a/chrome/browser/download/download_shelf_context_menu.h b/chrome/browser/download/download_shelf_context_menu.h
index 15b6504..a5d8a5eb 100644
--- a/chrome/browser/download/download_shelf_context_menu.h
+++ b/chrome/browser/download/download_shelf_context_menu.h
@@ -52,6 +52,7 @@ class DownloadShelfContextMenu : public ui::SimpleMenuModel::Delegate,
// ui::SimpleMenuModel::Delegate:
virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
+ virtual bool IsCommandIdVisible(int command_id) const OVERRIDE;
virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
virtual bool GetAcceleratorForCommandId(
int command_id,
@@ -73,6 +74,13 @@ class DownloadShelfContextMenu : public ui::SimpleMenuModel::Delegate,
ui::SimpleMenuModel* GetMaybeMaliciousMenuModel();
ui::SimpleMenuModel* GetMaliciousMenuModel();
+ int GetAlwaysOpenStringId() const;
+
+#if defined(OS_WIN)
+ bool IsDownloadPdf() const;
+ bool CanOpenPdfInReader() const;
+#endif
+
// We show slightly different menus if the download is in progress vs. if the
// download has finished.
scoped_ptr<ui::SimpleMenuModel> in_progress_download_menu_model_;
@@ -87,6 +95,10 @@ class DownloadShelfContextMenu : public ui::SimpleMenuModel::Delegate,
// Used to open tabs.
content::PageNavigator* navigator_;
+#if defined(OS_WIN)
+ bool is_pdf_reader_up_to_date_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(DownloadShelfContextMenu);
};
diff --git a/chrome/browser/download/download_target_determiner.cc b/chrome/browser/download/download_target_determiner.cc
index ee54bad..cca194b 100644
--- a/chrome/browser/download/download_target_determiner.cc
+++ b/chrome/browser/download/download_target_determiner.cc
@@ -36,6 +36,10 @@
#include "content/public/common/webplugininfo.h"
#endif
+#if defined(OS_WIN)
+#include "chrome/browser/ui/pdf/adobe_reader_info_win.h"
+#endif
+
using content::BrowserThread;
using content::DownloadItem;
@@ -58,7 +62,12 @@ void VisitCountsToVisitedBefore(
(first_visit.LocalMidnight() < base::Time::Now().LocalMidnight()));
}
-} // namespace
+#if defined(OS_WIN)
+// Keeps track of whether Adobe Reader is up to date.
+bool g_is_adobe_reader_up_to_date_ = false;
+#endif
+
+} // namespace
DownloadTargetInfo::DownloadTargetInfo()
: is_filetype_handled_safely(false) {}
@@ -133,6 +142,9 @@ void DownloadTargetDeterminer::DoLoop() {
case STATE_DETERMINE_IF_HANDLED_SAFELY_BY_BROWSER:
result = DoDetermineIfHandledSafely();
break;
+ case STATE_DETERMINE_IF_ADOBE_READER_UP_TO_DATE:
+ result = DoDetermineIfAdobeReaderUpToDate();
+ break;
case STATE_CHECK_DOWNLOAD_URL:
result = DoCheckDownloadUrl();
break;
@@ -449,8 +461,8 @@ void IsHandledBySafePlugin(content::ResourceContext* resource_context,
BrowserThread::UI, FROM_HERE, base::Bind(callback, is_handled_safely));
}
-} // namespace
-#endif // ENABLE_PLUGINS
+} // namespace
+#endif // defined(ENABLE_PLUGINS)
DownloadTargetDeterminer::Result
DownloadTargetDeterminer::DoDetermineIfHandledSafely() {
@@ -459,7 +471,7 @@ DownloadTargetDeterminer::Result
DCHECK(!local_path_.empty());
DCHECK(!is_filetype_handled_safely_);
- next_state_ = STATE_CHECK_DOWNLOAD_URL;
+ next_state_ = STATE_DETERMINE_IF_ADOBE_READER_UP_TO_DATE;
if (mime_type_.empty())
return CONTINUE;
@@ -487,14 +499,51 @@ DownloadTargetDeterminer::Result
#endif
}
+#if defined(ENABLE_PLUGINS)
void DownloadTargetDeterminer::DetermineIfHandledSafelyDone(
bool is_handled_safely) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DVLOG(20) << "Is file type handled safely: " << is_filetype_handled_safely_;
- DCHECK_EQ(STATE_CHECK_DOWNLOAD_URL, next_state_);
+ DCHECK_EQ(STATE_DETERMINE_IF_ADOBE_READER_UP_TO_DATE, next_state_);
is_filetype_handled_safely_ = is_handled_safely;
DoLoop();
}
+#endif
+
+DownloadTargetDeterminer::Result
+ DownloadTargetDeterminer::DoDetermineIfAdobeReaderUpToDate() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ next_state_ = STATE_CHECK_DOWNLOAD_URL;
+
+#if defined(OS_WIN)
+ if (!local_path_.MatchesExtension(FILE_PATH_LITERAL(".pdf")))
+ return CONTINUE;
+ if (!IsAdobeReaderDefaultPDFViewer())
+ return CONTINUE;
+
+ base::PostTaskAndReplyWithResult(
+ BrowserThread::GetBlockingPool(),
+ FROM_HERE,
+ base::Bind(&::IsAdobeReaderUpToDate),
+ base::Bind(&DownloadTargetDeterminer::DetermineIfAdobeReaderUpToDateDone,
+ weak_ptr_factory_.GetWeakPtr()));
+ return QUIT_DOLOOP;
+#else
+ return CONTINUE;
+#endif
+}
+
+#if defined(OS_WIN)
+void DownloadTargetDeterminer::DetermineIfAdobeReaderUpToDateDone(
+ bool adobe_reader_up_to_date) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DVLOG(20) << "Is Adobe Reader Up To Date: " << adobe_reader_up_to_date;
+ DCHECK_EQ(STATE_CHECK_DOWNLOAD_URL, next_state_);
+ g_is_adobe_reader_up_to_date_ = adobe_reader_up_to_date;
+ DoLoop();
+}
+#endif
DownloadTargetDeterminer::Result
DownloadTargetDeterminer::DoCheckDownloadUrl() {
@@ -828,3 +877,10 @@ base::FilePath DownloadTargetDeterminer::GetCrDownloadPath(
const base::FilePath& suggested_path) {
return base::FilePath(suggested_path.value() + kCrdownloadSuffix);
}
+
+#if defined(OS_WIN)
+// static
+bool DownloadTargetDeterminer::IsAdobeReaderUpToDate() {
+ return g_is_adobe_reader_up_to_date_;
+}
+#endif
diff --git a/chrome/browser/download/download_target_determiner.h b/chrome/browser/download/download_target_determiner.h
index f57341d..8cca804 100644
--- a/chrome/browser/download/download_target_determiner.h
+++ b/chrome/browser/download/download_target_determiner.h
@@ -80,6 +80,13 @@ class DownloadTargetDeterminer
// Returns a .crdownload intermediate path for the |suggested_path|.
static base::FilePath GetCrDownloadPath(const base::FilePath& suggested_path);
+#if defined(OS_WIN)
+ // Returns true if Adobe Reader is up to date. This information refreshed
+ // only when Start() gets called for a PDF and Adobe Reader is the default
+ // System PDF viewer.
+ static bool IsAdobeReaderUpToDate();
+#endif
+
private:
// The main workflow is controlled via a set of state transitions. Each state
// has an associated handler. The handler for STATE_FOO is DoFoo. Each handler
@@ -94,6 +101,7 @@ class DownloadTargetDeterminer
STATE_DETERMINE_LOCAL_PATH,
STATE_DETERMINE_MIME_TYPE,
STATE_DETERMINE_IF_HANDLED_SAFELY_BY_BROWSER,
+ STATE_DETERMINE_IF_ADOBE_READER_UP_TO_DATE,
STATE_CHECK_DOWNLOAD_URL,
STATE_CHECK_VISITED_REFERRER_BEFORE,
STATE_DETERMINE_INTERMEDIATE_PATH,
@@ -206,12 +214,26 @@ class DownloadTargetDeterminer
// Determine if the file type can be handled safely by the browser if it were
// to be opened via a file:// URL.
// Next state:
- // - STATE_CHECK_DOWNLOAD_URL.
+ // - STATE_DETERMINE_IF_ADOBE_READER_UP_TO_DATE.
Result DoDetermineIfHandledSafely();
+#if defined(ENABLE_PLUGINS)
// Callback invoked when a decision is available about whether the file type
// can be handled safely by the browser.
void DetermineIfHandledSafelyDone(bool is_handled_safely);
+#endif
+
+ // Determine if Adobe Reader is up to date. Only do the check on Windows for
+ // .pdf file targets.
+ // Next state:
+ // - STATE_CHECK_DOWNLOAD_URL.
+ Result DoDetermineIfAdobeReaderUpToDate();
+
+#if defined(OS_WIN)
+ // Callback invoked when a decision is available about whether Adobe Reader
+ // is up to date.
+ void DetermineIfAdobeReaderUpToDateDone(bool adobe_reader_up_to_date);
+#endif
// Checks whether the downloaded URL is malicious. Invokes the
// DownloadProtectionService via the delegate.
diff --git a/chrome/browser/ui/pdf/adobe_reader_info_win.cc b/chrome/browser/ui/pdf/adobe_reader_info_win.cc
new file mode 100644
index 0000000..601f157
--- /dev/null
+++ b/chrome/browser/ui/pdf/adobe_reader_info_win.cc
@@ -0,0 +1,184 @@
+// Copyright 2014 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.
+
+#include "chrome/browser/ui/pdf/adobe_reader_info_win.h"
+
+#include <shlwapi.h>
+
+#include <algorithm>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/file_version_info.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/win/registry.h"
+#include "base/win/windows_version.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/plugins/plugin_finder.h"
+#include "chrome/browser/plugins/plugin_metadata.h"
+#include "chrome/browser/plugins/plugin_prefs.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "content/public/browser/plugin_service.h"
+
+namespace {
+
+// Hardcoded value for the secure version of Acrobat Reader.
+const char kSecureVersion[] = "11.0.7.79";
+
+const char kAdobeReaderIdentifier[] = "adobe-reader";
+const char kPdfMimeType[] = "application/pdf";
+const base::char16 kRegistryAcrobat[] = L"Acrobat.exe";
+const base::char16 kRegistryAcrobatReader[] = L"AcroRd32.exe";
+const base::char16 kRegistryApps[] =
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths";
+const base::char16 kRegistryPath[] = L"Path";
+
+// Gets the installed path for a registered app.
+base::FilePath GetInstalledPath(const base::char16* app) {
+ base::string16 reg_path(kRegistryApps);
+ reg_path.append(L"\\");
+ reg_path.append(app);
+
+ base::FilePath filepath;
+ base::win::RegKey hkcu_key(HKEY_CURRENT_USER, reg_path.c_str(), KEY_READ);
+ base::string16 path;
+ // As of Win7 AppPaths can also be registered in HKCU: http://goo.gl/UgFOf.
+ if (base::win::GetVersion() >= base::win::VERSION_WIN7 &&
+ hkcu_key.ReadValue(kRegistryPath, &path) == ERROR_SUCCESS) {
+ filepath = base::FilePath(path);
+ } else {
+ base::win::RegKey hklm_key(HKEY_LOCAL_MACHINE, reg_path.c_str(), KEY_READ);
+ if (hklm_key.ReadValue(kRegistryPath, &path) == ERROR_SUCCESS) {
+ filepath = base::FilePath(path);
+ }
+ }
+
+ return filepath;
+}
+
+bool IsPdfMimeType(const content::WebPluginMimeType& plugin_mime_type) {
+ return plugin_mime_type.mime_type == kPdfMimeType;
+}
+
+AdobeReaderPluginInfo GetReaderPlugin(
+ Profile* profile,
+ const std::vector<content::WebPluginInfo>& plugins) {
+ AdobeReaderPluginInfo reader_info;
+ reader_info.is_installed = false;
+ reader_info.is_enabled = false;
+ reader_info.is_secure = false;
+
+ PluginFinder* plugin_finder = PluginFinder::GetInstance();
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ const content::WebPluginInfo& plugin = plugins[i];
+ if (plugin.is_pepper_plugin())
+ continue;
+ if (std::find_if(plugin.mime_types.begin(), plugin.mime_types.end(),
+ IsPdfMimeType) == plugin.mime_types.end())
+ continue;
+ scoped_ptr<PluginMetadata> plugin_metadata(
+ plugin_finder->GetPluginMetadata(plugins[i]));
+ if (plugin_metadata->identifier() != kAdobeReaderIdentifier)
+ continue;
+
+ reader_info.is_installed = true;
+
+ if (profile) {
+ PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile);
+ PluginPrefs::PolicyStatus plugin_status =
+ plugin_prefs->PolicyStatusForPlugin(plugin_metadata->name());
+ reader_info.is_enabled = plugin_status != PluginPrefs::POLICY_DISABLED;
+ }
+
+ PluginMetadata::SecurityStatus security_status =
+ plugin_metadata->GetSecurityStatus(plugins[i]);
+ reader_info.is_secure =
+ security_status == PluginMetadata::SECURITY_STATUS_UP_TO_DATE;
+
+ reader_info.plugin_info = plugins[i];
+ break;
+ }
+ return reader_info;
+}
+
+void OnGotPluginInfo(Profile* profile,
+ const GetAdobeReaderPluginInfoCallback& callback,
+ const std::vector<content::WebPluginInfo>& plugins) {
+ if (!g_browser_process->profile_manager()->IsValidProfile(profile))
+ profile = NULL;
+ callback.Run(GetReaderPlugin(profile, plugins));
+}
+
+bool IsAdobeReaderDefaultPDFViewerInternal(base::FilePath* path) {
+ base::char16 app_cmd_buf[MAX_PATH];
+ DWORD app_cmd_buf_len = MAX_PATH;
+ HRESULT hr = AssocQueryString(ASSOCF_NONE, ASSOCSTR_COMMAND, L".pdf", L"open",
+ app_cmd_buf, &app_cmd_buf_len);
+ if (FAILED(hr))
+ return false;
+
+ // Looks for the install paths for Acrobat / Reader.
+ base::FilePath install_path = GetInstalledPath(kRegistryAcrobatReader);
+ if (install_path.empty())
+ install_path = GetInstalledPath(kRegistryAcrobat);
+ if (install_path.empty())
+ return false;
+
+ base::string16 app_cmd(app_cmd_buf);
+ bool found = app_cmd.find(install_path.value()) != base::string16::npos;
+ if (found && path)
+ *path = install_path;
+ return found;
+}
+
+} // namespace
+
+void GetAdobeReaderPluginInfoAsync(
+ Profile* profile,
+ const GetAdobeReaderPluginInfoCallback& callback) {
+ DCHECK(!callback.is_null());
+ content::PluginService::GetInstance()->GetPlugins(
+ base::Bind(&OnGotPluginInfo, profile, callback));
+}
+
+bool GetAdobeReaderPluginInfo(Profile* profile,
+ AdobeReaderPluginInfo* reader_info) {
+ DCHECK(reader_info);
+ std::vector<content::WebPluginInfo> plugins;
+ bool up_to_date = content::PluginService::GetInstance()->GetPluginInfoArray(
+ GURL(), kPdfMimeType, false, &plugins, NULL);
+ *reader_info = GetReaderPlugin(profile, plugins);
+ return up_to_date;
+}
+
+bool IsAdobeReaderDefaultPDFViewer() {
+ return IsAdobeReaderDefaultPDFViewerInternal(NULL);
+}
+
+bool IsAdobeReaderUpToDate() {
+ base::FilePath install_path;
+ bool is_default = IsAdobeReaderDefaultPDFViewerInternal(&install_path);
+ if (!is_default)
+ return false;
+
+ scoped_ptr<FileVersionInfo> file_version_info(
+ FileVersionInfo::CreateFileVersionInfo(install_path));
+ if (!file_version_info)
+ return false;
+
+ std::string reader_version =
+ base::UTF16ToUTF8(file_version_info->product_version());
+ // Convert 1.2.03.45 to 1.2.3.45 so base::Version considers it as valid.
+ for (int i = 1; i <= 9; ++i) {
+ std::string from = base::StringPrintf(".0%d", i);
+ std::string to = base::StringPrintf(".%d", i);
+ ReplaceSubstringsAfterOffset(&reader_version, 0, from, to);
+ }
+ base::Version file_version(reader_version);
+ return file_version.IsValid() && !file_version.IsOlderThan(kSecureVersion);
+}
diff --git a/chrome/browser/ui/pdf/adobe_reader_info_win.h b/chrome/browser/ui/pdf/adobe_reader_info_win.h
new file mode 100644
index 0000000..9666d8b
--- /dev/null
+++ b/chrome/browser/ui/pdf/adobe_reader_info_win.h
@@ -0,0 +1,48 @@
+// Copyright 2014 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_UI_PDF_ADOBE_READER_INFO_WIN_H_
+#define CHROME_BROWSER_UI_PDF_ADOBE_READER_INFO_WIN_H_
+
+#include "base/basictypes.h"
+#include "base/callback_forward.h"
+#include "content/public/common/webplugininfo.h"
+
+class Profile;
+
+struct AdobeReaderPluginInfo {
+ bool is_installed;
+ bool is_enabled; // Only valid in the context of a given Profile.
+ bool is_secure; // Whether the plugin is up to date.
+ content::WebPluginInfo plugin_info;
+};
+
+typedef base::Callback<void(const AdobeReaderPluginInfo&)>
+ GetAdobeReaderPluginInfoCallback;
+
+// Fetches information about the Adobe Reader plugin asynchronously.
+// If |profile| is NULL, then the plugin's enable status cannot be
+// determined.
+void GetAdobeReaderPluginInfoAsync(
+ Profile* profile,
+ const GetAdobeReaderPluginInfoCallback& callback);
+
+// Fetches information about the Adobe Reader plugin synchronously.
+// Returns true if the plugin info is not stale.
+// If |profile| is NULL, then the plugin's enable status cannot be
+// determined.
+bool GetAdobeReaderPluginInfo(Profile* profile,
+ AdobeReaderPluginInfo* reader_info);
+
+// Returns true if Adobe Reader or Adobe Acrobat is the default viewer for the
+// .pdf extension.
+bool IsAdobeReaderDefaultPDFViewer();
+
+// If Adobe Reader or Adobe Acrobat is program associated with the .pdf viewer,
+// return true if the executable is up to date.
+// If Reader/Acrobat is not the default .pdf handler, return false.
+// This function does blocking I/O, since it needs to read from the disk.
+bool IsAdobeReaderUpToDate();
+
+#endif // CHROME_BROWSER_UI_PDF_ADOBE_READER_INFO_WIN_H_
diff --git a/chrome/browser/ui/pdf/pdf_unsupported_feature.cc b/chrome/browser/ui/pdf/pdf_unsupported_feature.cc
index 6252408..4ae28c0 100644
--- a/chrome/browser/ui/pdf/pdf_unsupported_feature.cc
+++ b/chrome/browser/ui/pdf/pdf_unsupported_feature.cc
@@ -6,13 +6,9 @@
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
-#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "base/version.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
-#include "chrome/browser/plugins/plugin_finder.h"
#include "chrome/browser/plugins/plugin_metadata.h"
#include "chrome/browser/plugins/plugin_prefs.h"
#include "chrome/browser/profiles/profile.h"
@@ -21,46 +17,39 @@
#include "chrome/browser/ui/pdf/open_pdf_in_reader_prompt_delegate.h"
#include "chrome/browser/ui/pdf/pdf_tab_helper.h"
#include "chrome/common/chrome_content_client.h"
-#include "chrome/common/pref_names.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/interstitial_page_delegate.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
-#include "content/public/browser/plugin_service.h"
+#include "content/public/browser/page_navigator.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
-#include "content/public/common/page_transition_types.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
-#include "ui/gfx/image/image.h"
#if defined(OS_WIN)
#include "base/win/metro.h"
+#include "chrome/browser/ui/pdf/adobe_reader_info_win.h"
#endif
using base::UserMetricsAction;
using content::InterstitialPage;
using content::OpenURLParams;
-using content::PluginService;
using content::Referrer;
using content::WebContents;
using content::WebPluginInfo;
+#if defined(OS_WIN)
namespace {
const char kAdobeReaderUpdateUrl[] = "http://www.adobe.com/go/getreader_chrome";
-#if defined(OS_WIN) && defined(ENABLE_PLUGIN_INSTALLATION)
-const char kAdobeReaderIdentifier[] = "adobe-reader";
-#endif
-
// The prompt delegate used to ask the user if they want to use Adobe Reader
// by default.
class PDFEnableAdobeReaderPromptDelegate
@@ -244,10 +233,9 @@ class PDFUnsupportedFeatureInterstitial
class PDFUnsupportedFeaturePromptDelegate
: public OpenPDFInReaderPromptDelegate {
public:
- // |reader| is NULL if Adobe Reader isn't installed.
- PDFUnsupportedFeaturePromptDelegate(WebContents* web_contents,
- const content::WebPluginInfo* reader,
- PluginFinder* plugin_finder);
+ PDFUnsupportedFeaturePromptDelegate(
+ WebContents* web_contents,
+ const AdobeReaderPluginInfo& reader_info);
virtual ~PDFUnsupportedFeaturePromptDelegate();
// OpenPDFInReaderPromptDelegate:
@@ -261,38 +249,19 @@ class PDFUnsupportedFeaturePromptDelegate
private:
WebContents* web_contents_;
- bool reader_installed_;
- bool reader_vulnerable_;
- WebPluginInfo reader_webplugininfo_;
+ const AdobeReaderPluginInfo reader_info_;
DISALLOW_IMPLICIT_CONSTRUCTORS(PDFUnsupportedFeaturePromptDelegate);
};
PDFUnsupportedFeaturePromptDelegate::PDFUnsupportedFeaturePromptDelegate(
WebContents* web_contents,
- const content::WebPluginInfo* reader,
- PluginFinder* plugin_finder)
+ const AdobeReaderPluginInfo& reader_info)
: web_contents_(web_contents),
- reader_installed_(!!reader),
- reader_vulnerable_(false) {
- if (!reader_installed_) {
- content::RecordAction(
- UserMetricsAction("PDF_InstallReaderInfoBarShown"));
- return;
- }
-
- content::RecordAction(UserMetricsAction("PDF_UseReaderInfoBarShown"));
- reader_webplugininfo_ = *reader;
-
-#if defined(ENABLE_PLUGIN_INSTALLATION)
- scoped_ptr<PluginMetadata> plugin_metadata(
- plugin_finder->GetPluginMetadata(reader_webplugininfo_));
-
- reader_vulnerable_ = plugin_metadata->GetSecurityStatus(*reader) !=
- PluginMetadata::SECURITY_STATUS_UP_TO_DATE;
-#else
- NOTREACHED();
-#endif
+ reader_info_(reader_info) {
+ content::RecordAction(reader_info_.is_installed ?
+ UserMetricsAction("PDF_UseReaderInfoBarShown") :
+ UserMetricsAction("PDF_InstallReaderInfoBarShown"));
}
PDFUnsupportedFeaturePromptDelegate::~PDFUnsupportedFeaturePromptDelegate() {
@@ -304,15 +273,12 @@ base::string16 PDFUnsupportedFeaturePromptDelegate::GetMessageText() const {
base::string16 PDFUnsupportedFeaturePromptDelegate::GetAcceptButtonText()
const {
-#if defined(OS_WIN)
if (base::win::IsMetroProcess())
return l10n_util::GetStringUTF16(IDS_PDF_BUBBLE_METRO_MODE_LINK);
-#endif
- if (reader_installed_)
- return l10n_util::GetStringUTF16(IDS_PDF_BUBBLE_OPEN_IN_READER_LINK);
-
- return l10n_util::GetStringUTF16(IDS_PDF_BUBBLE_INSTALL_READER_LINK);
+ return l10n_util::GetStringUTF16(
+ reader_info_.is_installed ? IDS_PDF_BUBBLE_OPEN_IN_READER_LINK
+ : IDS_PDF_BUBBLE_INSTALL_READER_LINK);
}
base::string16 PDFUnsupportedFeaturePromptDelegate::GetCancelButtonText()
@@ -326,14 +292,12 @@ bool PDFUnsupportedFeaturePromptDelegate::ShouldExpire(
}
void PDFUnsupportedFeaturePromptDelegate::Accept() {
-#if defined(OS_WIN)
if (base::win::IsMetroProcess()) {
chrome::AttemptRestartWithModeSwitch();
return;
}
-#endif
- if (!reader_installed_) {
+ if (!reader_info_.is_installed) {
content::RecordAction(UserMetricsAction("PDF_InstallReaderInfoBarOK"));
OpenReaderUpdateURL(web_contents_);
return;
@@ -341,8 +305,9 @@ void PDFUnsupportedFeaturePromptDelegate::Accept() {
content::RecordAction(UserMetricsAction("PDF_UseReaderInfoBarOK"));
- if (reader_vulnerable_) {
- new PDFUnsupportedFeatureInterstitial(web_contents_, reader_webplugininfo_);
+ if (!reader_info_.is_secure) {
+ new PDFUnsupportedFeatureInterstitial(web_contents_,
+ reader_info_.plugin_info);
return;
}
@@ -351,61 +316,54 @@ void PDFUnsupportedFeaturePromptDelegate::Accept() {
OpenPDFInReaderPromptDelegate* delegate =
new PDFEnableAdobeReaderPromptDelegate(profile);
- OpenUsingReader(web_contents_, reader_webplugininfo_, delegate);
+ OpenUsingReader(web_contents_, reader_info_.plugin_info, delegate);
}
void PDFUnsupportedFeaturePromptDelegate::Cancel() {
- content::RecordAction(reader_installed_ ?
+ content::RecordAction(reader_info_.is_installed ?
UserMetricsAction("PDF_UseReaderInfoBarCancel") :
UserMetricsAction("PDF_InstallReaderInfoBarCancel"));
}
-#if defined(OS_WIN) && defined(ENABLE_PLUGIN_INSTALLATION)
-void GotPluginsCallback(int process_id,
- int routing_id,
- const std::vector<content::WebPluginInfo>& plugins) {
- WebContents* web_contents =
- tab_util::GetWebContentsByID(process_id, routing_id);
- if (!web_contents)
+void MaybeShowOpenPDFInReaderPrompt(WebContents* web_contents,
+ const AdobeReaderPluginInfo& reader_info) {
+ // If the Reader plugin is disabled by policy, don't prompt them.
+ if (!reader_info.is_installed || !reader_info.is_enabled)
return;
- const content::WebPluginInfo* reader = NULL;
- PluginFinder* plugin_finder = PluginFinder::GetInstance();
- for (size_t i = 0; i < plugins.size(); ++i) {
- scoped_ptr<PluginMetadata> plugin_metadata(
- plugin_finder->GetPluginMetadata(plugins[i]));
- if (plugin_metadata->identifier() != kAdobeReaderIdentifier)
- continue;
-
- DCHECK(!reader);
- reader = &plugins[i];
- // If the Reader plugin is disabled by policy, don't prompt them.
- Profile* profile =
- Profile::FromBrowserContext(web_contents->GetBrowserContext());
- PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile);
- if (plugin_prefs->PolicyStatusForPlugin(plugin_metadata->name()) ==
- PluginPrefs::POLICY_DISABLED) {
- return;
- }
- break;
- }
-
scoped_ptr<OpenPDFInReaderPromptDelegate> prompt(
- new PDFUnsupportedFeaturePromptDelegate(
- web_contents, reader, plugin_finder));
+ new PDFUnsupportedFeaturePromptDelegate(web_contents, reader_info));
PDFTabHelper* pdf_tab_helper = PDFTabHelper::FromWebContents(web_contents);
pdf_tab_helper->ShowOpenInReaderPrompt(prompt.Pass());
}
-#endif // defined(OS_WIN) && defined(ENABLE_PLUGIN_INSTALLATION)
+
+void GotPluginsCallback(int process_id,
+ int routing_id,
+ const AdobeReaderPluginInfo& reader_info) {
+ WebContents* web_contents =
+ tab_util::GetWebContentsByID(process_id, routing_id);
+ if (web_contents)
+ MaybeShowOpenPDFInReaderPrompt(web_contents, reader_info);
+}
} // namespace
+#endif // defined(OS_WIN)
-void PDFHasUnsupportedFeature(content::WebContents* web_contents) {
-#if defined(OS_WIN) && defined(ENABLE_PLUGIN_INSTALLATION)
+void PDFHasUnsupportedFeature(WebContents* web_contents) {
+#if defined(OS_WIN)
// Only works for Windows for now. For Mac, we'll have to launch the file
// externally since Adobe Reader doesn't work inside Chrome.
- PluginService::GetInstance()->GetPlugins(base::Bind(&GotPluginsCallback,
- web_contents->GetRenderProcessHost()->GetID(),
- web_contents->GetRenderViewHost()->GetRoutingID()));
-#endif
+ Profile* profile =
+ Profile::FromBrowserContext(web_contents->GetBrowserContext());
+ AdobeReaderPluginInfo reader_info;
+ if (GetAdobeReaderPluginInfo(profile, &reader_info)) {
+ MaybeShowOpenPDFInReaderPrompt(web_contents, reader_info);
+ return;
+ }
+ GetAdobeReaderPluginInfoAsync(
+ profile,
+ base::Bind(&GotPluginsCallback,
+ web_contents->GetRenderProcessHost()->GetID(),
+ web_contents->GetRenderViewHost()->GetRoutingID()));
+#endif // defined(OS_WIN)
}
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index d1b558bd..0eb98a2 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -1508,6 +1508,8 @@
'browser/ui/panels/stacked_panel_collection.h',
'browser/ui/panels/stacked_panel_drag_handler.cc',
'browser/ui/panels/stacked_panel_drag_handler.h',
+ 'browser/ui/pdf/adobe_reader_info_win.cc',
+ 'browser/ui/pdf/adobe_reader_info_win.h',
'browser/ui/pdf/open_pdf_in_reader_prompt_delegate.h',
'browser/ui/pdf/pdf_tab_helper.cc',
'browser/ui/pdf/pdf_tab_helper.h',
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index fcf8671..6b00c153 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1417,6 +1417,12 @@ const char kDownloadDefaultDirectory[] = "download.default_directory";
// upgrade a unsafe location to a safe location.
const char kDownloadDirUpgraded[] = "download.directory_upgrade";
+#if defined(OS_WIN)
+// Whether downloaded PDFs should be opened in Adobe Acrobat Reader.
+const char kOpenPdfDownloadInAdobeReader[] =
+ "download.open_pdf_in_adobe_reader";
+#endif
+
// String which specifies where to save html files to by default.
const char kSaveFileDefaultDirectory[] = "savefile.default_directory";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 38cbbe6..d821fa2 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -472,6 +472,9 @@ extern const char kMemoryCacheSize[];
extern const char kDownloadDefaultDirectory[];
extern const char kDownloadExtensionsToOpen[];
extern const char kDownloadDirUpgraded[];
+#if defined(OS_WIN)
+extern const char kOpenPdfDownloadInAdobeReader[];
+#endif
extern const char kSaveFileDefaultDirectory[];
extern const char kSaveFileType[];