Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / ui / pdf / pdf_unsupported_feature.cc
blobdc40e459eb89f658edae0057095b03eb3ddba1a0
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/pdf/pdf_unsupported_feature.h"
7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/lifetime/application_lifetime.h"
11 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
12 #include "chrome/browser/plugins/plugin_metadata.h"
13 #include "chrome/browser/plugins/plugin_prefs.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/renderer_preferences_util.h"
16 #include "chrome/browser/tab_contents/tab_util.h"
17 #include "chrome/common/chrome_content_client.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "components/pdf/browser/open_pdf_in_reader_prompt_client.h"
20 #include "components/pdf/browser/pdf_web_contents_helper.h"
21 #include "content/public/browser/interstitial_page.h"
22 #include "content/public/browser/interstitial_page_delegate.h"
23 #include "content/public/browser/navigation_details.h"
24 #include "content/public/browser/navigation_entry.h"
25 #include "content/public/browser/page_navigator.h"
26 #include "content/public/browser/render_frame_host.h"
27 #include "content/public/browser/render_process_host.h"
28 #include "content/public/browser/render_view_host.h"
29 #include "content/public/browser/user_metrics.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/renderer_preferences.h"
32 #include "grit/browser_resources.h"
33 #include "ui/base/l10n/l10n_util.h"
34 #include "ui/base/resource/resource_bundle.h"
35 #include "ui/base/webui/jstemplate_builder.h"
37 #if defined(OS_WIN)
38 #include "base/win/metro.h"
39 #include "chrome/browser/ui/pdf/adobe_reader_info_win.h"
40 #endif
42 using base::UserMetricsAction;
43 using content::InterstitialPage;
44 using content::OpenURLParams;
45 using content::Referrer;
46 using content::WebContents;
47 using content::WebPluginInfo;
49 #if defined(OS_WIN)
50 namespace {
52 const char kAdobeReaderUpdateUrl[] = "http://www.adobe.com/go/getreader_chrome";
54 // The prompt delegate used to ask the user if they want to use Adobe Reader
55 // by default.
56 class PDFEnableAdobeReaderPromptClient
57 : public pdf::OpenPDFInReaderPromptClient {
58 public:
59 explicit PDFEnableAdobeReaderPromptClient(Profile* profile);
60 virtual ~PDFEnableAdobeReaderPromptClient();
62 // pdf::OpenPDFInReaderPromptClient
63 virtual base::string16 GetMessageText() const override;
64 virtual base::string16 GetAcceptButtonText() const override;
65 virtual base::string16 GetCancelButtonText() const override;
66 virtual bool ShouldExpire(
67 const content::LoadCommittedDetails& details) const override;
68 virtual void Accept() override;
69 virtual void Cancel() override;
71 private:
72 void OnYes();
73 void OnNo();
75 Profile* profile_;
77 DISALLOW_IMPLICIT_CONSTRUCTORS(PDFEnableAdobeReaderPromptClient);
80 PDFEnableAdobeReaderPromptClient::PDFEnableAdobeReaderPromptClient(
81 Profile* profile)
82 : profile_(profile) {
83 content::RecordAction(UserMetricsAction("PDF_EnableReaderInfoBarShown"));
86 PDFEnableAdobeReaderPromptClient::~PDFEnableAdobeReaderPromptClient() {
89 bool PDFEnableAdobeReaderPromptClient::ShouldExpire(
90 const content::LoadCommittedDetails& details) const {
91 ui::PageTransition transition =
92 ui::PageTransitionStripQualifier(details.entry->GetTransitionType());
93 // We don't want to expire on a reload, because that is how we open the PDF in
94 // Reader.
95 return !details.is_in_page && transition != ui::PAGE_TRANSITION_RELOAD;
98 void PDFEnableAdobeReaderPromptClient::Accept() {
99 content::RecordAction(UserMetricsAction("PDF_EnableReaderInfoBarOK"));
100 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile_).get();
101 plugin_prefs->EnablePluginGroup(
102 true, base::ASCIIToUTF16(PluginMetadata::kAdobeReaderGroupName));
103 plugin_prefs->EnablePluginGroup(
104 false, base::ASCIIToUTF16(ChromeContentClient::kPDFPluginName));
107 void PDFEnableAdobeReaderPromptClient::Cancel() {
108 content::RecordAction(UserMetricsAction("PDF_EnableReaderInfoBarCancel"));
111 base::string16 PDFEnableAdobeReaderPromptClient::GetAcceptButtonText() const {
112 return l10n_util::GetStringUTF16(IDS_PDF_INFOBAR_ALWAYS_USE_READER_BUTTON);
115 base::string16 PDFEnableAdobeReaderPromptClient::GetCancelButtonText() const {
116 return l10n_util::GetStringUTF16(IDS_DONE);
119 base::string16 PDFEnableAdobeReaderPromptClient::GetMessageText() const {
120 return l10n_util::GetStringUTF16(IDS_PDF_INFOBAR_QUESTION_ALWAYS_USE_READER);
123 // Launch the url to get the latest Adbobe Reader installer.
124 void OpenReaderUpdateURL(WebContents* web_contents) {
125 OpenURLParams params(
126 GURL(kAdobeReaderUpdateUrl), Referrer(), NEW_FOREGROUND_TAB,
127 ui::PAGE_TRANSITION_LINK, false);
128 web_contents->OpenURL(params);
131 // Opens the PDF using Adobe Reader.
132 void OpenUsingReader(WebContents* web_contents,
133 const WebPluginInfo& reader_plugin,
134 pdf::OpenPDFInReaderPromptClient* client) {
135 ChromePluginServiceFilter::GetInstance()->OverridePluginForFrame(
136 web_contents->GetRenderProcessHost()->GetID(),
137 web_contents->GetMainFrame()->GetRoutingID(),
138 web_contents->GetURL(),
139 reader_plugin);
140 web_contents->ReloadFocusedFrame(false);
142 pdf::PDFWebContentsHelper* pdf_tab_helper =
143 pdf::PDFWebContentsHelper::FromWebContents(web_contents);
144 if (client)
145 pdf_tab_helper->ShowOpenInReaderPrompt(make_scoped_ptr(client));
148 // An interstitial to be used when the user chooses to open a PDF using Adobe
149 // Reader, but it is out of date.
150 class PDFUnsupportedFeatureInterstitial
151 : public content::InterstitialPageDelegate {
152 public:
153 PDFUnsupportedFeatureInterstitial(
154 WebContents* web_contents,
155 const WebPluginInfo& reader_webplugininfo)
156 : web_contents_(web_contents),
157 reader_webplugininfo_(reader_webplugininfo) {
158 content::RecordAction(UserMetricsAction("PDF_ReaderInterstitialShown"));
159 interstitial_page_ = InterstitialPage::Create(
160 web_contents, false, web_contents->GetURL(), this);
161 interstitial_page_->Show();
164 protected:
165 // InterstitialPageDelegate implementation.
166 virtual std::string GetHTMLContents() override {
167 base::DictionaryValue strings;
168 strings.SetString(
169 "title",
170 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_TITLE));
171 strings.SetString(
172 "headLine",
173 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_BODY));
174 strings.SetString(
175 "update",
176 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_UPDATE));
177 strings.SetString(
178 "open_with_reader",
179 l10n_util::GetStringUTF16(
180 IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_PROCEED));
181 strings.SetString(
182 "ok",
183 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_OK));
184 strings.SetString(
185 "cancel",
186 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_CANCEL));
188 base::StringPiece html(ResourceBundle::GetSharedInstance().
189 GetRawDataResource(IDR_READER_OUT_OF_DATE_HTML));
191 return webui::GetI18nTemplateHtml(html, &strings);
194 virtual void CommandReceived(const std::string& command) override {
195 if (command == "0") {
196 content::RecordAction(
197 UserMetricsAction("PDF_ReaderInterstitialCancel"));
198 interstitial_page_->DontProceed();
199 return;
202 if (command == "1") {
203 content::RecordAction(
204 UserMetricsAction("PDF_ReaderInterstitialUpdate"));
205 OpenReaderUpdateURL(web_contents_);
206 } else if (command == "2") {
207 content::RecordAction(
208 UserMetricsAction("PDF_ReaderInterstitialIgnore"));
209 // Pretend that the plugin is up-to-date so that we don't block it.
210 reader_webplugininfo_.version = base::ASCIIToUTF16("11.0.0.0");
211 OpenUsingReader(web_contents_, reader_webplugininfo_, NULL);
212 } else {
213 NOTREACHED();
215 interstitial_page_->Proceed();
218 virtual void OverrideRendererPrefs(
219 content::RendererPreferences* prefs) override {
220 Profile* profile =
221 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
222 renderer_preferences_util::UpdateFromSystemSettings(
223 prefs, profile, web_contents_);
226 private:
227 WebContents* web_contents_;
228 WebPluginInfo reader_webplugininfo_;
229 InterstitialPage* interstitial_page_; // Owns us.
231 DISALLOW_COPY_AND_ASSIGN(PDFUnsupportedFeatureInterstitial);
234 // The delegate for the bubble used to inform the user that we don't support a
235 // feature in the PDF.
236 class PDFUnsupportedFeaturePromptClient
237 : public pdf::OpenPDFInReaderPromptClient {
238 public:
239 PDFUnsupportedFeaturePromptClient(WebContents* web_contents,
240 const AdobeReaderPluginInfo& reader_info);
241 virtual ~PDFUnsupportedFeaturePromptClient();
243 // pdf::OpenPDFInReaderPromptClient:
244 virtual base::string16 GetMessageText() const override;
245 virtual base::string16 GetAcceptButtonText() const override;
246 virtual base::string16 GetCancelButtonText() const override;
247 virtual bool ShouldExpire(
248 const content::LoadCommittedDetails& details) const override;
249 virtual void Accept() override;
250 virtual void Cancel() override;
252 private:
253 WebContents* web_contents_;
254 const AdobeReaderPluginInfo reader_info_;
256 DISALLOW_IMPLICIT_CONSTRUCTORS(PDFUnsupportedFeaturePromptClient);
259 PDFUnsupportedFeaturePromptClient::PDFUnsupportedFeaturePromptClient(
260 WebContents* web_contents,
261 const AdobeReaderPluginInfo& reader_info)
262 : web_contents_(web_contents), reader_info_(reader_info) {
263 content::RecordAction(reader_info_.is_installed ?
264 UserMetricsAction("PDF_UseReaderInfoBarShown") :
265 UserMetricsAction("PDF_InstallReaderInfoBarShown"));
268 PDFUnsupportedFeaturePromptClient::~PDFUnsupportedFeaturePromptClient() {
271 base::string16 PDFUnsupportedFeaturePromptClient::GetMessageText() const {
272 return l10n_util::GetStringUTF16(IDS_PDF_BUBBLE_MESSAGE);
275 base::string16 PDFUnsupportedFeaturePromptClient::GetAcceptButtonText() const {
276 if (base::win::IsMetroProcess())
277 return l10n_util::GetStringUTF16(IDS_PDF_BUBBLE_METRO_MODE_LINK);
279 return l10n_util::GetStringUTF16(
280 reader_info_.is_installed ? IDS_PDF_BUBBLE_OPEN_IN_READER_LINK
281 : IDS_PDF_BUBBLE_INSTALL_READER_LINK);
284 base::string16 PDFUnsupportedFeaturePromptClient::GetCancelButtonText() const {
285 return l10n_util::GetStringUTF16(IDS_DONE);
288 bool PDFUnsupportedFeaturePromptClient::ShouldExpire(
289 const content::LoadCommittedDetails& details) const {
290 return !details.is_in_page;
293 void PDFUnsupportedFeaturePromptClient::Accept() {
294 if (base::win::IsMetroProcess()) {
295 chrome::AttemptRestartToDesktopMode();
296 return;
299 if (!reader_info_.is_installed) {
300 content::RecordAction(UserMetricsAction("PDF_InstallReaderInfoBarOK"));
301 OpenReaderUpdateURL(web_contents_);
302 return;
305 content::RecordAction(UserMetricsAction("PDF_UseReaderInfoBarOK"));
307 if (!reader_info_.is_secure) {
308 new PDFUnsupportedFeatureInterstitial(web_contents_,
309 reader_info_.plugin_info);
310 return;
313 Profile* profile =
314 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
315 pdf::OpenPDFInReaderPromptClient* client =
316 new PDFEnableAdobeReaderPromptClient(profile);
318 OpenUsingReader(web_contents_, reader_info_.plugin_info, client);
321 void PDFUnsupportedFeaturePromptClient::Cancel() {
322 content::RecordAction(reader_info_.is_installed ?
323 UserMetricsAction("PDF_UseReaderInfoBarCancel") :
324 UserMetricsAction("PDF_InstallReaderInfoBarCancel"));
327 void MaybeShowOpenPDFInReaderPrompt(WebContents* web_contents,
328 const AdobeReaderPluginInfo& reader_info) {
329 // If the Reader plugin is disabled by policy, don't prompt them.
330 if (!reader_info.is_installed || !reader_info.is_enabled)
331 return;
333 scoped_ptr<pdf::OpenPDFInReaderPromptClient> prompt(
334 new PDFUnsupportedFeaturePromptClient(web_contents, reader_info));
335 pdf::PDFWebContentsHelper* pdf_tab_helper =
336 pdf::PDFWebContentsHelper::FromWebContents(web_contents);
337 pdf_tab_helper->ShowOpenInReaderPrompt(prompt.Pass());
340 void GotPluginsCallback(int process_id,
341 int routing_id,
342 const AdobeReaderPluginInfo& reader_info) {
343 WebContents* web_contents =
344 tab_util::GetWebContentsByID(process_id, routing_id);
345 if (web_contents)
346 MaybeShowOpenPDFInReaderPrompt(web_contents, reader_info);
349 } // namespace
350 #endif // defined(OS_WIN)
352 void PDFHasUnsupportedFeature(WebContents* web_contents) {
353 #if defined(OS_WIN)
354 // Only works for Windows for now. For Mac, we'll have to launch the file
355 // externally since Adobe Reader doesn't work inside Chrome.
356 Profile* profile =
357 Profile::FromBrowserContext(web_contents->GetBrowserContext());
358 AdobeReaderPluginInfo reader_info;
359 if (GetAdobeReaderPluginInfo(profile, &reader_info)) {
360 MaybeShowOpenPDFInReaderPrompt(web_contents, reader_info);
361 return;
363 GetAdobeReaderPluginInfoAsync(
364 profile,
365 base::Bind(&GotPluginsCallback,
366 web_contents->GetRenderProcessHost()->GetID(),
367 web_contents->GetRenderViewHost()->GetRoutingID()));
368 #endif // defined(OS_WIN)