pdf_unsupported_feature.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/pdf/pdf_unsupported_feature.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/prefs/pref_service.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/version.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/plugins/plugin_finder.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/plugins/plugin_metadata.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/plugins/plugin_prefs.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/renderer_preferences_util.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/tab_contents/tab_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/pdf/open_pdf_in_reader_prompt_delegate.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/pdf/pdf_tab_helper.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_content_client.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/interstitial_page.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/interstitial_page_delegate.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_details.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/browser/plugin_service.h"
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/web_contents.h"
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/page_transition_types.h"
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/browser_resources.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
40bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "ui/gfx/image/image.h"
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/webui/jstemplate_builder.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/win/metro.h"
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using content::InterstitialPage;
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using content::OpenURLParams;
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing content::PluginService;
50558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochusing content::Referrer;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UserMetricsAction;
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using content::WebContents;
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing content::WebPluginInfo;
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAdobeReaderIdentifier[] = "adobe-reader";
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAdobeReaderUpdateUrl[] =
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://www.adobe.com/go/getreader_chrome";
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The prompt delegate used to ask the user if they want to use Adobe Reader
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by default.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PDFEnableAdobeReaderPromptDelegate
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public OpenPDFInReaderPromptDelegate {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit PDFEnableAdobeReaderPromptDelegate(Profile* profile);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PDFEnableAdobeReaderPromptDelegate();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OpenPDFInReaderPromptDelegate
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetMessageText() const OVERRIDE;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetAcceptButtonText() const OVERRIDE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetCancelButtonText() const OVERRIDE;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ShouldExpire(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const content::LoadCommittedDetails& details) const OVERRIDE;
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Accept() OVERRIDE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Cancel() OVERRIDE;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void OnYes();
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void OnNo();
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Profile* profile_;
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(PDFEnableAdobeReaderPromptDelegate);
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)PDFEnableAdobeReaderPromptDelegate::PDFEnableAdobeReaderPromptDelegate(
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    Profile* profile)
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : profile_(profile) {
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  content::RecordAction(UserMetricsAction("PDF_EnableReaderInfoBarShown"));
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)PDFEnableAdobeReaderPromptDelegate::~PDFEnableAdobeReaderPromptDelegate() {
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool PDFEnableAdobeReaderPromptDelegate::ShouldExpire(
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const content::LoadCommittedDetails& details) const {
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::PageTransition transition =
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      content::PageTransitionStripQualifier(details.entry->GetTransitionType());
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't want to expire on a reload, because that is how we open the PDF in
10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Reader.
10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return !details.is_in_page && transition != content::PAGE_TRANSITION_RELOAD;
10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void PDFEnableAdobeReaderPromptDelegate::Accept() {
10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  content::RecordAction(UserMetricsAction("PDF_EnableReaderInfoBarOK"));
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile_).get();
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  plugin_prefs->EnablePluginGroup(
10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      true, ASCIIToUTF16(PluginMetadata::kAdobeReaderGroupName));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_prefs->EnablePluginGroup(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false, ASCIIToUTF16(chrome::ChromeContentClient::kPDFPluginName));
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PDFEnableAdobeReaderPromptDelegate::Cancel() {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("PDF_EnableReaderInfoBarCancel"));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 PDFEnableAdobeReaderPromptDelegate::GetAcceptButtonText() const {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_PDF_INFOBAR_ALWAYS_USE_READER_BUTTON);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 PDFEnableAdobeReaderPromptDelegate::GetCancelButtonText() const {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_DONE);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)string16 PDFEnableAdobeReaderPromptDelegate::GetMessageText() const {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_PDF_INFOBAR_QUESTION_ALWAYS_USE_READER);
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Launch the url to get the latest Adbobe Reader installer.
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void OpenReaderUpdateURL(WebContents* web_contents) {
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  OpenURLParams params(
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GURL(kAdobeReaderUpdateUrl), Referrer(), NEW_FOREGROUND_TAB,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::PAGE_TRANSITION_LINK, false);
135bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  web_contents->OpenURL(params);
136bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opens the PDF using Adobe Reader.
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void OpenUsingReader(WebContents* web_contents,
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                     const WebPluginInfo& reader_plugin,
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                     OpenPDFInReaderPromptDelegate* delegate) {
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ChromePluginServiceFilter::GetInstance()->OverridePluginForTab(
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      web_contents->GetRenderProcessHost()->GetID(),
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents->GetRenderViewHost()->GetRoutingID(),
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents->GetURL(),
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reader_plugin);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents->GetRenderViewHost()->ReloadFrame();
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PDFTabHelper* pdf_tab_helper = PDFTabHelper::FromWebContents(web_contents);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pdf_tab_helper->ShowOpenInReaderPrompt(make_scoped_ptr(delegate));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An interstitial to be used when the user chooses to open a PDF using Adobe
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Reader, but it is out of date.
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class PDFUnsupportedFeatureInterstitial
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : public content::InterstitialPageDelegate {
158558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch public:
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PDFUnsupportedFeatureInterstitial(
16023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      WebContents* web_contents,
16123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      const WebPluginInfo& reader_webplugininfo)
16223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      : web_contents_(web_contents),
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reader_webplugininfo_(reader_webplugininfo) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RecordAction(UserMetricsAction("PDF_ReaderInterstitialShown"));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    interstitial_page_ = InterstitialPage::Create(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        web_contents, false, web_contents->GetURL(), this);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    interstitial_page_->Show();
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // InterstitialPageDelegate implementation.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual std::string GetHTMLContents() OVERRIDE {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue strings;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strings.SetString(
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "title",
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_TITLE));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strings.SetString(
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "headLine",
179558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_BODY));
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    strings.SetString(
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "update",
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_UPDATE));
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    strings.SetString(
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "open_with_reader",
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        l10n_util::GetStringUTF16(
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_PROCEED));
18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    strings.SetString(
18823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "ok",
18923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_OK));
19023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    strings.SetString(
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "cancel",
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_CANCEL));
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::StringPiece html(ResourceBundle::GetSharedInstance().
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           GetRawDataResource(IDR_READER_OUT_OF_DATE_HTML));
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197    return webui::GetI18nTemplateHtml(html, &strings);
198  }
199
200  virtual void CommandReceived(const std::string& command) OVERRIDE {
201    if (command == "0") {
202      content::RecordAction(
203          UserMetricsAction("PDF_ReaderInterstitialCancel"));
204      interstitial_page_->DontProceed();
205      return;
206    }
207
208    if (command == "1") {
209      content::RecordAction(
210          UserMetricsAction("PDF_ReaderInterstitialUpdate"));
211      OpenReaderUpdateURL(web_contents_);
212    } else if (command == "2") {
213      content::RecordAction(
214          UserMetricsAction("PDF_ReaderInterstitialIgnore"));
215      // Pretend that the plug-in is up-to-date so that we don't block it.
216      reader_webplugininfo_.version = ASCIIToUTF16("11.0.0.0");
217      OpenUsingReader(web_contents_, reader_webplugininfo_, NULL);
218    } else {
219      NOTREACHED();
220    }
221    interstitial_page_->Proceed();
222  }
223
224  virtual void OverrideRendererPrefs(
225      content::RendererPreferences* prefs) OVERRIDE {
226    Profile* profile =
227        Profile::FromBrowserContext(web_contents_->GetBrowserContext());
228    renderer_preferences_util::UpdateFromSystemSettings(prefs, profile);
229  }
230
231 private:
232  WebContents* web_contents_;
233  WebPluginInfo reader_webplugininfo_;
234  InterstitialPage* interstitial_page_;  // Owns us.
235
236  DISALLOW_COPY_AND_ASSIGN(PDFUnsupportedFeatureInterstitial);
237};
238
239// The delegate for the bubble used to inform the user that we don't support a
240// feature in the PDF.
241class PDFUnsupportedFeaturePromptDelegate
242    : public OpenPDFInReaderPromptDelegate {
243 public:
244  // |reader| is NULL if Adobe Reader isn't installed.
245  PDFUnsupportedFeaturePromptDelegate(WebContents* web_contents,
246                                      const content::WebPluginInfo* reader,
247                                      PluginFinder* plugin_finder);
248  virtual ~PDFUnsupportedFeaturePromptDelegate();
249
250  // OpenPDFInReaderPromptDelegate:
251  virtual string16 GetMessageText() const OVERRIDE;
252  virtual string16 GetAcceptButtonText() const OVERRIDE;
253  virtual string16 GetCancelButtonText() const OVERRIDE;
254  virtual bool ShouldExpire(
255      const content::LoadCommittedDetails& details) const OVERRIDE;
256  virtual void Accept() OVERRIDE;
257  virtual void Cancel() OVERRIDE;
258
259 private:
260  WebContents* web_contents_;
261  bool reader_installed_;
262  bool reader_vulnerable_;
263  WebPluginInfo reader_webplugininfo_;
264
265  DISALLOW_IMPLICIT_CONSTRUCTORS(PDFUnsupportedFeaturePromptDelegate);
266};
267
268PDFUnsupportedFeaturePromptDelegate::PDFUnsupportedFeaturePromptDelegate(
269    WebContents* web_contents,
270    const content::WebPluginInfo* reader,
271    PluginFinder* plugin_finder)
272    : web_contents_(web_contents),
273      reader_installed_(!!reader),
274      reader_vulnerable_(false) {
275  if (!reader_installed_) {
276    content::RecordAction(
277        UserMetricsAction("PDF_InstallReaderInfoBarShown"));
278    return;
279  }
280
281  content::RecordAction(UserMetricsAction("PDF_UseReaderInfoBarShown"));
282  reader_webplugininfo_ = *reader;
283
284#if defined(ENABLE_PLUGIN_INSTALLATION)
285  scoped_ptr<PluginMetadata> plugin_metadata(
286      plugin_finder->GetPluginMetadata(reader_webplugininfo_));
287
288  reader_vulnerable_ = plugin_metadata->GetSecurityStatus(*reader) !=
289                       PluginMetadata::SECURITY_STATUS_UP_TO_DATE;
290#else
291  NOTREACHED();
292#endif
293}
294
295PDFUnsupportedFeaturePromptDelegate::~PDFUnsupportedFeaturePromptDelegate() {
296}
297
298string16 PDFUnsupportedFeaturePromptDelegate::GetMessageText() const {
299  return l10n_util::GetStringUTF16(IDS_PDF_BUBBLE_MESSAGE);
300}
301
302string16 PDFUnsupportedFeaturePromptDelegate::GetAcceptButtonText() const {
303#if defined(OS_WIN)
304  if (base::win::IsMetroProcess())
305    return l10n_util::GetStringUTF16(IDS_PDF_BUBBLE_METRO_MODE_LINK);
306#endif
307
308  if (reader_installed_)
309    return l10n_util::GetStringUTF16(IDS_PDF_BUBBLE_OPEN_IN_READER_LINK);
310
311  return l10n_util::GetStringUTF16(IDS_PDF_BUBBLE_INSTALL_READER_LINK);
312}
313
314string16 PDFUnsupportedFeaturePromptDelegate::GetCancelButtonText() const {
315  return l10n_util::GetStringUTF16(IDS_DONE);
316}
317
318bool PDFUnsupportedFeaturePromptDelegate::ShouldExpire(
319    const content::LoadCommittedDetails& details) const {
320  return !details.is_in_page;
321}
322
323void PDFUnsupportedFeaturePromptDelegate::Accept() {
324#if defined(OS_WIN)
325  if (base::win::IsMetroProcess()) {
326    chrome::AttemptRestartWithModeSwitch();
327    return;
328  }
329#endif
330
331  if (!reader_installed_) {
332    content::RecordAction(UserMetricsAction("PDF_InstallReaderInfoBarOK"));
333    OpenReaderUpdateURL(web_contents_);
334    return;
335  }
336
337  content::RecordAction(UserMetricsAction("PDF_UseReaderInfoBarOK"));
338
339  if (reader_vulnerable_) {
340    new PDFUnsupportedFeatureInterstitial(web_contents_, reader_webplugininfo_);
341    return;
342  }
343
344  Profile* profile =
345      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
346  OpenPDFInReaderPromptDelegate* delegate =
347      new PDFEnableAdobeReaderPromptDelegate(profile);
348
349  OpenUsingReader(web_contents_, reader_webplugininfo_, delegate);
350}
351
352void PDFUnsupportedFeaturePromptDelegate::Cancel() {
353  content::RecordAction(reader_installed_ ?
354                        UserMetricsAction("PDF_UseReaderInfoBarCancel") :
355                        UserMetricsAction("PDF_InstallReaderInfoBarCancel"));
356}
357
358#if defined(OS_WIN) && defined(ENABLE_PLUGIN_INSTALLATION)
359void GotPluginsCallback(int process_id,
360                        int routing_id,
361                        const std::vector<content::WebPluginInfo>& plugins) {
362  WebContents* web_contents =
363      tab_util::GetWebContentsByID(process_id, routing_id);
364  if (!web_contents)
365    return;
366
367  const content::WebPluginInfo* reader = NULL;
368  PluginFinder* plugin_finder = PluginFinder::GetInstance();
369  for (size_t i = 0; i < plugins.size(); ++i) {
370    scoped_ptr<PluginMetadata> plugin_metadata(
371        plugin_finder->GetPluginMetadata(plugins[i]));
372    if (plugin_metadata->identifier() != kAdobeReaderIdentifier)
373      continue;
374
375    DCHECK(!reader);
376    reader = &plugins[i];
377    // If the Reader plugin is disabled by policy, don't prompt them.
378    Profile* profile =
379        Profile::FromBrowserContext(web_contents->GetBrowserContext());
380    PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile);
381    if (plugin_prefs->PolicyStatusForPlugin(plugin_metadata->name()) ==
382        PluginPrefs::POLICY_DISABLED) {
383      return;
384    }
385    break;
386  }
387
388  scoped_ptr<OpenPDFInReaderPromptDelegate> prompt(
389      new PDFUnsupportedFeaturePromptDelegate(
390          web_contents, reader, plugin_finder));
391  PDFTabHelper* pdf_tab_helper = PDFTabHelper::FromWebContents(web_contents);
392  pdf_tab_helper->ShowOpenInReaderPrompt(prompt.Pass());
393}
394#endif  // defined(OS_WIN) && defined(ENABLE_PLUGIN_INSTALLATION)
395
396}  // namespace
397
398void PDFHasUnsupportedFeature(content::WebContents* web_contents) {
399#if defined(OS_WIN) && defined(ENABLE_PLUGIN_INSTALLATION)
400  // Only works for Windows for now.  For Mac, we'll have to launch the file
401  // externally since Adobe Reader doesn't work inside Chrome.
402  PluginService::GetInstance()->GetPlugins(base::Bind(&GotPluginsCallback,
403      web_contents->GetRenderProcessHost()->GetID(),
404      web_contents->GetRenderViewHost()->GetRoutingID()));
405#endif
406}
407