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

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

Issue 6278017: If a user chooses to open a PDF with Reader, ask them if they want to do so a... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months 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
« no previous file with comments | « no previous file | chrome/tools/chromeactions.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/pdf_unsupported_feature.h" 5 #include "chrome/browser/pdf_unsupported_feature.h"
6 6
7 #include "base/utf_string_conversions.h" 7 #include "base/utf_string_conversions.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 #include "base/version.h" 9 #include "base/version.h"
10 #include "chrome/browser/metrics/user_metrics.h"
10 #include "chrome/browser/plugin_service.h" 11 #include "chrome/browser/plugin_service.h"
11 #include "chrome/browser/renderer_host/render_process_host.h" 12 #include "chrome/browser/renderer_host/render_process_host.h"
12 #include "chrome/browser/renderer_host/render_view_host.h" 13 #include "chrome/browser/renderer_host/render_view_host.h"
13 #include "chrome/browser/tab_contents/infobar_delegate.h" 14 #include "chrome/browser/tab_contents/infobar_delegate.h"
14 #include "chrome/browser/tab_contents/interstitial_page.h" 15 #include "chrome/browser/tab_contents/interstitial_page.h"
15 #include "chrome/browser/tab_contents/tab_contents.h" 16 #include "chrome/browser/tab_contents/tab_contents.h"
16 #include "chrome/common/jstemplate_builder.h" 17 #include "chrome/common/jstemplate_builder.h"
18 #include "chrome/common/pepper_plugin_registry.h"
17 #include "grit/browser_resources.h" 19 #include "grit/browser_resources.h"
18 #include "grit/generated_resources.h" 20 #include "grit/generated_resources.h"
19 #include "ui/base/l10n/l10n_util.h" 21 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/resource/resource_bundle.h" 22 #include "ui/base/resource/resource_bundle.h"
21 #include "webkit/plugins/npapi/plugin_group.h" 23 #include "webkit/plugins/npapi/plugin_group.h"
22 #include "webkit/plugins/npapi/plugin_list.h" 24 #include "webkit/plugins/npapi/plugin_list.h"
23 #include "webkit/plugins/npapi/webplugininfo.h" 25 #include "webkit/plugins/npapi/webplugininfo.h"
24 26
25 using webkit::npapi::PluginGroup; 27 using webkit::npapi::PluginGroup;
26 using webkit::npapi::PluginList; 28 using webkit::npapi::PluginList;
27 using webkit::npapi::WebPluginInfo; 29 using webkit::npapi::WebPluginInfo;
28 30
29 // Only launch Adobe Reader X or later. 31 // Only launch Adobe Reader X or later.
30 static const uint16 kMinReaderVersionToUse = 10; 32 static const uint16 kMinReaderVersionToUse = 10;
31 33
32 namespace { 34 namespace {
33 35
36 // The info bar delegate used to ask the user if they want to use Adobe Reader
37 // by default.
38 class PDFEnableAdobeReaderConfirmInfoBarDelegate
39 : public ConfirmInfoBarDelegate {
40 public:
41 PDFEnableAdobeReaderConfirmInfoBarDelegate(
42 TabContents* tab_contents)
43 : ConfirmInfoBarDelegate(tab_contents) {
44 UserMetrics::RecordAction(
45 UserMetricsAction("PDF_EnableReaderInfoBarShown"));
46 }
47
48 // ConfirmInfoBarDelegate
49 virtual void InfoBarClosed() {
50 delete this;
51 }
52
53 virtual void InfoBarDismissed() {
54 Cancel();
55 }
56
57 virtual Type GetInfoBarType() const {
58 return PAGE_ACTION_TYPE;
59 }
60
61 virtual bool Accept() {
62 UserMetrics::RecordAction(
63 UserMetricsAction("PDF_EnableReaderInfoBarOK"));
64 webkit::npapi::PluginList::Singleton()->EnableGroup(
65 false, ASCIIToUTF16(PepperPluginRegistry::kPDFPluginName));
66 webkit::npapi::PluginList::Singleton()->EnableGroup(
67 true, ASCIIToUTF16(webkit::npapi::PluginGroup::kAdobeReaderGroupName));
68 return true;
69 }
70
71 virtual bool Cancel() {
72 UserMetrics::RecordAction(
73 UserMetricsAction("PDF_EnableReaderInfoBarCancel"));
74 return true;
75 }
76
77 virtual int GetButtons() const {
78 return BUTTON_OK | BUTTON_CANCEL;
79 }
80
81 virtual string16 GetButtonLabel(InfoBarButton button) const {
82 switch (button) {
83 case BUTTON_OK:
84 return l10n_util::GetStringUTF16(
85 IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL);
86 case BUTTON_CANCEL:
87 return l10n_util::GetStringUTF16(
88 IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL);
89 default:
90 // All buttons are labeled above.
91 NOTREACHED() << "Bad button id " << button;
92 return string16();
93 }
94 }
95
96 virtual string16 GetMessageText() const {
97 return l10n_util::GetStringUTF16(
98 IDS_PDF_INFOBAR_QUESTION_ALWAYS_USE_READER);
99 }
100
101 private:
102 DISALLOW_IMPLICIT_CONSTRUCTORS(PDFEnableAdobeReaderConfirmInfoBarDelegate);
103 };
104
34 // Launch the url to get the latest Adbobe Reader installer. 105 // Launch the url to get the latest Adbobe Reader installer.
35 void OpenReaderUpdateURL(TabContents* tab) { 106 void OpenReaderUpdateURL(TabContents* tab) {
36 tab->OpenURL(GURL(PluginGroup::kAdobeReaderUpdateURL), GURL(), CURRENT_TAB, 107 tab->OpenURL(GURL(PluginGroup::kAdobeReaderUpdateURL), GURL(), CURRENT_TAB,
37 PageTransition::LINK); 108 PageTransition::LINK);
38 } 109 }
39 110
40 // Opens the PDF using Adobe Reader. 111 // Opens the PDF using Adobe Reader.
41 void OpenUsingReader(TabContents* tab, const WebPluginInfo& reader_plugin) { 112 void OpenUsingReader(TabContents* tab,
113 const WebPluginInfo& reader_plugin,
114 InfoBarDelegate* old_delegate) {
42 PluginService::OverriddenPlugin plugin; 115 PluginService::OverriddenPlugin plugin;
43 plugin.render_process_id = tab->GetRenderProcessHost()->id(); 116 plugin.render_process_id = tab->GetRenderProcessHost()->id();
44 plugin.render_view_id = tab->render_view_host()->routing_id(); 117 plugin.render_view_id = tab->render_view_host()->routing_id();
45 plugin.url = tab->GetURL(); 118 plugin.url = tab->GetURL();
46 plugin.plugin = reader_plugin; 119 plugin.plugin = reader_plugin;
120 // The plugin is disabled, so enable it to get around the renderer check.
121 // Also give it a new version so that the renderer doesn't show the blocked
122 // plugin UI if it's vulnerable, since we already went through the
123 // interstitial.
124 plugin.plugin.enabled = WebPluginInfo::USER_ENABLED;
125 plugin.plugin.version = ASCIIToUTF16("11.0.0.0");
47 126
48 PluginService::GetInstance()->OverridePluginForTab(plugin); 127 PluginService::GetInstance()->OverridePluginForTab(plugin);
49 tab->render_view_host()->ReloadFrame(); 128 tab->render_view_host()->ReloadFrame();
129
130 InfoBarDelegate* bar = new PDFEnableAdobeReaderConfirmInfoBarDelegate(tab);
131 if (old_delegate) {
132 tab->ReplaceInfoBar(old_delegate, bar);
133 } else {
134 tab->AddInfoBar(bar);
135 }
50 } 136 }
51 137
52 // An interstitial to be used when the user chooses to open a PDF using Adobe 138 // An interstitial to be used when the user chooses to open a PDF using Adobe
53 // Reader, but it is out of date. 139 // Reader, but it is out of date.
54 class PDFUnsupportedFeatureInterstitial : public InterstitialPage { 140 class PDFUnsupportedFeatureInterstitial : public InterstitialPage {
55 public: 141 public:
56 PDFUnsupportedFeatureInterstitial( 142 PDFUnsupportedFeatureInterstitial(
57 TabContents* tab, 143 TabContents* tab,
58 const WebPluginInfo& reader_webplugininfo) 144 const WebPluginInfo& reader_webplugininfo)
59 : InterstitialPage(tab, false, tab->GetURL()), 145 : InterstitialPage(tab, false, tab->GetURL()),
60 reader_webplugininfo_(reader_webplugininfo) { 146 reader_webplugininfo_(reader_webplugininfo) {
147 UserMetrics::RecordAction(UserMetricsAction("PDF_ReaderInterstitialShown"));
61 } 148 }
62 149
63 protected: 150 protected:
64 // InterstitialPage implementation. 151 // InterstitialPage implementation.
65 virtual std::string GetHTMLContents() { 152 virtual std::string GetHTMLContents() {
66 DictionaryValue strings; 153 DictionaryValue strings;
67 strings.SetString( 154 strings.SetString(
68 "title", 155 "title",
69 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_TITLE)); 156 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_TITLE));
70 strings.SetString( 157 strings.SetString(
(...skipping 14 matching lines...) Expand all
85 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_CANCEL)); 172 l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_CANCEL));
86 173
87 base::StringPiece html(ResourceBundle::GetSharedInstance(). 174 base::StringPiece html(ResourceBundle::GetSharedInstance().
88 GetRawDataResource(IDR_READER_OUT_OF_DATE_HTML)); 175 GetRawDataResource(IDR_READER_OUT_OF_DATE_HTML));
89 176
90 return jstemplate_builder::GetI18nTemplateHtml(html, &strings); 177 return jstemplate_builder::GetI18nTemplateHtml(html, &strings);
91 } 178 }
92 179
93 virtual void CommandReceived(const std::string& command) { 180 virtual void CommandReceived(const std::string& command) {
94 if (command == "0") { 181 if (command == "0") {
182 UserMetrics::RecordAction(
183 UserMetricsAction("PDF_ReaderInterstitialCancel"));
95 DontProceed(); 184 DontProceed();
96 return; 185 return;
97 } 186 }
98 187
99 if (command == "1") { 188 if (command == "1") {
189 UserMetrics::RecordAction(
190 UserMetricsAction("PDF_ReaderInterstitialUpdate"));
100 OpenReaderUpdateURL(tab()); 191 OpenReaderUpdateURL(tab());
101 } else if (command == "2") { 192 } else if (command == "2") {
102 OpenUsingReader(tab(), reader_webplugininfo_); 193 UserMetrics::RecordAction(
194 UserMetricsAction("PDF_ReaderInterstitialIgnore"));
195 OpenUsingReader(tab(), reader_webplugininfo_, NULL);
103 } else { 196 } else {
104 NOTREACHED(); 197 NOTREACHED();
105 } 198 }
106 Proceed(); 199 Proceed();
107 } 200 }
108 201
109 private: 202 private:
110 WebPluginInfo reader_webplugininfo_; 203 WebPluginInfo reader_webplugininfo_;
111 204
112 DISALLOW_COPY_AND_ASSIGN(PDFUnsupportedFeatureInterstitial); 205 DISALLOW_COPY_AND_ASSIGN(PDFUnsupportedFeatureInterstitial);
113 }; 206 };
114 207
115 // The info bar delegate used to inform the user that we don't support a feature 208 // The info bar delegate used to inform the user that we don't support a feature
116 // in the PDF. 209 // in the PDF.
117 class PDFUnsupportedFeatureConfirmInfoBarDelegate 210 class PDFUnsupportedFeatureConfirmInfoBarDelegate
118 : public ConfirmInfoBarDelegate { 211 : public ConfirmInfoBarDelegate {
119 public: 212 public:
120 PDFUnsupportedFeatureConfirmInfoBarDelegate( 213 PDFUnsupportedFeatureConfirmInfoBarDelegate(
121 TabContents* tab_contents, 214 TabContents* tab_contents,
122 PluginGroup* reader_group) // NULL if Adobe Reader isn't installed. 215 PluginGroup* reader_group) // NULL if Adobe Reader isn't installed.
123 : ConfirmInfoBarDelegate(tab_contents), 216 : ConfirmInfoBarDelegate(tab_contents),
124 tab_contents_(tab_contents), 217 tab_contents_(tab_contents),
125 reader_installed_(!!reader_group), 218 reader_installed_(!!reader_group),
126 reader_vulnerable_(false) { 219 reader_vulnerable_(false) {
127 if (reader_installed_) { 220 if (reader_installed_) {
221 UserMetrics::RecordAction(UserMetricsAction("PDF_UseReaderInfoBarShown"));
128 std::vector<WebPluginInfo> plugins = reader_group->web_plugin_infos(); 222 std::vector<WebPluginInfo> plugins = reader_group->web_plugin_infos();
129 DCHECK_EQ(plugins.size(), 1u); 223 DCHECK_EQ(plugins.size(), 1u);
130 reader_webplugininfo_ = plugins[0]; 224 reader_webplugininfo_ = plugins[0];
131 225
132 reader_vulnerable_ = reader_group->IsVulnerable(); 226 reader_vulnerable_ = reader_group->IsVulnerable();
133 if (!reader_vulnerable_) { 227 if (!reader_vulnerable_) {
134 scoped_ptr<Version> version(PluginGroup::CreateVersionFromString( 228 scoped_ptr<Version> version(PluginGroup::CreateVersionFromString(
135 reader_webplugininfo_.version)); 229 reader_webplugininfo_.version));
136 if (version.get()) { 230 if (version.get()) {
137 if (version->components()[0] < kMinReaderVersionToUse) 231 if (version->components()[0] < kMinReaderVersionToUse)
138 reader_vulnerable_ = true; 232 reader_vulnerable_ = true;
139 } 233 }
140 } 234 }
235 } else {
236 UserMetrics::RecordAction(
237 UserMetricsAction("PDF_InstallReaderInfoBarShown"));
141 } 238 }
142 } 239 }
143 240
144 // ConfirmInfoBarDelegate 241 // ConfirmInfoBarDelegate
145 virtual void InfoBarClosed() { 242 virtual void InfoBarClosed() {
146 delete this; 243 delete this;
147 } 244 }
148 virtual Type GetInfoBarType() { 245
246 virtual void InfoBarDismissed() {
247 Cancel();
248 }
249
250 virtual Type GetInfoBarType() const {
149 return PAGE_ACTION_TYPE; 251 return PAGE_ACTION_TYPE;
150 } 252 }
253
151 virtual bool Accept() { 254 virtual bool Accept() {
152 LaunchReader(); 255 if (!reader_installed_) {
256 UserMetrics::RecordAction(
257 UserMetricsAction("PDF_InstallReaderInfoBarOK"));
258 OpenReaderUpdateURL(tab_contents_);
259 return true;
260 }
261
262 UserMetrics::RecordAction(
263 UserMetricsAction("PDF_UseReaderInfoBarOK"));
264
265 if (reader_vulnerable_) {
266 PDFUnsupportedFeatureInterstitial* interstitial = new
267 PDFUnsupportedFeatureInterstitial(
268 tab_contents_, reader_webplugininfo_);
269 interstitial->Show();
270 return true;
271 }
272
273 OpenUsingReader(tab_contents_, reader_webplugininfo_, this);
274 return false;
275 }
276
277 virtual bool Cancel() {
278 if (reader_installed_) {
279 UserMetrics::RecordAction(
280 UserMetricsAction("PDF_UseReaderInfoBarCancel"));
281 } else {
282 UserMetrics::RecordAction(
283 UserMetricsAction("PDF_InstallReaderInfoBarCancel"));
284 }
153 return true; 285 return true;
154 } 286 }
287
155 virtual int GetButtons() const { 288 virtual int GetButtons() const {
156 return BUTTON_OK | BUTTON_CANCEL; 289 return BUTTON_OK | BUTTON_CANCEL;
157 } 290 }
291
158 virtual string16 GetButtonLabel(InfoBarButton button) const { 292 virtual string16 GetButtonLabel(InfoBarButton button) const {
159 switch (button) { 293 switch (button) {
160 case BUTTON_OK: 294 case BUTTON_OK:
161 return l10n_util::GetStringUTF16( 295 return l10n_util::GetStringUTF16(
162 IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL); 296 IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL);
163 case BUTTON_CANCEL: 297 case BUTTON_CANCEL:
164 return l10n_util::GetStringUTF16( 298 return l10n_util::GetStringUTF16(
165 IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL); 299 IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL);
166 default: 300 default:
167 // All buttons are labeled above. 301 // All buttons are labeled above.
168 NOTREACHED() << "Bad button id " << button; 302 NOTREACHED() << "Bad button id " << button;
169 return string16(); 303 return string16();
170 } 304 }
171 } 305 }
306
172 virtual string16 GetMessageText() const { 307 virtual string16 GetMessageText() const {
173 return l10n_util::GetStringUTF16(reader_installed_ ? 308 return l10n_util::GetStringUTF16(reader_installed_ ?
174 IDS_PDF_INFOBAR_QUESTION_READER_INSTALLED : 309 IDS_PDF_INFOBAR_QUESTION_READER_INSTALLED :
175 IDS_PDF_INFOBAR_QUESTION_READER_NOT_INSTALLED); 310 IDS_PDF_INFOBAR_QUESTION_READER_NOT_INSTALLED);
176 } 311 }
177 312
178 private: 313 private:
179 void LaunchReader() {
180 if (!reader_installed_) {
181 OpenReaderUpdateURL(tab_contents_);
182 return;
183 }
184
185 if (reader_vulnerable_) {
186 PDFUnsupportedFeatureInterstitial* interstitial = new
187 PDFUnsupportedFeatureInterstitial(
188 tab_contents_, reader_webplugininfo_);
189 interstitial->Show();
190 return;
191 }
192
193 OpenUsingReader(tab_contents_, reader_webplugininfo_);
194 }
195
196 TabContents* tab_contents_; 314 TabContents* tab_contents_;
197 bool reader_installed_; 315 bool reader_installed_;
198 bool reader_vulnerable_; 316 bool reader_vulnerable_;
199 WebPluginInfo reader_webplugininfo_; 317 WebPluginInfo reader_webplugininfo_;
200 318
201 DISALLOW_IMPLICIT_CONSTRUCTORS(PDFUnsupportedFeatureConfirmInfoBarDelegate); 319 DISALLOW_IMPLICIT_CONSTRUCTORS(PDFUnsupportedFeatureConfirmInfoBarDelegate);
202 }; 320 };
203 321
204 } // namespace 322 } // namespace
205 323
206 void PDFHasUnsupportedFeature(TabContents* tab) { 324 void PDFHasUnsupportedFeature(TabContents* tab) {
207 #if !defined(OS_WIN) 325 #if !defined(OS_WIN)
208 // Only works for Windows for now. For Mac, we'll have to launch the file 326 // Only works for Windows for now. For Mac, we'll have to launch the file
209 // externally since Adobe Reader doesn't work inside Chrome. 327 // externally since Adobe Reader doesn't work inside Chrome.
210 return; 328 return;
211 #endif 329 #endif
330 string16 reader_group_name(ASCIIToUTF16(PluginGroup::kAdobeReaderGroupName));
331
332 // If the Reader plugin is disabled by policy, don't prompt them.
333 if (PluginGroup::IsPluginNameDisabledByPolicy(reader_group_name))
334 return;
212 335
213 PluginGroup* reader_group = NULL; 336 PluginGroup* reader_group = NULL;
214 std::vector<PluginGroup> plugin_groups; 337 std::vector<PluginGroup> plugin_groups;
215 PluginList::Singleton()->GetPluginGroups( 338 PluginList::Singleton()->GetPluginGroups(
216 false, &plugin_groups); 339 false, &plugin_groups);
217 string16 reader_group_name(UTF8ToUTF16(PluginGroup::kAdobeReaderGroupName));
218 for (size_t i = 0; i < plugin_groups.size(); ++i) { 340 for (size_t i = 0; i < plugin_groups.size(); ++i) {
219 if (plugin_groups[i].GetGroupName() == reader_group_name) { 341 if (plugin_groups[i].GetGroupName() == reader_group_name) {
220 reader_group = &plugin_groups[i]; 342 reader_group = &plugin_groups[i];
221 break; 343 break;
222 } 344 }
223 } 345 }
224 346
225 // If the plugin is disabled by policy or by the user, don't prompt them.
226 if (reader_group && !reader_group->Enabled())
227 return;
228
229 tab->AddInfoBar(new PDFUnsupportedFeatureConfirmInfoBarDelegate( 347 tab->AddInfoBar(new PDFUnsupportedFeatureConfirmInfoBarDelegate(
230 tab, reader_group)); 348 tab, reader_group));
231 } 349 }
OLDNEW
« no previous file with comments | « no previous file | chrome/tools/chromeactions.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698