Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(892)

Side by Side Diff: chrome/browser/pdf_unsupported_feature.cc

Issue 8865004: Create CoreTabHelper, move remaining core TCW functionality into it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: lots of helpers now Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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.
4
5 #include "chrome/browser/pdf_unsupported_feature.h"
6
7 #include "base/bind.h"
8 #include "base/utf_string_conversions.h"
9 #include "base/values.h"
10 #include "base/version.h"
11 #include "chrome/browser/chrome_plugin_service_filter.h"
12 #include "chrome/browser/infobars/infobar_tab_helper.h"
13 #include "chrome/browser/plugin_prefs.h"
14 #include "chrome/browser/prefs/pref_service.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/tab_contents/chrome_interstitial_page.h"
17 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
18 #include "chrome/browser/tab_contents/tab_util.h"
19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
20 #include "chrome/common/chrome_content_client.h"
21 #include "chrome/common/jstemplate_builder.h"
22 #include "chrome/common/pref_names.h"
23 #include "content/browser/plugin_service.h"
24 #include "content/browser/renderer_host/render_view_host.h"
25 #include "content/browser/user_metrics.h"
26 #include "grit/browser_resources.h"
27 #include "grit/generated_resources.h"
28 #include "grit/theme_resources_standard.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/gfx/image/image.h"
32 #include "webkit/plugins/npapi/plugin_group.h"
33
34 using webkit::npapi::PluginGroup;
35 using webkit::WebPluginInfo;
36
37 namespace {
38
39 // Only launch Adobe Reader X or later.
40 static const uint16 kMinReaderVersionToUse = 10;
41
42 static const char kReaderUpdateUrl[] =
43 "http://www.adobe.com/go/getreader_chrome";
44
45 // The info bar delegate used to ask the user if they want to use Adobe Reader
46 // by default. We want the infobar to have [No][Yes], so we swap the text on
47 // the buttons, and the meaning of the delegate callbacks.
48 class PDFEnableAdobeReaderInfoBarDelegate : public ConfirmInfoBarDelegate {
49 public:
50 explicit PDFEnableAdobeReaderInfoBarDelegate(
51 InfoBarTabHelper* infobar_helper,
52 Profile* profile);
53 virtual ~PDFEnableAdobeReaderInfoBarDelegate();
54
55 // ConfirmInfoBarDelegate
56 virtual void InfoBarDismissed() OVERRIDE;
57 virtual Type GetInfoBarType() const OVERRIDE;
58 virtual bool Accept() OVERRIDE;
59 virtual bool Cancel() OVERRIDE;
60 virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
61 virtual string16 GetMessageText() const OVERRIDE;
62
63 private:
64 void OnYes();
65 void OnNo();
66
67 Profile* profile_;
68
69 DISALLOW_IMPLICIT_CONSTRUCTORS(PDFEnableAdobeReaderInfoBarDelegate);
70 };
71
72 PDFEnableAdobeReaderInfoBarDelegate::PDFEnableAdobeReaderInfoBarDelegate(
73 InfoBarTabHelper* infobar_helper, Profile* profile)
74 : ConfirmInfoBarDelegate(infobar_helper),
75 profile_(profile) {
76 UserMetrics::RecordAction(UserMetricsAction("PDF_EnableReaderInfoBarShown"));
77 }
78
79 PDFEnableAdobeReaderInfoBarDelegate::~PDFEnableAdobeReaderInfoBarDelegate() {
80 }
81
82 void PDFEnableAdobeReaderInfoBarDelegate::InfoBarDismissed() {
83 OnNo();
84 }
85
86 InfoBarDelegate::Type
87 PDFEnableAdobeReaderInfoBarDelegate::GetInfoBarType() const {
88 return PAGE_ACTION_TYPE;
89 }
90
91 bool PDFEnableAdobeReaderInfoBarDelegate::Accept() {
92 profile_->GetPrefs()->SetBoolean(
93 prefs::kPluginsShowSetReaderDefaultInfobar, false);
94 OnNo();
95 return true;
96 }
97
98 bool PDFEnableAdobeReaderInfoBarDelegate::Cancel() {
99 OnYes();
100 return true;
101 }
102
103 string16 PDFEnableAdobeReaderInfoBarDelegate::GetButtonLabel(
104 InfoBarButton button) const {
105 return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
106 IDS_PDF_INFOBAR_NEVER_USE_READER_BUTTON :
107 IDS_PDF_INFOBAR_ALWAYS_USE_READER_BUTTON);
108 }
109
110 string16 PDFEnableAdobeReaderInfoBarDelegate::GetMessageText() const {
111 return l10n_util::GetStringUTF16(IDS_PDF_INFOBAR_QUESTION_ALWAYS_USE_READER);
112 }
113
114 void PDFEnableAdobeReaderInfoBarDelegate::OnYes() {
115 UserMetrics::RecordAction(UserMetricsAction("PDF_EnableReaderInfoBarOK"));
116 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile_);
117 plugin_prefs->EnablePluginGroup(
118 true, ASCIIToUTF16(webkit::npapi::PluginGroup::kAdobeReaderGroupName));
119 plugin_prefs->EnablePluginGroup(
120 false, ASCIIToUTF16(chrome::ChromeContentClient::kPDFPluginName));
121 }
122
123 void PDFEnableAdobeReaderInfoBarDelegate::OnNo() {
124 UserMetrics::RecordAction(UserMetricsAction("PDF_EnableReaderInfoBarCancel"));
125 }
126
127 // Launch the url to get the latest Adbobe Reader installer.
128 void OpenReaderUpdateURL(TabContents* tab) {
129 tab->OpenURL(GURL(kReaderUpdateUrl), GURL(), NEW_FOREGROUND_TAB,
130 content::PAGE_TRANSITION_LINK);
131 }
132
133 // Opens the PDF using Adobe Reader.
134 void OpenUsingReader(TabContentsWrapper* tab,
135 const WebPluginInfo& reader_plugin,
136 InfoBarDelegate* old_delegate,
137 InfoBarDelegate* new_delegate) {
138 ChromePluginServiceFilter::GetInstance()->OverridePluginForTab(
139 tab->render_view_host()->process()->GetID(),
140 tab->render_view_host()->routing_id(),
141 tab->tab_contents()->GetURL(),
142 ASCIIToUTF16(PluginGroup::kAdobeReaderGroupName));
143 tab->render_view_host()->ReloadFrame();
144
145 if (new_delegate) {
146 if (old_delegate) {
147 tab->infobar_tab_helper()->ReplaceInfoBar(old_delegate, new_delegate);
148 } else {
149 tab->infobar_tab_helper()->AddInfoBar(new_delegate);
150 }
151 }
152 }
153
154 // An interstitial to be used when the user chooses to open a PDF using Adobe
155 // Reader, but it is out of date.
156 class PDFUnsupportedFeatureInterstitial : public ChromeInterstitialPage {
157 public:
158 PDFUnsupportedFeatureInterstitial(
159 TabContentsWrapper* tab,
160 const WebPluginInfo& reader_webplugininfo)
161 : ChromeInterstitialPage(
162 tab->tab_contents(), false, tab->tab_contents()->GetURL()),
163 tab_contents_(tab),
164 reader_webplugininfo_(reader_webplugininfo) {
165 UserMetrics::RecordAction(UserMetricsAction("PDF_ReaderInterstitialShown"));
166 }
167
168 protected:
169 // ChromeInterstitialPage implementation.
170 virtual std::string GetHTMLContents() {
171 DictionaryValue strings;
172 strings.SetString(
173 "title",
174 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_TITLE));
175 strings.SetString(
176 "headLine",
177 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_BODY));
178 strings.SetString(
179 "update",
180 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_UPDATE));
181 strings.SetString(
182 "open_with_reader",
183 l10n_util::GetStringUTF16(
184 IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_PROCEED));
185 strings.SetString(
186 "ok",
187 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_OK));
188 strings.SetString(
189 "cancel",
190 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_CANCEL));
191
192 base::StringPiece html(ResourceBundle::GetSharedInstance().
193 GetRawDataResource(IDR_READER_OUT_OF_DATE_HTML));
194
195 return jstemplate_builder::GetI18nTemplateHtml(html, &strings);
196 }
197
198 virtual void CommandReceived(const std::string& command) {
199 if (command == "0") {
200 UserMetrics::RecordAction(
201 UserMetricsAction("PDF_ReaderInterstitialCancel"));
202 DontProceed();
203 return;
204 }
205
206 if (command == "1") {
207 UserMetrics::RecordAction(
208 UserMetricsAction("PDF_ReaderInterstitialUpdate"));
209 OpenReaderUpdateURL(tab());
210 } else if (command == "2") {
211 UserMetrics::RecordAction(
212 UserMetricsAction("PDF_ReaderInterstitialIgnore"));
213 OpenUsingReader(tab_contents_, reader_webplugininfo_, NULL, NULL);
214 } else {
215 NOTREACHED();
216 }
217 Proceed();
218 }
219
220 private:
221 TabContentsWrapper* tab_contents_;
222 WebPluginInfo reader_webplugininfo_;
223
224 DISALLOW_COPY_AND_ASSIGN(PDFUnsupportedFeatureInterstitial);
225 };
226
227 // The info bar delegate used to inform the user that we don't support a feature
228 // in the PDF. See the comment about how we swap buttons for
229 // PDFEnableAdobeReaderInfoBarDelegate.
230 class PDFUnsupportedFeatureInfoBarDelegate : public ConfirmInfoBarDelegate {
231 public:
232 // |reader_group| is NULL if Adobe Reader isn't installed.
233 PDFUnsupportedFeatureInfoBarDelegate(TabContentsWrapper* tab_contents,
234 const PluginGroup* reader_group);
235 virtual ~PDFUnsupportedFeatureInfoBarDelegate();
236
237 // ConfirmInfoBarDelegate
238 virtual void InfoBarDismissed() OVERRIDE;
239 virtual gfx::Image* GetIcon() const OVERRIDE;
240 virtual Type GetInfoBarType() const OVERRIDE;
241 virtual bool Accept() OVERRIDE;
242 virtual bool Cancel() OVERRIDE;
243 virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
244 virtual string16 GetMessageText() const OVERRIDE;
245
246 private:
247 bool OnYes();
248 void OnNo();
249
250 TabContentsWrapper* tab_contents_;
251 bool reader_installed_;
252 bool reader_vulnerable_;
253 WebPluginInfo reader_webplugininfo_;
254
255 DISALLOW_IMPLICIT_CONSTRUCTORS(PDFUnsupportedFeatureInfoBarDelegate);
256 };
257
258 PDFUnsupportedFeatureInfoBarDelegate::PDFUnsupportedFeatureInfoBarDelegate(
259 TabContentsWrapper* tab_contents,
260 const PluginGroup* reader_group)
261 : ConfirmInfoBarDelegate(tab_contents->infobar_tab_helper()),
262 tab_contents_(tab_contents),
263 reader_installed_(!!reader_group),
264 reader_vulnerable_(false) {
265 if (!reader_installed_) {
266 UserMetrics::RecordAction(
267 UserMetricsAction("PDF_InstallReaderInfoBarShown"));
268 return;
269 }
270
271 UserMetrics::RecordAction(UserMetricsAction("PDF_UseReaderInfoBarShown"));
272 const std::vector<WebPluginInfo>& plugins =
273 reader_group->web_plugin_infos();
274 DCHECK_EQ(plugins.size(), 1u);
275 reader_webplugininfo_ = plugins[0];
276
277 reader_vulnerable_ = reader_group->IsVulnerable(reader_webplugininfo_);
278 if (!reader_vulnerable_) {
279 scoped_ptr<Version> version(PluginGroup::CreateVersionFromString(
280 reader_webplugininfo_.version));
281 reader_vulnerable_ =
282 version.get() && (version->components()[0] < kMinReaderVersionToUse);
283 }
284 }
285
286 PDFUnsupportedFeatureInfoBarDelegate::~PDFUnsupportedFeatureInfoBarDelegate() {
287 }
288
289 void PDFUnsupportedFeatureInfoBarDelegate::InfoBarDismissed() {
290 OnNo();
291 }
292
293 gfx::Image* PDFUnsupportedFeatureInfoBarDelegate::GetIcon() const {
294 return &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
295 IDR_INFOBAR_INCOMPLETE);
296 }
297
298 InfoBarDelegate::Type
299 PDFUnsupportedFeatureInfoBarDelegate::GetInfoBarType() const {
300 return PAGE_ACTION_TYPE;
301 }
302
303 bool PDFUnsupportedFeatureInfoBarDelegate::Accept() {
304 OnNo();
305 return true;
306 }
307
308 bool PDFUnsupportedFeatureInfoBarDelegate::Cancel() {
309 return OnYes();
310 }
311
312 string16 PDFUnsupportedFeatureInfoBarDelegate::GetButtonLabel(
313 InfoBarButton button) const {
314 return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
315 IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL :
316 IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL);
317 }
318
319 string16 PDFUnsupportedFeatureInfoBarDelegate::GetMessageText() const {
320 return l10n_util::GetStringUTF16(reader_installed_ ?
321 IDS_PDF_INFOBAR_QUESTION_READER_INSTALLED :
322 IDS_PDF_INFOBAR_QUESTION_READER_NOT_INSTALLED);
323 }
324
325 bool PDFUnsupportedFeatureInfoBarDelegate::OnYes() {
326 if (!reader_installed_) {
327 UserMetrics::RecordAction(UserMetricsAction("PDF_InstallReaderInfoBarOK"));
328 OpenReaderUpdateURL(tab_contents_->tab_contents());
329 return true;
330 }
331
332 UserMetrics::RecordAction(UserMetricsAction("PDF_UseReaderInfoBarOK"));
333
334 if (reader_vulnerable_) {
335 PDFUnsupportedFeatureInterstitial* interstitial =
336 new PDFUnsupportedFeatureInterstitial(tab_contents_,
337 reader_webplugininfo_);
338 interstitial->Show();
339 return true;
340 }
341
342 if (tab_contents_->profile()->GetPrefs()->GetBoolean(
343 prefs::kPluginsShowSetReaderDefaultInfobar)) {
344 InfoBarDelegate* bar = new PDFEnableAdobeReaderInfoBarDelegate(
345 tab_contents_->infobar_tab_helper(), tab_contents_->profile());
346 OpenUsingReader(tab_contents_, reader_webplugininfo_, this, bar);
347 return false;
348 }
349
350 OpenUsingReader(tab_contents_, reader_webplugininfo_, NULL, NULL);
351 return true;
352 }
353
354 void PDFUnsupportedFeatureInfoBarDelegate::OnNo() {
355 UserMetrics::RecordAction(reader_installed_ ?
356 UserMetricsAction("PDF_UseReaderInfoBarCancel") :
357 UserMetricsAction("PDF_InstallReaderInfoBarCancel"));
358 }
359
360 void GotPluginGroupsCallback(int process_id,
361 int routing_id,
362 const std::vector<PluginGroup>& groups) {
363 TabContents* tab_contents =
364 tab_util::GetTabContentsByID(process_id, routing_id);
365 if (!tab_contents)
366 return;
367
368 TabContentsWrapper* tab =
369 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
370 if (!tab)
371 return;
372
373 string16 reader_group_name(ASCIIToUTF16(PluginGroup::kAdobeReaderGroupName));
374
375 // If the Reader plugin is disabled by policy, don't prompt them.
376 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(tab->profile());
377 if (plugin_prefs->PolicyStatusForPlugin(reader_group_name) ==
378 PluginPrefs::POLICY_DISABLED) {
379 return;
380 }
381
382 const PluginGroup* reader_group = NULL;
383 for (size_t i = 0; i < groups.size(); ++i) {
384 if (groups[i].GetGroupName() == reader_group_name) {
385 reader_group = &groups[i];
386 break;
387 }
388 }
389
390 tab->infobar_tab_helper()->AddInfoBar(
391 new PDFUnsupportedFeatureInfoBarDelegate(tab, reader_group));
392 }
393
394 } // namespace
395
396 void PDFHasUnsupportedFeature(TabContentsWrapper* tab) {
397 #if !defined(OS_WIN)
398 // Only works for Windows for now. For Mac, we'll have to launch the file
399 // externally since Adobe Reader doesn't work inside Chrome.
400 return;
401 #endif
402
403 PluginService::GetInstance()->GetPluginGroups(
404 base::Bind(&GotPluginGroupsCallback,
405 tab->render_view_host()->process()->GetID(),
406 tab->render_view_host()->routing_id()));
407 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698