| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/ui/pdf/pdf_unsupported_feature.h" | 5 #include "chrome/browser/ui/pdf/pdf_unsupported_feature.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "base/version.h" | 10 #include "base/version.h" |
| 11 #include "chrome/browser/chrome_plugin_service_filter.h" | 11 #include "chrome/browser/chrome_plugin_service_filter.h" |
| 12 #include "chrome/browser/infobars/infobar_tab_helper.h" | 12 #include "chrome/browser/infobars/infobar_tab_helper.h" |
| 13 #include "chrome/browser/plugin_finder.h" |
| 14 #include "chrome/browser/plugin_installer.h" |
| 13 #include "chrome/browser/plugin_prefs.h" | 15 #include "chrome/browser/plugin_prefs.h" |
| 14 #include "chrome/browser/prefs/pref_service.h" | 16 #include "chrome/browser/prefs/pref_service.h" |
| 15 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 16 #include "chrome/browser/renderer_preferences_util.h" | 18 #include "chrome/browser/renderer_preferences_util.h" |
| 17 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" | 19 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" |
| 18 #include "chrome/browser/tab_contents/tab_util.h" | 20 #include "chrome/browser/tab_contents/tab_util.h" |
| 19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 21 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| 20 #include "chrome/common/chrome_content_client.h" | 22 #include "chrome/common/chrome_content_client.h" |
| 21 #include "chrome/common/jstemplate_builder.h" | 23 #include "chrome/common/jstemplate_builder.h" |
| 22 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 39 using content::OpenURLParams; | 41 using content::OpenURLParams; |
| 40 using content::PluginService; | 42 using content::PluginService; |
| 41 using content::Referrer; | 43 using content::Referrer; |
| 42 using content::UserMetricsAction; | 44 using content::UserMetricsAction; |
| 43 using content::WebContents; | 45 using content::WebContents; |
| 44 using webkit::npapi::PluginGroup; | 46 using webkit::npapi::PluginGroup; |
| 45 using webkit::WebPluginInfo; | 47 using webkit::WebPluginInfo; |
| 46 | 48 |
| 47 namespace { | 49 namespace { |
| 48 | 50 |
| 49 // Only launch Adobe Reader X or later. | |
| 50 static const uint16 kMinReaderVersionToUse = 10; | |
| 51 | |
| 52 static const char kReaderUpdateUrl[] = | 51 static const char kReaderUpdateUrl[] = |
| 53 "http://www.adobe.com/go/getreader_chrome"; | 52 "http://www.adobe.com/go/getreader_chrome"; |
| 54 | 53 |
| 55 // The info bar delegate used to ask the user if they want to use Adobe Reader | 54 // The info bar delegate used to ask the user if they want to use Adobe Reader |
| 56 // by default. We want the infobar to have [No][Yes], so we swap the text on | 55 // by default. We want the infobar to have [No][Yes], so we swap the text on |
| 57 // the buttons, and the meaning of the delegate callbacks. | 56 // the buttons, and the meaning of the delegate callbacks. |
| 58 class PDFEnableAdobeReaderInfoBarDelegate : public ConfirmInfoBarDelegate { | 57 class PDFEnableAdobeReaderInfoBarDelegate : public ConfirmInfoBarDelegate { |
| 59 public: | 58 public: |
| 60 explicit PDFEnableAdobeReaderInfoBarDelegate( | 59 explicit PDFEnableAdobeReaderInfoBarDelegate( |
| 61 InfoBarTabHelper* infobar_helper, | 60 InfoBarTabHelper* infobar_helper, |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 InterstitialPage* interstitial_page_; // Owns us. | 242 InterstitialPage* interstitial_page_; // Owns us. |
| 244 | 243 |
| 245 DISALLOW_COPY_AND_ASSIGN(PDFUnsupportedFeatureInterstitial); | 244 DISALLOW_COPY_AND_ASSIGN(PDFUnsupportedFeatureInterstitial); |
| 246 }; | 245 }; |
| 247 | 246 |
| 248 // The info bar delegate used to inform the user that we don't support a feature | 247 // The info bar delegate used to inform the user that we don't support a feature |
| 249 // in the PDF. See the comment about how we swap buttons for | 248 // in the PDF. See the comment about how we swap buttons for |
| 250 // PDFEnableAdobeReaderInfoBarDelegate. | 249 // PDFEnableAdobeReaderInfoBarDelegate. |
| 251 class PDFUnsupportedFeatureInfoBarDelegate : public ConfirmInfoBarDelegate { | 250 class PDFUnsupportedFeatureInfoBarDelegate : public ConfirmInfoBarDelegate { |
| 252 public: | 251 public: |
| 253 // |reader_group| is NULL if Adobe Reader isn't installed. | 252 // |reader| is NULL if Adobe Reader isn't installed. |
| 254 PDFUnsupportedFeatureInfoBarDelegate(TabContentsWrapper* tab_contents, | 253 PDFUnsupportedFeatureInfoBarDelegate(TabContentsWrapper* tab_contents, |
| 255 const PluginGroup* reader_group); | 254 const webkit::WebPluginInfo* reader, |
| 255 PluginFinder* plugin_finder); |
| 256 virtual ~PDFUnsupportedFeatureInfoBarDelegate(); | 256 virtual ~PDFUnsupportedFeatureInfoBarDelegate(); |
| 257 | 257 |
| 258 // ConfirmInfoBarDelegate | 258 // ConfirmInfoBarDelegate |
| 259 virtual void InfoBarDismissed() OVERRIDE; | 259 virtual void InfoBarDismissed() OVERRIDE; |
| 260 virtual gfx::Image* GetIcon() const OVERRIDE; | 260 virtual gfx::Image* GetIcon() const OVERRIDE; |
| 261 virtual Type GetInfoBarType() const OVERRIDE; | 261 virtual Type GetInfoBarType() const OVERRIDE; |
| 262 virtual bool Accept() OVERRIDE; | 262 virtual bool Accept() OVERRIDE; |
| 263 virtual bool Cancel() OVERRIDE; | 263 virtual bool Cancel() OVERRIDE; |
| 264 virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE; | 264 virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE; |
| 265 virtual string16 GetMessageText() const OVERRIDE; | 265 virtual string16 GetMessageText() const OVERRIDE; |
| 266 | 266 |
| 267 private: | 267 private: |
| 268 bool OnYes(); | 268 bool OnYes(); |
| 269 void OnNo(); | 269 void OnNo(); |
| 270 | 270 |
| 271 TabContentsWrapper* tab_contents_; | 271 TabContentsWrapper* tab_contents_; |
| 272 bool reader_installed_; | 272 bool reader_installed_; |
| 273 bool reader_vulnerable_; | 273 bool reader_vulnerable_; |
| 274 WebPluginInfo reader_webplugininfo_; | 274 WebPluginInfo reader_webplugininfo_; |
| 275 | 275 |
| 276 DISALLOW_IMPLICIT_CONSTRUCTORS(PDFUnsupportedFeatureInfoBarDelegate); | 276 DISALLOW_IMPLICIT_CONSTRUCTORS(PDFUnsupportedFeatureInfoBarDelegate); |
| 277 }; | 277 }; |
| 278 | 278 |
| 279 PDFUnsupportedFeatureInfoBarDelegate::PDFUnsupportedFeatureInfoBarDelegate( | 279 PDFUnsupportedFeatureInfoBarDelegate::PDFUnsupportedFeatureInfoBarDelegate( |
| 280 TabContentsWrapper* tab_contents, | 280 TabContentsWrapper* tab_contents, |
| 281 const PluginGroup* reader_group) | 281 const webkit::WebPluginInfo* reader, |
| 282 PluginFinder* plugin_finder) |
| 282 : ConfirmInfoBarDelegate(tab_contents->infobar_tab_helper()), | 283 : ConfirmInfoBarDelegate(tab_contents->infobar_tab_helper()), |
| 283 tab_contents_(tab_contents), | 284 tab_contents_(tab_contents), |
| 284 reader_installed_(!!reader_group), | 285 reader_installed_(!!reader), |
| 285 reader_vulnerable_(false) { | 286 reader_vulnerable_(false) { |
| 286 if (!reader_installed_) { | 287 if (!reader_installed_) { |
| 287 content::RecordAction( | 288 content::RecordAction( |
| 288 UserMetricsAction("PDF_InstallReaderInfoBarShown")); | 289 UserMetricsAction("PDF_InstallReaderInfoBarShown")); |
| 289 return; | 290 return; |
| 290 } | 291 } |
| 291 | 292 |
| 292 content::RecordAction(UserMetricsAction("PDF_UseReaderInfoBarShown")); | 293 content::RecordAction(UserMetricsAction("PDF_UseReaderInfoBarShown")); |
| 293 const std::vector<WebPluginInfo>& plugins = | 294 reader_webplugininfo_ = *reader; |
| 294 reader_group->web_plugin_infos(); | |
| 295 DCHECK_EQ(plugins.size(), 1u); | |
| 296 reader_webplugininfo_ = plugins[0]; | |
| 297 | 295 |
| 298 reader_vulnerable_ = reader_group->IsVulnerable(reader_webplugininfo_); | 296 PluginInstaller* installer = |
| 299 if (!reader_vulnerable_) { | 297 plugin_finder->FindPluginWithIdentifier("adobe-reader"); |
| 300 scoped_ptr<Version> version(PluginGroup::CreateVersionFromString( | 298 |
| 301 reader_webplugininfo_.version)); | 299 reader_vulnerable_ = |
| 302 reader_vulnerable_ = | 300 installer->GetSecurityStatus(*reader) != |
| 303 version.get() && (version->components()[0] < kMinReaderVersionToUse); | 301 PluginInstaller::SECURITY_STATUS_UP_TO_DATE; |
| 304 } | |
| 305 } | 302 } |
| 306 | 303 |
| 307 PDFUnsupportedFeatureInfoBarDelegate::~PDFUnsupportedFeatureInfoBarDelegate() { | 304 PDFUnsupportedFeatureInfoBarDelegate::~PDFUnsupportedFeatureInfoBarDelegate() { |
| 308 } | 305 } |
| 309 | 306 |
| 310 void PDFUnsupportedFeatureInfoBarDelegate::InfoBarDismissed() { | 307 void PDFUnsupportedFeatureInfoBarDelegate::InfoBarDismissed() { |
| 311 OnNo(); | 308 OnNo(); |
| 312 } | 309 } |
| 313 | 310 |
| 314 gfx::Image* PDFUnsupportedFeatureInfoBarDelegate::GetIcon() const { | 311 gfx::Image* PDFUnsupportedFeatureInfoBarDelegate::GetIcon() const { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 } | 367 } |
| 371 | 368 |
| 372 void PDFUnsupportedFeatureInfoBarDelegate::OnNo() { | 369 void PDFUnsupportedFeatureInfoBarDelegate::OnNo() { |
| 373 content::RecordAction(reader_installed_ ? | 370 content::RecordAction(reader_installed_ ? |
| 374 UserMetricsAction("PDF_UseReaderInfoBarCancel") : | 371 UserMetricsAction("PDF_UseReaderInfoBarCancel") : |
| 375 UserMetricsAction("PDF_InstallReaderInfoBarCancel")); | 372 UserMetricsAction("PDF_InstallReaderInfoBarCancel")); |
| 376 } | 373 } |
| 377 | 374 |
| 378 void GotPluginGroupsCallback(int process_id, | 375 void GotPluginGroupsCallback(int process_id, |
| 379 int routing_id, | 376 int routing_id, |
| 377 PluginFinder* plugin_finder, |
| 380 const std::vector<PluginGroup>& groups) { | 378 const std::vector<PluginGroup>& groups) { |
| 381 WebContents* web_contents = | 379 WebContents* web_contents = |
| 382 tab_util::GetWebContentsByID(process_id, routing_id); | 380 tab_util::GetWebContentsByID(process_id, routing_id); |
| 383 if (!web_contents) | 381 if (!web_contents) |
| 384 return; | 382 return; |
| 385 | 383 |
| 386 TabContentsWrapper* tab = | 384 TabContentsWrapper* tab = |
| 387 TabContentsWrapper::GetCurrentWrapperForContents(web_contents); | 385 TabContentsWrapper::GetCurrentWrapperForContents(web_contents); |
| 388 if (!tab) | 386 if (!tab) |
| 389 return; | 387 return; |
| 390 | 388 |
| 391 string16 reader_group_name(ASCIIToUTF16(PluginGroup::kAdobeReaderGroupName)); | 389 string16 reader_group_name(ASCIIToUTF16(PluginGroup::kAdobeReaderGroupName)); |
| 392 | |
| 393 // If the Reader plugin is disabled by policy, don't prompt them. | 390 // If the Reader plugin is disabled by policy, don't prompt them. |
| 394 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(tab->profile()); | 391 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(tab->profile()); |
| 395 if (plugin_prefs->PolicyStatusForPlugin(reader_group_name) == | 392 if (plugin_prefs->PolicyStatusForPlugin(reader_group_name) == |
| 396 PluginPrefs::POLICY_DISABLED) { | 393 PluginPrefs::POLICY_DISABLED) { |
| 397 return; | 394 return; |
| 398 } | 395 } |
| 399 | 396 |
| 400 const PluginGroup* reader_group = NULL; | 397 const webkit::WebPluginInfo* reader = NULL; |
| 401 for (size_t i = 0; i < groups.size(); ++i) { | 398 for (size_t i = 0; i < groups.size(); ++i) { |
| 402 if (groups[i].GetGroupName() == reader_group_name) { | 399 if (groups[i].GetGroupName() == reader_group_name) { |
| 403 reader_group = &groups[i]; | 400 const std::vector<WebPluginInfo>& plugins = |
| 401 groups[i].web_plugin_infos(); |
| 402 DCHECK_EQ(plugins.size(), 1u); |
| 403 reader = &plugins[0]; |
| 404 break; | 404 break; |
| 405 } | 405 } |
| 406 } | 406 } |
| 407 | 407 |
| 408 tab->infobar_tab_helper()->AddInfoBar( | 408 tab->infobar_tab_helper()->AddInfoBar( |
| 409 new PDFUnsupportedFeatureInfoBarDelegate(tab, reader_group)); | 409 new PDFUnsupportedFeatureInfoBarDelegate(tab, reader, plugin_finder)); |
| 410 } |
| 411 |
| 412 void GotPluginFinderCallback(int process_id, |
| 413 int routing_id, |
| 414 PluginFinder* plugin_finder) { |
| 415 PluginService::GetInstance()->GetPluginGroups( |
| 416 base::Bind(&GotPluginGroupsCallback, process_id, routing_id, |
| 417 base::Unretained(plugin_finder))); |
| 410 } | 418 } |
| 411 | 419 |
| 412 } // namespace | 420 } // namespace |
| 413 | 421 |
| 414 void PDFHasUnsupportedFeature(TabContentsWrapper* tab) { | 422 void PDFHasUnsupportedFeature(TabContentsWrapper* tab) { |
| 415 #if !defined(OS_WIN) | 423 #if !defined(OS_WIN) |
| 416 // Only works for Windows for now. For Mac, we'll have to launch the file | 424 // Only works for Windows for now. For Mac, we'll have to launch the file |
| 417 // externally since Adobe Reader doesn't work inside Chrome. | 425 // externally since Adobe Reader doesn't work inside Chrome. |
| 418 return; | 426 return; |
| 419 #endif | 427 #endif |
| 420 | 428 |
| 421 PluginService::GetInstance()->GetPluginGroups( | 429 PluginFinder::Get(base::Bind(&GotPluginFinderCallback, |
| 422 base::Bind(&GotPluginGroupsCallback, | 430 tab->web_contents()->GetRenderProcessHost()->GetID(), |
| 423 tab->web_contents()->GetRenderProcessHost()->GetID(), | 431 tab->web_contents()->GetRenderViewHost()->GetRoutingID())); |
| 424 tab->web_contents()->GetRenderViewHost()->GetRoutingID())); | |
| 425 } | 432 } |
| OLD | NEW |