diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-22 00:05:17 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-22 00:05:17 +0000 |
commit | c8f73aba9f1fd8b2e0a34fcca08a1e968ddd8244 (patch) | |
tree | d2658c6f1da345a1f38531809250c934dd4d73fa /chrome | |
parent | 090d7108424b5a8600e1b590b2227e52f23d6e7e (diff) | |
download | chromium_src-c8f73aba9f1fd8b2e0a34fcca08a1e968ddd8244.zip chromium_src-c8f73aba9f1fd8b2e0a34fcca08a1e968ddd8244.tar.gz chromium_src-c8f73aba9f1fd8b2e0a34fcca08a1e968ddd8244.tar.bz2 |
When we detect a PDF with an unsupported feature, ask the user if they want to view it with Adobe Reader if it's installed. If it's not, ask them if they want to launch the url to install it. If it's installed and out of date, show an interstitial.
BUG=65339
Review URL: http://codereview.chromium.org/6259008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72240 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
24 files changed, 518 insertions, 47 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index ee7596b..9fc08e7 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -11144,6 +11144,35 @@ Keep your key file in a safe place. You will need it to create new versions of y The credentials used to share your printers to <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph> have expired. Please click here to re-enter your username and password. </message> + <!-- PDF with unsupported feature Info Bar --> + <message name="IDS_PDF_INFOBAR_QUESTION_READER_INSTALLED" desc="Question asked on the info bar when a user views a PDF with an unsupported feature and they have Adobe Reader installed."> + Parts of this PDF document could not be displayed. View with Adobe Reader? + </message> + + <message name="IDS_PDF_INFOBAR_QUESTION_READER_NOT_INSTALLED" desc="Question asked on the info bar when a user views a PDF with an unsupported feature and they don't have Adobe Reader installed."> + Parts of this PDF document could not be displayed. Install Adobe Reader? + </message> + + <!-- Adobe Reader is out of date Blocking Page --> + <message name="IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_TITLE" desc="The title of the Adobe Reader out of date blocking page."> + Adobe Reader Out Of Date + </message> + <message name="IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_BODY" desc="The body of the Adobe Reader out of date blocking page."> + Adobe Reader is out of date and may be insecure. + </message> + <message name="IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_UPDATE" desc="The name of the radio button option to go to the Adobe Reader installer website."> + Update Adobe Reader now + </message> + <message name="IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_PROCEED" desc="The name of the radio button to proceed to open the PDF with the out of date Adobe Reader."> + Proceed without updating Adobe Reader (not recommended) + </message> + <message name="IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_OK" desc="OK button text of the Adobe Reader out of date blocking page."> + OK + </message> + <message name="IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_CANCEL" desc="Cancel button text of the Adobe Reader out of date blocking page."> + Cancel + </message> + </messages> <includes> <if expr="pp_ifdef('_google_chrome')"> diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 27beb5f..907deb4 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -52,6 +52,7 @@ without changes to the corresponding grd file. etaa --> <include name="IDR_NOTIFICATION_ICON_HTML" file="resources\notification_icon.html" type="BINDATA" /> <include name="IDR_OPTIONS_HTML" file="resources\options\options.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_PLUGINS_HTML" file="resources\plugins.html" flattenhtml="true" type="BINDATA" /> + <include name="IDR_READER_OUT_OF_DATE_HTML" file="resources\reader_out_of_date.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_PRINT_PREVIEW_HTML" file="resources\print_preview.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_SAFE_BROWSING_MALWARE_BLOCK" file="resources\safe_browsing_malware_block.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_SAFE_BROWSING_MULTIPLE_THREAT_BLOCK" file="resources\safe_browsing_multiple_threat_block.html" flattenhtml="true" type="BINDATA" /> diff --git a/chrome/browser/pdf_unsupported_feature.cc b/chrome/browser/pdf_unsupported_feature.cc new file mode 100644 index 0000000..2e89da2 --- /dev/null +++ b/chrome/browser/pdf_unsupported_feature.cc @@ -0,0 +1,231 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/pdf_unsupported_feature.h" + +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "base/utf_string_conversions.h" +#include "base/values.h" +#include "base/version.h" +#include "chrome/browser/plugin_service.h" +#include "chrome/browser/renderer_host/render_process_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/tab_contents/infobar_delegate.h" +#include "chrome/browser/tab_contents/interstitial_page.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/jstemplate_builder.h" +#include "grit/browser_resources.h" +#include "grit/generated_resources.h" +#include "webkit/plugins/npapi/plugin_group.h" +#include "webkit/plugins/npapi/plugin_list.h" +#include "webkit/plugins/npapi/webplugininfo.h" + +using webkit::npapi::PluginGroup; +using webkit::npapi::PluginList; +using webkit::npapi::WebPluginInfo; + +// Only launch Adobe Reader X or later. +static const uint16 kMinReaderVersionToUse = 10; + +namespace { + +// Launch the url to get the latest Adbobe Reader installer. +void OpenReaderUpdateURL(TabContents* tab) { + tab->OpenURL(GURL(PluginGroup::kAdobeReaderUpdateURL), GURL(), CURRENT_TAB, + PageTransition::LINK); +} + +// Opens the PDF using Adobe Reader. +void OpenUsingReader(TabContents* tab, const WebPluginInfo& reader_plugin) { + PluginService::OverriddenPlugin plugin; + plugin.render_process_id = tab->GetRenderProcessHost()->id(); + plugin.render_view_id = tab->render_view_host()->routing_id(); + plugin.url = tab->GetURL(); + plugin.plugin = reader_plugin; + + PluginService::GetInstance()->OverridePluginForTab(plugin); + tab->render_view_host()->ReloadFrame(); +} + +// An interstitial to be used when the user chooses to open a PDF using Adobe +// Reader, but it is out of date. +class PDFUnsupportedFeatureInterstitial : public InterstitialPage { + public: + PDFUnsupportedFeatureInterstitial( + TabContents* tab, + const WebPluginInfo& reader_webplugininfo) + : InterstitialPage(tab, false, tab->GetURL()), + reader_webplugininfo_(reader_webplugininfo) { + } + + protected: + // InterstitialPage implementation. + virtual std::string GetHTMLContents() { + DictionaryValue strings; + strings.SetString( + "title", + l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_TITLE)); + strings.SetString( + "headLine", + l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_BODY)); + strings.SetString( + "update", + l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_UPDATE)); + strings.SetString( + "open_with_reader", + l10n_util::GetStringUTF16( + IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_PROCEED)); + strings.SetString( + "ok", + l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_OK)); + strings.SetString( + "cancel", + l10n_util::GetStringUTF16(IDS_READER_OUT_OF_DATE_BLOCKING_PAGE_CANCEL)); + + base::StringPiece html(ResourceBundle::GetSharedInstance(). + GetRawDataResource(IDR_READER_OUT_OF_DATE_HTML)); + + return jstemplate_builder::GetI18nTemplateHtml(html, &strings); + } + + virtual void CommandReceived(const std::string& command) { + if (command == "0") { + DontProceed(); + return; + } + + if (command == "1") { + OpenReaderUpdateURL(tab()); + } else if (command == "2") { + OpenUsingReader(tab(), reader_webplugininfo_); + } else { + NOTREACHED(); + } + Proceed(); + } + + private: + WebPluginInfo reader_webplugininfo_; + + DISALLOW_COPY_AND_ASSIGN(PDFUnsupportedFeatureInterstitial); +}; + +// The info bar delegate used to inform the user that we don't support a feature +// in the PDF. +class PDFUnsupportedFeatureConfirmInfoBarDelegate + : public ConfirmInfoBarDelegate { + public: + PDFUnsupportedFeatureConfirmInfoBarDelegate( + TabContents* tab_contents, + PluginGroup* reader_group) // NULL if Adobe Reader isn't installed. + : ConfirmInfoBarDelegate(tab_contents), + tab_contents_(tab_contents), + reader_installed_(!!reader_group), + reader_vulnerable_(false) { + if (reader_installed_) { + std::vector<WebPluginInfo> plugins = reader_group->web_plugin_infos(); + DCHECK_EQ(plugins.size(), 1u); + reader_webplugininfo_ = plugins[0]; + + reader_vulnerable_ = reader_group->IsVulnerable(); + if (!reader_vulnerable_) { + scoped_ptr<Version> version(PluginGroup::CreateVersionFromString( + reader_webplugininfo_.version)); + if (version.get()) { + if (version->components()[0] < kMinReaderVersionToUse) + reader_vulnerable_ = true; + } + } + } + } + + // ConfirmInfoBarDelegate + virtual void InfoBarClosed() { + delete this; + } + virtual Type GetInfoBarType() { + return PAGE_ACTION_TYPE; + } + virtual bool Accept() { + LaunchReader(); + return true; + } + virtual int GetButtons() const { + return BUTTON_OK | BUTTON_CANCEL; + } + virtual string16 GetButtonLabel(InfoBarButton button) const { + switch (button) { + case BUTTON_OK: + return l10n_util::GetStringUTF16( + IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL); + case BUTTON_CANCEL: + return l10n_util::GetStringUTF16( + IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL); + default: + // All buttons are labeled above. + NOTREACHED() << "Bad button id " << button; + return string16(); + } + } + virtual string16 GetMessageText() const { + return l10n_util::GetStringUTF16(reader_installed_ ? + IDS_PDF_INFOBAR_QUESTION_READER_INSTALLED : + IDS_PDF_INFOBAR_QUESTION_READER_NOT_INSTALLED); + } + + private: + void LaunchReader() { + if (!reader_installed_) { + OpenReaderUpdateURL(tab_contents_); + return; + } + + if (reader_vulnerable_) { + PDFUnsupportedFeatureInterstitial* interstitial = new + PDFUnsupportedFeatureInterstitial( + tab_contents_, reader_webplugininfo_); + interstitial->Show(); + return; + } + + OpenUsingReader(tab_contents_, reader_webplugininfo_); + } + + TabContents* tab_contents_; + bool reader_installed_; + bool reader_vulnerable_; + WebPluginInfo reader_webplugininfo_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(PDFUnsupportedFeatureConfirmInfoBarDelegate); +}; + +} // namespace + +void PDFHasUnsupportedFeature(TabContents* tab) { +#if !defined(OS_WIN) + // Only works for Windows for now. For Mac, we'll have to launch the file + // externally since Adobe Reader doesn't work inside Chrome. + return; +#endif + + PluginGroup* reader_group = NULL; + std::vector<PluginGroup> plugin_groups; + PluginList::Singleton()->GetPluginGroups( + false, &plugin_groups); + string16 reader_group_name(UTF8ToUTF16(PluginGroup::kAdobeReaderGroupName)); + for (size_t i = 0; i < plugin_groups.size(); ++i) { + if (plugin_groups[i].GetGroupName() == reader_group_name) { + reader_group = &plugin_groups[i]; + break; + } + } + + // If the plugin is disabled by policy or by the user, don't prompt them. + if (reader_group && !reader_group->Enabled()) + return; + + tab->AddInfoBar(new PDFUnsupportedFeatureConfirmInfoBarDelegate( + tab, reader_group)); +} diff --git a/chrome/browser/pdf_unsupported_feature.h b/chrome/browser/pdf_unsupported_feature.h new file mode 100644 index 0000000..e6e4f64 --- /dev/null +++ b/chrome/browser/pdf_unsupported_feature.h @@ -0,0 +1,19 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PDF_UNSUPPORTED_FEATURE_H_ +#define CHROME_BROWSER_PDF_UNSUPPORTED_FEATURE_H_ +#pragma once + +#include "base/basictypes.h" + +class TabContents; + +// Call this when a tab encounters a PDF that has features which our internal +// viewer doesn't support. Will take care of puting up an infobar to inform the +// user and launch Reader if they choose. If Reader is out of date, it will put +// up an interstitial. +void PDFHasUnsupportedFeature(TabContents* tab); + +#endif // CHROME_BROWSER_PDF_UNSUPPORTED_FEATURE_H_ diff --git a/chrome/browser/plugin_data_remover.cc b/chrome/browser/plugin_data_remover.cc index 89e0ece..bfc9811 100644 --- a/chrome/browser/plugin_data_remover.cc +++ b/chrome/browser/plugin_data_remover.cc @@ -50,7 +50,7 @@ base::WaitableEvent* PluginDataRemover::StartRemoving( AddRef(); PluginService::GetInstance()->OpenChannelToPlugin( - GURL(), mime_type_, this); + 0, 0, GURL(), mime_type_, this); BrowserThread::PostDelayedTask( BrowserThread::IO, diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc index b9774e8..4cf18ec 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -20,6 +20,7 @@ #include "chrome/browser/plugin_updater.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/common/chrome_plugin_lib.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" @@ -211,6 +212,9 @@ PluginService::PluginService() #endif registrar_.Add(this, NotificationType::PLUGIN_ENABLE_STATUS_CHANGED, NotificationService::AllSources()); + registrar_.Add(this, + NotificationType::RENDERER_PROCESS_CLOSED, + NotificationService::AllSources()); } PluginService::~PluginService() { @@ -285,6 +289,8 @@ PluginProcessHost* PluginService::FindOrStartPluginProcess( } void PluginService::OpenChannelToPlugin( + int render_process_id, + int render_view_id, const GURL& url, const std::string& mime_type, PluginProcessHost::Client* client) { @@ -294,16 +300,19 @@ void PluginService::OpenChannelToPlugin( BrowserThread::FILE, FROM_HERE, NewRunnableMethod( this, &PluginService::GetAllowedPluginForOpenChannelToPlugin, - url, mime_type, client)); + render_process_id, render_view_id, url, mime_type, client)); } void PluginService::GetAllowedPluginForOpenChannelToPlugin( + int render_process_id, + int render_view_id, const GURL& url, const std::string& mime_type, PluginProcessHost::Client* client) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); webkit::npapi::WebPluginInfo info; - bool found = GetFirstAllowedPluginInfo(url, mime_type, &info, NULL); + bool found = GetFirstAllowedPluginInfo( + render_process_id, render_view_id, url, mime_type, &info, NULL); FilePath plugin_path; if (found && info.enabled) plugin_path = FilePath(info.path); @@ -329,6 +338,8 @@ void PluginService::FinishOpenChannelToPlugin( } bool PluginService::GetFirstAllowedPluginInfo( + int render_process_id, + int render_view_id, const GURL& url, const std::string& mime_type, webkit::npapi::WebPluginInfo* info, @@ -354,6 +365,18 @@ bool PluginService::GetFirstAllowedPluginInfo( } return false; #else + { + AutoLock auto_lock(overridden_plugins_lock_); + for (size_t i = 0; i < overridden_plugins_.size(); ++i) { + if (overridden_plugins_[i].render_process_id == render_process_id && + overridden_plugins_[i].render_view_id == render_view_id && + overridden_plugins_[i].url == url) { + *actual_mime_type = mime_type; + *info = overridden_plugins_[i].plugin; + return true; + } + } + } return webkit::npapi::PluginList::Singleton()->GetPluginInfo( url, mime_type, allow_wildcard, info, actual_mime_type); #endif @@ -436,6 +459,18 @@ void PluginService::Observe(NotificationType type, PurgePluginListCache(false); break; } + case NotificationType::RENDERER_PROCESS_CLOSED: { + int render_process_id = Source<RenderProcessHost>(source).ptr()->id(); + + AutoLock auto_lock(overridden_plugins_lock_); + for (size_t i = 0; i < overridden_plugins_.size(); ++i) { + if (overridden_plugins_[i].render_process_id == render_process_id) { + overridden_plugins_.erase(overridden_plugins_.begin() + i); + break; + } + } + break; + } default: NOTREACHED(); } @@ -457,6 +492,11 @@ bool PluginService::PrivatePluginAllowedForURL(const FilePath& plugin_path, url.host() == required_url.host()); } +void PluginService::OverridePluginForTab(OverriddenPlugin plugin) { + AutoLock auto_lock(overridden_plugins_lock_); + overridden_plugins_.push_back(plugin); +} + void PluginService::RegisterPepperPlugins() { std::vector<PepperPluginInfo> plugins; PepperPluginRegistry::GetList(&plugins); diff --git a/chrome/browser/plugin_service.h b/chrome/browser/plugin_service.h index 5e03c09..f2732b2 100644 --- a/chrome/browser/plugin_service.h +++ b/chrome/browser/plugin_service.h @@ -16,6 +16,7 @@ #include "base/hash_tables.h" #include "base/scoped_vector.h" #include "base/singleton.h" +#include "base/synchronization/lock.h" #include "base/synchronization/waitable_event_watcher.h" #include "build/build_config.h" #include "chrome/browser/plugin_process_host.h" @@ -23,6 +24,7 @@ #include "chrome/common/notification_registrar.h" #include "googleurl/src/gurl.h" #include "ipc/ipc_channel_handle.h" +#include "webkit/plugins/npapi/webplugininfo.h" #if defined(OS_WIN) #include "base/scoped_ptr.h" @@ -52,18 +54,19 @@ namespace net { class URLRequestContext; } // namespace net -namespace webkit { -namespace npapi { -struct WebPluginInfo; -} -} - // This must be created on the main thread but it's only called on the IO/file // thread. class PluginService : public base::WaitableEventWatcher::Delegate, public NotificationObserver { public: + struct OverriddenPlugin { + int render_process_id; + int render_view_id; + GURL url; + webkit::npapi::WebPluginInfo plugin; + }; + // Initializes the global instance; should be called on startup from the main // thread. static void InitGlobalInstance(Profile* profile); @@ -97,13 +100,17 @@ class PluginService // Opens a channel to a plugin process for the given mime type, starting // a new plugin process if necessary. This must be called on the IO thread // or else a deadlock can occur. - void OpenChannelToPlugin(const GURL& url, + void OpenChannelToPlugin(int render_process_id, + int render_view_id, + const GURL& url, const std::string& mime_type, PluginProcessHost::Client* client); // Gets the first allowed plugin in the list of plugins that matches // the given url and mime type. Must be called on the FILE thread. - bool GetFirstAllowedPluginInfo(const GURL& url, + bool GetFirstAllowedPluginInfo(int render_process_id, + int render_view_id, + const GURL& url, const std::string& mime_type, webkit::npapi::WebPluginInfo* info, std::string* actual_mime_type); @@ -112,6 +119,9 @@ class PluginService // the given URL. bool PrivatePluginAllowedForURL(const FilePath& plugin_path, const GURL& url); + // Safe to be called from any thread. + void OverridePluginForTab(OverriddenPlugin plugin); + // The UI thread's message loop MessageLoop* main_message_loop() { return main_message_loop_; } @@ -140,6 +150,8 @@ class PluginService // Helper so we can do the plugin lookup on the FILE thread. void GetAllowedPluginForOpenChannelToPlugin( + int render_process_id, + int render_view_id, const GURL& url, const std::string& mime_type, PluginProcessHost::Client* client); @@ -203,6 +215,9 @@ class PluginService // Set to true if chrome plugins are enabled. Defaults to true. static bool enable_chrome_plugins_; + std::vector<OverriddenPlugin> overridden_plugins_; + base::Lock overridden_plugins_lock_; + DISALLOW_COPY_AND_ASSIGN(PluginService); }; diff --git a/chrome/browser/plugin_service_browsertest.cc b/chrome/browser/plugin_service_browsertest.cc index 5fed897..3f31159 100644 --- a/chrome/browser/plugin_service_browsertest.cc +++ b/chrome/browser/plugin_service_browsertest.cc @@ -82,7 +82,7 @@ IN_PROC_BROWSER_TEST_F(PluginServiceTest, StartAndFindPluginProcess) { IN_PROC_BROWSER_TEST_F(PluginServiceTest, OpenChannelToPlugin) { MockPluginProcessHostClient mock_client; EXPECT_CALL(mock_client, SetPluginInfo(testing::_)).Times(1); - plugin_service_->OpenChannelToPlugin(GURL("http://google.com/"), + plugin_service_->OpenChannelToPlugin(0, 0, GURL("http://google.com/"), "audio/mp3", &mock_client); message_loop_.RunAllPending(); @@ -97,7 +97,7 @@ IN_PROC_BROWSER_TEST_F(PluginServiceTest, GetFirstAllowedPluginInfo) { // supports all mime types. webkit::npapi::WebPluginInfo plugin_info; std::string plugin_mime_type; - plugin_service_->GetFirstAllowedPluginInfo(GURL("http://google.com/"), + plugin_service_->GetFirstAllowedPluginInfo(0, 0, GURL("http://google.com/"), "application/pdf", &plugin_info, &plugin_mime_type); diff --git a/chrome/browser/renderer_host/render_message_filter.cc b/chrome/browser/renderer_host/render_message_filter.cc index 4156424..e00a6b8 100644 --- a/chrome/browser/renderer_host/render_message_filter.cc +++ b/chrome/browser/renderer_host/render_message_filter.cc @@ -648,7 +648,8 @@ void RenderMessageFilter::OnGetPluginsOnFileThread( NewRunnableMethod(this, &RenderMessageFilter::Send, reply_msg)); } -void RenderMessageFilter::OnGetPluginInfo(const GURL& url, +void RenderMessageFilter::OnGetPluginInfo(int routing_id, + const GURL& url, const GURL& policy_url, const std::string& mime_type, IPC::Message* reply_msg) { @@ -658,20 +659,20 @@ void RenderMessageFilter::OnGetPluginInfo(const GURL& url, BrowserThread::FILE, FROM_HERE, NewRunnableMethod( this, &RenderMessageFilter::OnGetPluginInfoOnFileThread, - url, policy_url, mime_type, reply_msg)); + routing_id, url, policy_url, mime_type, reply_msg)); } void RenderMessageFilter::OnGetPluginInfoOnFileThread( + int render_view_id, const GURL& url, const GURL& policy_url, const std::string& mime_type, IPC::Message* reply_msg) { std::string actual_mime_type; webkit::npapi::WebPluginInfo info; - bool found = plugin_service_->GetFirstAllowedPluginInfo(url, - mime_type, - &info, - &actual_mime_type); + bool found = plugin_service_->GetFirstAllowedPluginInfo( + render_process_id_, render_view_id, url, mime_type, &info, + &actual_mime_type); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, NewRunnableMethod( @@ -704,12 +705,12 @@ void RenderMessageFilter::OnGotPluginInfo( Send(reply_msg); } -void RenderMessageFilter::OnOpenChannelToPlugin(const GURL& url, +void RenderMessageFilter::OnOpenChannelToPlugin(int routing_id, + const GURL& url, const std::string& mime_type, IPC::Message* reply_msg) { plugin_service_->OpenChannelToPlugin( - url, - mime_type, + render_process_id_, routing_id, url, mime_type, new OpenChannelToPluginCallback(this, reply_msg)); } diff --git a/chrome/browser/renderer_host/render_message_filter.h b/chrome/browser/renderer_host/render_message_filter.h index c4af367..dee75a0 100644 --- a/chrome/browser/renderer_host/render_message_filter.h +++ b/chrome/browser/renderer_host/render_message_filter.h @@ -143,11 +143,13 @@ class RenderMessageFilter : public BrowserMessageFilter, #endif void OnGetPlugins(bool refresh, IPC::Message* reply_msg); void OnGetPluginsOnFileThread(bool refresh, IPC::Message* reply_msg); - void OnGetPluginInfo(const GURL& url, + void OnGetPluginInfo(int routing_id, + const GURL& url, const GURL& policy_url, const std::string& mime_type, IPC::Message* reply_msg); - void OnGetPluginInfoOnFileThread(const GURL& url, + void OnGetPluginInfoOnFileThread(int render_view_id, + const GURL& url, const GURL& policy_url, const std::string& mime_type, IPC::Message* reply_msg); @@ -156,7 +158,8 @@ class RenderMessageFilter : public BrowserMessageFilter, const std::string& actual_mime_type, const GURL& policy_url, IPC::Message* reply_msg); - void OnOpenChannelToPlugin(const GURL& url, + void OnOpenChannelToPlugin(int routing_id, + const GURL& url, const std::string& mime_type, IPC::Message* reply_msg); void OnOpenChannelToPepperPlugin(const FilePath& path, diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 5c5e9b3..fc62759 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -847,8 +847,6 @@ bool RenderViewHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_DetectedPhishingSite, OnDetectedPhishingSite) IPC_MESSAGE_HANDLER(ViewHostMsg_ScriptEvalResponse, OnScriptEvalResponse) - IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateContentRestrictions, - OnUpdateContentRestrictions) #if defined(OS_MACOSX) IPC_MESSAGE_HANDLER(ViewHostMsg_ShowPopup, OnMsgShowPopup) #endif @@ -1925,10 +1923,6 @@ void RenderViewHost::OnScriptEvalResponse(int id, const ListValue& result) { Details<std::pair<int, Value*> >(&details)); } -void RenderViewHost::OnUpdateContentRestrictions(int restrictions) { - delegate_->UpdateContentRestrictions(restrictions); -} - #if defined(OS_MACOSX) void RenderViewHost::OnMsgShowPopup( const ViewHostMsg_ShowPopup_Params& params) { diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 4b8619e..1174588 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -684,7 +684,6 @@ class RenderViewHost : public RenderWidgetHost { void OnInstantSupportDetermined(int32 page_id, bool result); void OnDetectedPhishingSite(const GURL& phishing_url, double phishing_score); void OnScriptEvalResponse(int id, const ListValue& result); - void OnUpdateContentRestrictions(int restrictions); void OnPagesReadyForPreview( const ViewHostMsg_DidPreviewDocument_Params& params); diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index 6bd228e..ccd7e01 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -745,9 +745,6 @@ class RenderViewHostDelegate : public IPC::Channel::Listener { int maximum_percent, bool remember) {} - // Update the content restrictions, i.e. disable print/copy. - virtual void UpdateContentRestrictions(int restrictions) {} - protected: virtual ~RenderViewHostDelegate() {} }; diff --git a/chrome/browser/resources/reader_out_of_date.html b/chrome/browser/resources/reader_out_of_date.html new file mode 100644 index 0000000..df20c5b --- /dev/null +++ b/chrome/browser/resources/reader_out_of_date.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<html> +<head> +<title i18n-content="title"></title> +<style type="text/css"> +body { + background-color:#500; + font-family:Helvetica,Arial,sans-serif; + margin:0px; +} +.background { + position:absolute; + width:100%; + height:100%; +} +.cell { + padding:40px; +} +.box { + width:80%; + background-color:white; + color:black; + font-size:10pt; + line-height:16pt; + text-align:left; + padding:20px; + position:relative; + -webkit-box-shadow:3px 3px 8px #200; + border-radius:5px; +} +html[dir='rtl'] .box { + text-align:right; +} + +.icon { + position:absolute; +} +.title { + margin: 0px 77px 0px; + font-size:18pt; + line-height: 140%; + margin-bottom:6pt; + font-weight:bold; + color:#660000; +} +.main { + margin:0px 80px 0px; +} + +.submission { + margin:15px 5px 15px 0px; + padding:0px; +} +input { + margin:0px; +} +.proceedbutton { +} +</style> + +<script> +function sendCommand(cmd) { + window.domAutomationController.setAutomationId(1); + window.domAutomationController.send(cmd); +} + +function getChecked() { + for (var i = 0; i < document.form.group.length; i++) { + if (document.form.group[i].checked) + return parseInt(document.form.group[i].value); + } + return 0; +} +</script> +</head> +<body oncontextmenu="return false;"> +<div class="background"><img src="ssl_roadblock_background.png" width="100%" height="100%" alt="background" onmousedown="return false;"></div> +<table width="100%" cellspacing="0" cellpadding="0"> + <td class="cell" valign="middle" align="center"> + <div class="box"> + <div class="icon"><img src="ssl_roadblock_icon.png" alt="Reader out of date icon" onmousedown="return false;"></div> + <div class="title" i18n-content="headLine"></div> + <div class="main"> + <form name="form" class="submission"> + <input type="radio" name="group" value="1" checked> <span i18n-content="update"></span><br> + <input type="radio" name="group" value="2"> <span i18n-content="open_with_reader"></span><br> + <br> + <input type="button" i18n-values="value:ok" name="ok" class="proceedbutton" onClick="sendCommand(getChecked());"> + <input type="button" i18n-values="value:cancel" name="cancel" onClick="sendCommand(0);"> + </form> + </div> + </td> +</table> +</body> +</html> diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 758a1d0..938c9bf 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -47,6 +47,7 @@ #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/modal_html_dialog_delegate.h" #include "chrome/browser/omnibox_search_hint.h" +#include "chrome/browser/pdf_unsupported_feature.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/plugin_installer_infobar_delegate.h" #include "chrome/browser/prefs/pref_service.h" @@ -615,6 +616,10 @@ bool TabContents::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentLoadedInFrame, OnDocumentLoadedInFrame) IPC_MESSAGE_HANDLER(ViewHostMsg_DidFinishLoad, OnDidFinishLoad) + IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateContentRestrictions, + OnUpdateContentRestrictions) + IPC_MESSAGE_HANDLER(ViewHostMsg_PDFHasUnsupportedFeature, + OnPDFHasUnsupportedFeature) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP_EX() @@ -1778,6 +1783,15 @@ void TabContents::OnDidFinishLoad(int64 frame_id) { Details<int64>(&frame_id)); } +void TabContents::OnUpdateContentRestrictions(int restrictions) { + content_restrictions_ = restrictions; + delegate()->ContentRestrictionsChanged(this); +} + +void TabContents::OnPDFHasUnsupportedFeature() { + PDFHasUnsupportedFeature(this); +} + // Notifies the RenderWidgetHost instance about the fact that the page is // loading, or done loading and calls the base implementation. void TabContents::SetIsLoading(bool is_loading, @@ -3130,11 +3144,6 @@ void TabContents::UpdateZoomLimits(int minimum_percent, temporary_zoom_settings_ = !remember; } -void TabContents::UpdateContentRestrictions(int restrictions) { - content_restrictions_ = restrictions; - delegate()->ContentRestrictionsChanged(this); -} - void TabContents::BeforeUnloadFiredFromRenderManager( bool proceed, bool* proceed_to_fire_unload) { diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 1da5f14..da61f4e 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -808,6 +808,8 @@ class TabContents : public PageNavigator, const GURL& target_url); void OnDocumentLoadedInFrame(int64 frame_id); void OnDidFinishLoad(int64 frame_id); + void OnUpdateContentRestrictions(int restrictions); + void OnPDFHasUnsupportedFeature(); // Changes the IsLoading state and notifies delegate as needed // |details| is used to provide details on the load that just finished @@ -1033,7 +1035,6 @@ class TabContents : public PageNavigator, virtual void UpdateZoomLimits(int minimum_percent, int maximum_percent, bool remember); - virtual void UpdateContentRestrictions(int restrictions); // RenderViewHostManager::Delegate ------------------------------------------- diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index dc048d7..7a1ea50 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1330,6 +1330,8 @@ 'browser/gpu_process_host.h', 'browser/gpu_process_host_ui_shim.cc', 'browser/gpu_process_host_ui_shim.h', + 'browser/pdf_unsupported_feature.cc', + 'browser/pdf_unsupported_feature.h', 'browser/ui/gtk/about_chrome_dialog.cc', 'browser/ui/gtk/about_chrome_dialog.h', 'browser/ui/gtk/accelerators_gtk.cc', diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index e3f8af1..d8f3fb6 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -1393,7 +1393,8 @@ IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_GetPlugins, // |actual_mime_type| is the actual mime type supported by the // plugin found that match the URL given (one for each item in // |info|). -IPC_SYNC_MESSAGE_CONTROL3_4(ViewHostMsg_GetPluginInfo, +IPC_SYNC_MESSAGE_CONTROL4_4(ViewHostMsg_GetPluginInfo, + int /* routing_id */, GURL /* url */, GURL /* policy_url */, std::string /* mime_type */, @@ -1538,7 +1539,8 @@ IPC_MESSAGE_ROUTED3(ViewHostMsg_ForwardMessageToExternalHost, // create a plugin. The browser will create the plugin process if // necessary, and will return a handle to the channel on success. // On error an empty string is returned. -IPC_SYNC_MESSAGE_CONTROL2_2(ViewHostMsg_OpenChannelToPlugin, +IPC_SYNC_MESSAGE_CONTROL3_2(ViewHostMsg_OpenChannelToPlugin, + int /* routing_id */, GURL /* url */, std::string /* mime_type */, IPC::ChannelHandle /* channel_handle */, @@ -2587,6 +2589,9 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_ScriptEvalResponse, IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateContentRestrictions, int /* restrictions */) +// The currently displayed PDF has an unsupported feature. +IPC_MESSAGE_ROUTED0(ViewHostMsg_PDFHasUnsupportedFeature) + // Pepper-related messages ----------------------------------------------------- IPC_MESSAGE_CONTROL4(ViewHostMsg_PepperConnectTcp, diff --git a/chrome/renderer/pepper_plugin_delegate_impl.cc b/chrome/renderer/pepper_plugin_delegate_impl.cc index f4c2923..87b9914 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.cc +++ b/chrome/renderer/pepper_plugin_delegate_impl.cc @@ -891,3 +891,8 @@ void PepperPluginDelegateImpl::SetContentRestriction(int restrictions) { render_view_->Send(new ViewHostMsg_UpdateContentRestrictions( render_view_->routing_id(), restrictions)); } + +void PepperPluginDelegateImpl::HasUnsupportedFeature() { + render_view_->Send(new ViewHostMsg_PDFHasUnsupportedFeature( + render_view_->routing_id())); +} diff --git a/chrome/renderer/pepper_plugin_delegate_impl.h b/chrome/renderer/pepper_plugin_delegate_impl.h index b4d7424..408163a 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.h +++ b/chrome/renderer/pepper_plugin_delegate_impl.h @@ -163,6 +163,7 @@ class PepperPluginDelegateImpl virtual void DidStartLoading(); virtual void DidStopLoading(); virtual void SetContentRestriction(int restrictions); + virtual void HasUnsupportedFeature(); private: // Pointer to the RenderView that owns us. diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index ff9a209..d8adaaa 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -918,8 +918,8 @@ WebPlugin* RenderView::CreatePluginNoCheck(WebFrame* frame, ContentSetting setting; std::string mime_type; Send(new ViewHostMsg_GetPluginInfo( - params.url, frame->top()->url(), params.mimeType.utf8(), &found, - &info, &setting, &mime_type)); + routing_id_, params.url, frame->top()->url(), params.mimeType.utf8(), + &found, &info, &setting, &mime_type)); if (!found || !info.enabled) return NULL; @@ -2687,7 +2687,8 @@ WebPlugin* RenderView::createPlugin(WebFrame* frame, webkit::npapi::WebPluginInfo info; GURL url(params.url); std::string actual_mime_type; - Send(new ViewHostMsg_GetPluginInfo(url, + Send(new ViewHostMsg_GetPluginInfo(routing_id_, + url, frame->top()->url(), params.mimeType.utf8(), &found, diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc index e5c50ec..6e7b4fd 100644 --- a/chrome/renderer/webplugin_delegate_proxy.cc +++ b/chrome/renderer/webplugin_delegate_proxy.cc @@ -274,7 +274,8 @@ bool WebPluginDelegateProxy::Initialize( bool load_manually) { IPC::ChannelHandle channel_handle; if (!RenderThread::current()->Send(new ViewHostMsg_OpenChannelToPlugin( - url, mime_type_, &channel_handle, &info_))) { + render_view_->routing_id(), url, mime_type_, &channel_handle, + &info_))) { return false; } diff --git a/chrome/tools/chromeactions.txt b/chrome/tools/chromeactions.txt index 675a4e2..e1d450f 100644 --- a/chrome/tools/chromeactions.txt +++ b/chrome/tools/chromeactions.txt @@ -947,6 +947,17 @@ 0x99ed44568e5ff51a PDF.ZoomFromBrowser 0x1d57434947820665 PDF.ZoomInButton 0x40ca10ced9d81d17 PDF.ZoomOutButton +0x0b951f22f9dff291 PDF_Unsupported_3D +0xd39cd7449ac8702e PDF_Unsupported_Attachments +0x922a34409936d3c6 PDF_Unsupported_Digital_Signatures +0xc09901d647ad722f PDF_Unsupported_Movie +0x282157da06d467b9 PDF_Unsupported_Portfolios +0x74d8faa1b4e92791 PDF_Unsupported_Rights_Management +0x571f65a8518214ae PDF_Unsupported_Screen +0xdf8b4231d4bd3f90 PDF_Unsupported_Shared_Form +0xb7474a7496f9a77e PDF_Unsupported_Shared_Review +0x6efe497913838ea5 PDF_Unsupported_Sound +0x08640e2d5578cf94 PDF_Unsupported_XFA 0xee3677bcca83ece9 PageDown 0x9b869c510c75c582 PageUp 0x9ba3ff80fde405cd PasswordManager_Disabled diff --git a/chrome/tools/extract_actions.py b/chrome/tools/extract_actions.py index e28c85b..b111182 100755 --- a/chrome/tools/extract_actions.py +++ b/chrome/tools/extract_actions.py @@ -162,6 +162,17 @@ def AddClosedSourceActions(actions): actions.add('PDF.ZoomFromBrowser') actions.add('PDF.ZoomOutButton') actions.add('PDF.ZoomInButton') + actions.add('PDF_Unsupported_Rights_Management') + actions.add('PDF_Unsupported_XFA') + actions.add('PDF_Unsupported_3D') + actions.add('PDF_Unsupported_Movie') + actions.add('PDF_Unsupported_Sound') + actions.add('PDF_Unsupported_Screen') + actions.add('PDF_Unsupported_Portfolios') + actions.add('PDF_Unsupported_Attachments') + actions.add('PDF_Unsupported_Digital_Signatures') + actions.add('PDF_Unsupported_Shared_Review') + actions.add('PDF_Unsupported_Shared_Form') def AddAboutFlagsActions(actions): """This parses the experimental feature flags for UMA actions. |