summaryrefslogtreecommitdiffstats
path: root/chrome/browser/pdf_unsupported_feature.cc
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-22 00:05:17 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-22 00:05:17 +0000
commitc8f73aba9f1fd8b2e0a34fcca08a1e968ddd8244 (patch)
treed2658c6f1da345a1f38531809250c934dd4d73fa /chrome/browser/pdf_unsupported_feature.cc
parent090d7108424b5a8600e1b590b2227e52f23d6e7e (diff)
downloadchromium_src-c8f73aba9f1fd8b2e0a34fcca08a1e968ddd8244.zip
chromium_src-c8f73aba9f1fd8b2e0a34fcca08a1e968ddd8244.tar.gz
chromium_src-c8f73aba9f1fd8b2e0a34fcca08a1e968ddd8244.tar.bz2
When we detect a PDF with an unsupported feature, ask the user if they want to view it with Adobe Reader if it's installed. If it's not, ask them if they want to launch the url to install it. If it's installed and out of date, show an interstitial.
BUG=65339 Review URL: http://codereview.chromium.org/6259008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72240 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/pdf_unsupported_feature.cc')
-rw-r--r--chrome/browser/pdf_unsupported_feature.cc231
1 files changed, 231 insertions, 0 deletions
diff --git a/chrome/browser/pdf_unsupported_feature.cc b/chrome/browser/pdf_unsupported_feature.cc
new file mode 100644
index 0000000..2e89da2
--- /dev/null
+++ b/chrome/browser/pdf_unsupported_feature.cc
@@ -0,0 +1,231 @@
+// Copyright (c) 2011 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/pdf_unsupported_feature.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "base/version.h"
+#include "chrome/browser/plugin_service.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/tab_contents/infobar_delegate.h"
+#include "chrome/browser/tab_contents/interstitial_page.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/jstemplate_builder.h"
+#include "grit/browser_resources.h"
+#include "grit/generated_resources.h"
+#include "webkit/plugins/npapi/plugin_group.h"
+#include "webkit/plugins/npapi/plugin_list.h"
+#include "webkit/plugins/npapi/webplugininfo.h"
+
+using webkit::npapi::PluginGroup;
+using webkit::npapi::PluginList;
+using webkit::npapi::WebPluginInfo;
+
+// Only launch Adobe Reader X or later.
+static const uint16 kMinReaderVersionToUse = 10;
+
+namespace {
+
+// Launch the url to get the latest Adbobe Reader installer.
+void OpenReaderUpdateURL(TabContents* tab) {
+ tab->OpenURL(GURL(PluginGroup::kAdobeReaderUpdateURL), GURL(), CURRENT_TAB,
+ PageTransition::LINK);
+}
+
+// Opens the PDF using Adobe Reader.
+void OpenUsingReader(TabContents* tab, const WebPluginInfo& reader_plugin) {
+ PluginService::OverriddenPlugin plugin;
+ plugin.render_process_id = tab->GetRenderProcessHost()->id();
+ plugin.render_view_id = tab->render_view_host()->routing_id();
+ plugin.url = tab->GetURL();
+ plugin.plugin = reader_plugin;
+
+ PluginService::GetInstance()->OverridePluginForTab(plugin);
+ tab->render_view_host()->ReloadFrame();
+}
+
+// An interstitial to be used when the user chooses to open a PDF using Adobe
+// Reader, but it is out of date.
+class PDFUnsupportedFeatureInterstitial : public InterstitialPage {
+ public:
+ PDFUnsupportedFeatureInterstitial(
+ TabContents* tab,
+ const WebPluginInfo& reader_webplugininfo)
+ : InterstitialPage(tab, false, tab->GetURL()),
+ reader_webplugininfo_(reader_webplugininfo) {
+ }
+
+ protected:
+ // InterstitialPage implementation.
+ virtual std::string GetHTMLContents() {
+ DictionaryValue strings;
+ strings.SetString(
+ "title",
+ l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_TITLE));
+ strings.SetString(
+ "headLine",
+ l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_BODY));
+ strings.SetString(
+ "update",
+ l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_UPDATE));
+ strings.SetString(
+ "open_with_reader",
+ l10n_util::GetStringUTF16(
+ IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_PROCEED));
+ strings.SetString(
+ "ok",
+ l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_OK));
+ strings.SetString(
+ "cancel",
+ l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_CANCEL));
+
+ base::StringPiece html(ResourceBundle::GetSharedInstance().
+ GetRawDataResource(IDR_READER_OUT_OF_DATE_HTML));
+
+ return jstemplate_builder::GetI18nTemplateHtml(html, &strings);
+ }
+
+ virtual void CommandReceived(const std::string& command) {
+ if (command == "0") {
+ DontProceed();
+ return;
+ }
+
+ if (command == "1") {
+ OpenReaderUpdateURL(tab());
+ } else if (command == "2") {
+ OpenUsingReader(tab(), reader_webplugininfo_);
+ } else {
+ NOTREACHED();
+ }
+ Proceed();
+ }
+
+ private:
+ WebPluginInfo reader_webplugininfo_;
+
+ DISALLOW_COPY_AND_ASSIGN(PDFUnsupportedFeatureInterstitial);
+};
+
+// The info bar delegate used to inform the user that we don't support a feature
+// in the PDF.
+class PDFUnsupportedFeatureConfirmInfoBarDelegate
+ : public ConfirmInfoBarDelegate {
+ public:
+ PDFUnsupportedFeatureConfirmInfoBarDelegate(
+ TabContents* tab_contents,
+ PluginGroup* reader_group) // NULL if Adobe Reader isn't installed.
+ : ConfirmInfoBarDelegate(tab_contents),
+ tab_contents_(tab_contents),
+ reader_installed_(!!reader_group),
+ reader_vulnerable_(false) {
+ if (reader_installed_) {
+ std::vector<WebPluginInfo> plugins = reader_group->web_plugin_infos();
+ DCHECK_EQ(plugins.size(), 1u);
+ reader_webplugininfo_ = plugins[0];
+
+ reader_vulnerable_ = reader_group->IsVulnerable();
+ if (!reader_vulnerable_) {
+ scoped_ptr<Version> version(PluginGroup::CreateVersionFromString(
+ reader_webplugininfo_.version));
+ if (version.get()) {
+ if (version->components()[0] < kMinReaderVersionToUse)
+ reader_vulnerable_ = true;
+ }
+ }
+ }
+ }
+
+ // ConfirmInfoBarDelegate
+ virtual void InfoBarClosed() {
+ delete this;
+ }
+ virtual Type GetInfoBarType() {
+ return PAGE_ACTION_TYPE;
+ }
+ virtual bool Accept() {
+ LaunchReader();
+ return true;
+ }
+ virtual int GetButtons() const {
+ return BUTTON_OK | BUTTON_CANCEL;
+ }
+ virtual string16 GetButtonLabel(InfoBarButton button) const {
+ switch (button) {
+ case BUTTON_OK:
+ return l10n_util::GetStringUTF16(
+ IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL);
+ case BUTTON_CANCEL:
+ return l10n_util::GetStringUTF16(
+ IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL);
+ default:
+ // All buttons are labeled above.
+ NOTREACHED() << "Bad button id " << button;
+ return string16();
+ }
+ }
+ virtual string16 GetMessageText() const {
+ return l10n_util::GetStringUTF16(reader_installed_ ?
+ IDS_PDF_INFOBAR_QUESTION_READER_INSTALLED :
+ IDS_PDF_INFOBAR_QUESTION_READER_NOT_INSTALLED);
+ }
+
+ private:
+ void LaunchReader() {
+ if (!reader_installed_) {
+ OpenReaderUpdateURL(tab_contents_);
+ return;
+ }
+
+ if (reader_vulnerable_) {
+ PDFUnsupportedFeatureInterstitial* interstitial = new
+ PDFUnsupportedFeatureInterstitial(
+ tab_contents_, reader_webplugininfo_);
+ interstitial->Show();
+ return;
+ }
+
+ OpenUsingReader(tab_contents_, reader_webplugininfo_);
+ }
+
+ TabContents* tab_contents_;
+ bool reader_installed_;
+ bool reader_vulnerable_;
+ WebPluginInfo reader_webplugininfo_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(PDFUnsupportedFeatureConfirmInfoBarDelegate);
+};
+
+} // namespace
+
+void PDFHasUnsupportedFeature(TabContents* tab) {
+#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.
+ return;
+#endif
+
+ PluginGroup* reader_group = NULL;
+ std::vector<PluginGroup> plugin_groups;
+ PluginList::Singleton()->GetPluginGroups(
+ false, &plugin_groups);
+ string16 reader_group_name(UTF8ToUTF16(PluginGroup::kAdobeReaderGroupName));
+ for (size_t i = 0; i < plugin_groups.size(); ++i) {
+ if (plugin_groups[i].GetGroupName() == reader_group_name) {
+ reader_group = &plugin_groups[i];
+ break;
+ }
+ }
+
+ // If the plugin is disabled by policy or by the user, don't prompt them.
+ if (reader_group && !reader_group->Enabled())
+ return;
+
+ tab->AddInfoBar(new PDFUnsupportedFeatureConfirmInfoBarDelegate(
+ tab, reader_group));
+}