summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_process_impl.cc5
-rw-r--r--chrome/browser/browsing_data_remover.cc2
-rw-r--r--chrome/browser/chrome_plugin_service_filter.cc139
-rw-r--r--chrome/browser/chrome_plugin_service_filter.h87
-rw-r--r--chrome/browser/extensions/extension_service.cc9
-rw-r--r--chrome/browser/pdf_unsupported_feature.cc22
-rw-r--r--chrome/browser/plugin_data_remover.cc10
-rw-r--r--chrome/browser/plugin_data_remover.h6
-rw-r--r--chrome/browser/plugin_data_remover_browsertest.cc3
-rw-r--r--chrome/browser/plugin_data_remover_helper.cc5
-rw-r--r--chrome/browser/plugin_prefs.cc2
-rw-r--r--chrome/browser/printing/print_preview_tab_controller.cc16
-rw-r--r--chrome/browser/profiles/off_the_record_profile_impl.cc8
-rw-r--r--chrome/browser/profiles/profile_impl.cc8
-rw-r--r--chrome/browser/ui/webui/plugins_ui.cc5
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/common/chrome_notification_types.h4
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc2
-rw-r--r--content/browser/plugin_process_host.h8
-rw-r--r--content/browser/plugin_service.cc195
-rw-r--r--content/browser/plugin_service.h48
-rw-r--r--content/browser/plugin_service_browsertest.cc21
-rw-r--r--content/browser/plugin_service_filter.h37
-rw-r--r--content/browser/renderer_host/buffered_resource_handler.cc18
-rw-r--r--content/browser/renderer_host/render_message_filter.cc48
-rw-r--r--content/browser/renderer_host/render_message_filter.h2
-rw-r--r--content/common/content_notification_types.h4
-rw-r--r--content/common/view_messages.h9
-rw-r--r--content/content_browser.gypi1
-rw-r--r--content/renderer/render_view.cc2
-rw-r--r--content/renderer/render_view.h8
-rw-r--r--content/renderer/webplugin_delegate_proxy.cc4
-rw-r--r--webkit/plugins/npapi/plugin_list.cc28
33 files changed, 525 insertions, 243 deletions
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index c46580a..57fc0c4 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/browser_main.h"
#include "chrome/browser/browser_process_sub_thread.h"
#include "chrome/browser/browser_trial.h"
+#include "chrome/browser/chrome_plugin_service_filter.h"
#include "chrome/browser/component_updater/component_updater_configurator.h"
#include "chrome/browser/component_updater/component_updater_service.h"
#include "chrome/browser/debugger/devtools_protocol_handler.h"
@@ -739,7 +740,9 @@ void BrowserProcessImpl::CreateIOThread() {
// it is predominantly used from the io thread, but must be created
// on the main thread. The service ctor is inexpensive and does not
// invoke the io_thread() accessor.
- PluginService::GetInstance();
+ PluginService* plugin_service = PluginService::GetInstance();
+ plugin_service->set_filter(ChromePluginServiceFilter::GetInstance());
+ plugin_service->StartWatchingPlugins();
// Add the Chrome specific plugins.
chrome::RegisterInternalDefaultPlugin();
diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc
index bd05876..6f8a387 100644
--- a/chrome/browser/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data_remover.cc
@@ -276,7 +276,7 @@ void BrowsingDataRemover::Remove(int remove_mask) {
waiting_for_clear_lso_data_ = true;
if (!plugin_data_remover_.get())
- plugin_data_remover_ = new PluginDataRemover();
+ plugin_data_remover_ = new PluginDataRemover(profile_);
base::WaitableEvent* event =
plugin_data_remover_->StartRemoving(delete_begin_);
watcher_.StartWatching(event, this);
diff --git a/chrome/browser/chrome_plugin_service_filter.cc b/chrome/browser/chrome_plugin_service_filter.cc
new file mode 100644
index 0000000..23e11c8
--- /dev/null
+++ b/chrome/browser/chrome_plugin_service_filter.cc
@@ -0,0 +1,139 @@
+// 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/chrome_plugin_service_filter.h"
+
+#include "base/logging.h"
+#include "chrome/browser/plugin_prefs.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "content/browser/browser_thread.h"
+#include "content/browser/plugin_service.h"
+#include "content/browser/renderer_host/render_process_host.h"
+#include "content/browser/resource_context.h"
+#include "content/common/notification_service.h"
+#include "webkit/plugins/npapi/plugin_list.h"
+
+// static
+ChromePluginServiceFilter* ChromePluginServiceFilter::GetInstance() {
+ return Singleton<ChromePluginServiceFilter>::get();
+}
+
+void ChromePluginServiceFilter::RegisterResourceContext(
+ PluginPrefs* plugin_prefs,
+ const void* context) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ base::AutoLock lock(lock_);
+ resource_context_map_[context] = plugin_prefs;
+}
+
+void ChromePluginServiceFilter::UnregisterResourceContext(
+ const void* context) {
+ base::AutoLock lock(lock_);
+ resource_context_map_.erase(context);
+}
+
+void ChromePluginServiceFilter::OverridePluginForTab(
+ int render_process_id,
+ int render_view_id,
+ const GURL& url,
+ const webkit::WebPluginInfo& plugin) {
+ OverriddenPlugin overridden_plugin;
+ overridden_plugin.render_process_id = render_process_id;
+ overridden_plugin.render_view_id = render_view_id;
+ overridden_plugin.url = url;
+ overridden_plugin.plugin = plugin;
+ base::AutoLock auto_lock(lock_);
+ overridden_plugins_.push_back(overridden_plugin);
+}
+
+void ChromePluginServiceFilter::RestrictPluginToUrl(const FilePath& plugin_path,
+ const GURL& url) {
+ base::AutoLock auto_lock(lock_);
+ if (url.is_empty())
+ restricted_plugins_.erase(plugin_path);
+ else
+ restricted_plugins_[plugin_path] = url;
+}
+
+bool ChromePluginServiceFilter::ShouldUsePlugin(
+ int render_process_id,
+ int render_view_id,
+ const void* context,
+ const GURL& url,
+ const GURL& policy_url,
+ webkit::WebPluginInfo* plugin) {
+ base::AutoLock auto_lock(lock_);
+ // Check whether the plugin is overridden.
+ 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 ||
+ overridden_plugins_[i].url.is_empty())) {
+ if (overridden_plugins_[i].plugin.path != plugin->path)
+ return false;
+ *plugin = overridden_plugins_[i].plugin;
+ return true;
+ }
+ }
+
+ // Check whether the plugin is disabled.
+ ResourceContextMap::iterator prefs_it =
+ resource_context_map_.find(context);
+ if (prefs_it == resource_context_map_.end())
+ return false;
+
+ PluginPrefs* plugin_prefs = prefs_it->second.get();
+ if (!plugin_prefs->IsPluginEnabled(*plugin))
+ return false;
+
+ // Check whether the plugin is restricted to a URL.
+ RestrictedPluginMap::const_iterator it =
+ restricted_plugins_.find(plugin->path);
+ if (it != restricted_plugins_.end() &&
+ (policy_url.scheme() != it->second.scheme() ||
+ policy_url.host() != it->second.host())) {
+ return false;
+ }
+
+ return true;
+}
+
+ChromePluginServiceFilter::ChromePluginServiceFilter() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
+ NotificationService::AllSources());
+ registrar_.Add(this, chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
+ NotificationService::AllSources());
+}
+
+ChromePluginServiceFilter::~ChromePluginServiceFilter() {
+}
+
+void ChromePluginServiceFilter::Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ switch (type) {
+ case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
+ int render_process_id = Source<RenderProcessHost>(source).ptr()->id();
+
+ base::AutoLock auto_lock(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;
+ }
+ case chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED: {
+ PluginService::GetInstance()->PurgePluginListCache(false);
+ break;
+ }
+ default: {
+ NOTREACHED();
+ }
+ }
+}
diff --git a/chrome/browser/chrome_plugin_service_filter.h b/chrome/browser/chrome_plugin_service_filter.h
new file mode 100644
index 0000000..81bbfa1
--- /dev/null
+++ b/chrome/browser/chrome_plugin_service_filter.h
@@ -0,0 +1,87 @@
+// 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_CHROME_PLUGIN_SERVICE_FILTER_H_
+#define CHROME_BROWSER_CHROME_PLUGIN_SERVICE_FILTER_H_
+#pragma once
+
+#include <map>
+#include <vector>
+
+#include "base/hash_tables.h"
+#include "base/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/singleton.h"
+#include "base/synchronization/lock.h"
+#include "content/browser/plugin_service_filter.h"
+#include "content/common/notification_observer.h"
+#include "content/common/notification_registrar.h"
+#include "googleurl/src/gurl.h"
+#include "webkit/plugins/webplugininfo.h"
+
+class PluginPrefs;
+
+// This class must be created (by calling the |GetInstance| method) on the UI
+// thread, but is safe to use on any thread after that.
+class ChromePluginServiceFilter : public content::PluginServiceFilter,
+ public NotificationObserver {
+ public:
+ static ChromePluginServiceFilter* GetInstance();
+
+ // This method should be called on the UI thread.
+ void RegisterResourceContext(PluginPrefs* plugin_prefs, const void* context);
+
+ void UnregisterResourceContext(const void* context);
+
+ // Overrides the plugin lookup mechanism for a given tab and object URL to use
+ // a specifc plugin.
+ void OverridePluginForTab(int render_process_id,
+ int render_view_id,
+ const GURL& url,
+ const webkit::WebPluginInfo& plugin);
+
+ // Restricts the given plugin to the the scheme and host of the given url.
+ // Call with an empty url to reset this.
+ void RestrictPluginToUrl(const FilePath& plugin_path, const GURL& url);
+
+ // PluginServiceFilter implementation:
+ virtual bool ShouldUsePlugin(
+ int render_process_id,
+ int render_view_id,
+ const void* context,
+ const GURL& url,
+ const GURL& policy_url,
+ webkit::WebPluginInfo* plugin) OVERRIDE;
+
+ private:
+ friend struct DefaultSingletonTraits<ChromePluginServiceFilter>;
+
+ struct OverriddenPlugin {
+ int render_process_id;
+ int render_view_id;
+ GURL url; // If empty, the override applies to all urls in render_view.
+ webkit::WebPluginInfo plugin;
+ };
+
+ ChromePluginServiceFilter();
+ virtual ~ChromePluginServiceFilter();
+
+ // NotificationObserver implementation:
+ virtual void Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ NotificationRegistrar registrar_;
+
+ base::Lock lock_; // Guards access to member variables.
+ // Map of plugin paths to the origin they are restricted to.
+ typedef base::hash_map<FilePath, GURL> RestrictedPluginMap;
+ RestrictedPluginMap restricted_plugins_;
+ typedef std::map<const void*, scoped_refptr<PluginPrefs> > ResourceContextMap;
+ ResourceContextMap resource_context_map_;
+
+ std::vector<OverriddenPlugin> overridden_plugins_;
+};
+
+#endif // CHROME_BROWSER_CHROME_PLUGIN_SERVICE_FILTER_H_
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index e9143d0..dc4d403 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -24,6 +24,7 @@
#include "base/values.h"
#include "base/version.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_plugin_service_filter.h"
#include "chrome/browser/extensions/apps_promo.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_accessibility_api.h"
@@ -1502,7 +1503,7 @@ void ExtensionService::NotifyExtensionLoaded(const Extension* extension) {
webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(plugin.path);
plugins_changed = true;
if (!plugin.is_public) {
- PluginService::GetInstance()->RestrictPluginToUrl(
+ ChromePluginServiceFilter::GetInstance()->RestrictPluginToUrl(
plugin.path, extension->url());
}
}
@@ -1597,8 +1598,10 @@ void ExtensionService::NotifyExtensionUnloaded(
webkit::npapi::PluginList::Singleton()->RemoveExtraPluginPath(
plugin.path);
plugins_changed = true;
- if (!plugin.is_public)
- PluginService::GetInstance()->RestrictPluginToUrl(plugin.path, GURL());
+ if (!plugin.is_public) {
+ ChromePluginServiceFilter::GetInstance()->RestrictPluginToUrl(
+ plugin.path, GURL());
+ }
}
bool nacl_modules_changed = false;
diff --git a/chrome/browser/pdf_unsupported_feature.cc b/chrome/browser/pdf_unsupported_feature.cc
index 3f5f6d0..1a91a39 100644
--- a/chrome/browser/pdf_unsupported_feature.cc
+++ b/chrome/browser/pdf_unsupported_feature.cc
@@ -9,6 +9,7 @@
#include "base/version.h"
#include "chrome/browser/infobars/infobar_tab_helper.h"
#include "chrome/browser/plugin_prefs.h"
+#include "chrome/browser/chrome_plugin_service_filter.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/chrome_interstitial_page.h"
@@ -140,19 +141,19 @@ void OpenUsingReader(TabContentsWrapper* tab,
const WebPluginInfo& reader_plugin,
InfoBarDelegate* old_delegate,
InfoBarDelegate* new_delegate) {
- PluginService::OverriddenPlugin plugin;
- plugin.render_process_id = tab->render_view_host()->process()->id();
- plugin.render_view_id = tab->render_view_host()->routing_id();
- plugin.url = tab->tab_contents()->GetURL();
- plugin.plugin = reader_plugin;
+ WebPluginInfo plugin = reader_plugin;
// The plugin is disabled, so enable it to get around the renderer check.
// Also give it a new version so that the renderer doesn't show the blocked
// plugin UI if it's vulnerable, since we already went through the
// interstitial.
- plugin.plugin.enabled = WebPluginInfo::USER_ENABLED;
- plugin.plugin.version = ASCIIToUTF16("11.0.0.0");
-
- PluginService::GetInstance()->OverridePluginForTab(plugin);
+ plugin.enabled = WebPluginInfo::USER_ENABLED;
+ plugin.version = ASCIIToUTF16("11.0.0.0");
+
+ ChromePluginServiceFilter::GetInstance()->OverridePluginForTab(
+ tab->render_view_host()->process()->id(),
+ tab->render_view_host()->routing_id(),
+ tab->tab_contents()->GetURL(),
+ plugin);
tab->render_view_host()->Send(new ViewMsg_ReloadFrame(
tab->render_view_host()->routing_id()));
@@ -386,8 +387,7 @@ void PDFHasUnsupportedFeature(TabContentsWrapper* tab) {
PluginGroup* reader_group = NULL;
std::vector<PluginGroup> plugin_groups;
- PluginList::Singleton()->GetPluginGroups(
- false, &plugin_groups);
+ PluginList::Singleton()->GetPluginGroups(false, &plugin_groups);
for (size_t i = 0; i < plugin_groups.size(); ++i) {
if (plugin_groups[i].GetGroupName() == reader_group_name) {
reader_group = &plugin_groups[i];
diff --git a/chrome/browser/plugin_data_remover.cc b/chrome/browser/plugin_data_remover.cc
index b547b60..5b06586 100644
--- a/chrome/browser/plugin_data_remover.cc
+++ b/chrome/browser/plugin_data_remover.cc
@@ -10,6 +10,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/version.h"
#include "chrome/browser/plugin_prefs.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "content/browser/browser_thread.h"
#include "content/browser/plugin_service.h"
@@ -31,9 +32,10 @@ const uint64 kClearAllData = 0;
} // namespace
-PluginDataRemover::PluginDataRemover()
+PluginDataRemover::PluginDataRemover(Profile* profile)
: mime_type_(kFlashMimeType),
is_removing_(false),
+ context_(profile->GetResourceContext()),
event_(new base::WaitableEvent(true, false)),
channel_(NULL) {
}
@@ -55,7 +57,7 @@ base::WaitableEvent* PluginDataRemover::StartRemoving(base::Time begin_time) {
// called, so we need to keep this object around until then.
AddRef();
PluginService::GetInstance()->OpenChannelToNpapiPlugin(
- 0, 0, GURL(), mime_type_, this);
+ 0, 0, GURL(), GURL(), mime_type_, this);
BrowserThread::PostDelayedTask(
BrowserThread::IO,
@@ -87,6 +89,10 @@ bool PluginDataRemover::OffTheRecord() {
return false;
}
+const content::ResourceContext& PluginDataRemover::GetResourceContext() {
+ return context_;
+}
+
void PluginDataRemover::SetPluginInfo(
const webkit::WebPluginInfo& info) {
}
diff --git a/chrome/browser/plugin_data_remover.h b/chrome/browser/plugin_data_remover.h
index 9cad19b..9ff4235 100644
--- a/chrome/browser/plugin_data_remover.h
+++ b/chrome/browser/plugin_data_remover.h
@@ -11,6 +11,7 @@
#include "content/browser/plugin_process_host.h"
class PluginPrefs;
+class Profile;
class Task;
namespace base {
@@ -22,7 +23,7 @@ class PluginDataRemover : public base::RefCountedThreadSafe<PluginDataRemover>,
public PluginProcessHost::Client,
public IPC::Channel::Listener {
public:
- PluginDataRemover();
+ explicit PluginDataRemover(Profile* profile);
// The plug-in whose data should be removed (usually Flash) is specified via
// its MIME type. This method sets a different MIME type in order to call a
@@ -48,6 +49,7 @@ class PluginDataRemover : public base::RefCountedThreadSafe<PluginDataRemover>,
// PluginProcessHost::Client methods.
virtual int ID();
virtual bool OffTheRecord();
+ virtual const content::ResourceContext& GetResourceContext();
virtual void SetPluginInfo(const webkit::WebPluginInfo& info);
virtual void OnChannelOpened(const IPC::ChannelHandle& handle);
virtual void OnError();
@@ -78,6 +80,8 @@ class PluginDataRemover : public base::RefCountedThreadSafe<PluginDataRemover>,
base::Time remove_start_time_;
// The point in time from which on we remove data.
base::Time begin_time_;
+ // The resource context for the profile.
+ const content::ResourceContext& context_;
scoped_ptr<base::WaitableEvent> event_;
// We own the channel, but it's used on the IO thread, so it needs to be
// deleted there. It's NULL until we have opened a connection to the plug-in
diff --git a/chrome/browser/plugin_data_remover_browsertest.cc b/chrome/browser/plugin_data_remover_browsertest.cc
index aa85045..5e4a7b2 100644
--- a/chrome/browser/plugin_data_remover_browsertest.cc
+++ b/chrome/browser/plugin_data_remover_browsertest.cc
@@ -41,7 +41,8 @@ class PluginDataRemoverTest : public InProcessBrowserTest,
};
IN_PROC_BROWSER_TEST_F(PluginDataRemoverTest, RemoveData) {
- scoped_refptr<PluginDataRemover> plugin_data_remover(new PluginDataRemover());
+ scoped_refptr<PluginDataRemover> plugin_data_remover(
+ new PluginDataRemover(browser()->profile()));
plugin_data_remover->set_mime_type(kNPAPITestPluginMimeType);
base::WaitableEventWatcher watcher;
base::WaitableEvent* event =
diff --git a/chrome/browser/plugin_data_remover_helper.cc b/chrome/browser/plugin_data_remover_helper.cc
index 9d4e176..df0c907 100644
--- a/chrome/browser/plugin_data_remover_helper.cc
+++ b/chrome/browser/plugin_data_remover_helper.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/plugin_prefs.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_notification_types.h"
#include "content/browser/browser_thread.h"
#include "content/common/notification_service.h"
@@ -76,7 +77,7 @@ void PluginDataRemoverHelper::Init(const char* pref_name,
Profile* profile,
NotificationObserver* observer) {
pref_.Init(pref_name, profile->GetPrefs(), observer);
- registrar_.Add(this, content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
+ registrar_.Add(this, chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
NotificationService::AllSources());
internal_ = make_scoped_refptr(new Internal(pref_name, profile));
internal_->StartUpdate();
@@ -85,7 +86,7 @@ void PluginDataRemoverHelper::Init(const char* pref_name,
void PluginDataRemoverHelper::Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) {
- if (type == content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED) {
+ if (type == chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED) {
internal_->StartUpdate();
} else {
NOTREACHED();
diff --git a/chrome/browser/plugin_prefs.cc b/chrome/browser/plugin_prefs.cc
index 9af4c67..7b2ce4d 100644
--- a/chrome/browser/plugin_prefs.cc
+++ b/chrome/browser/plugin_prefs.cc
@@ -440,7 +440,7 @@ void PluginPrefs::NotifyPluginStatusChanged() {
void PluginPrefs::OnNotifyPluginStatusChanged() {
notify_pending_ = false;
NotificationService::current()->Notify(
- content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
+ chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
Source<PluginPrefs>(this),
NotificationService::NoDetails());
}
diff --git a/chrome/browser/printing/print_preview_tab_controller.cc b/chrome/browser/printing/print_preview_tab_controller.cc
index 6f5078c..cdcb02c 100644
--- a/chrome/browser/printing/print_preview_tab_controller.cc
+++ b/chrome/browser/printing/print_preview_tab_controller.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_plugin_service_filter.h"
#include "chrome/browser/printing/print_view_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/restore_tab_helper.h"
@@ -21,7 +22,6 @@
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
-#include "content/browser/plugin_service.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/navigation_details.h"
#include "content/browser/tab_contents/tab_contents.h"
@@ -55,13 +55,13 @@ void EnableInternalPDFPluginForTab(TabContentsWrapper* preview_tab) {
std::vector<WebPluginInfo> plugins = internal_pdf_group->web_plugin_infos();
DCHECK_EQ(plugins.size(), 1U);
- PluginService::OverriddenPlugin plugin;
- plugin.render_process_id = preview_tab->render_view_host()->process()->id();
- plugin.render_view_id = preview_tab->render_view_host()->routing_id();
- plugin.plugin = plugins[0];
- plugin.plugin.enabled = WebPluginInfo::USER_ENABLED;
-
- PluginService::GetInstance()->OverridePluginForTab(plugin);
+ webkit::WebPluginInfo plugin = plugins[0];
+ plugin.enabled = WebPluginInfo::USER_ENABLED;
+ ChromePluginServiceFilter::GetInstance()->OverridePluginForTab(
+ preview_tab->render_view_host()->process()->id(),
+ preview_tab->render_view_host()->routing_id(),
+ GURL(),
+ plugin);
}
}
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 964bc8b..ed0a2f4 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -16,6 +16,7 @@
#include "build/build_config.h"
#include "chrome/browser/background/background_contents_service_factory.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_plugin_service_filter.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/extensions/extension_info_map.h"
@@ -26,6 +27,7 @@
#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/extensions/extension_webrequest_api.h"
#include "chrome/browser/net/pref_proxy_config_service.h"
+#include "chrome/browser/plugin_prefs.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/off_the_record_profile_io_data.h"
@@ -117,6 +119,9 @@ class OffTheRecordProfileImpl : public Profile,
ExtensionIconSource* icon_source = new ExtensionIconSource(real_profile);
GetChromeURLDataManager()->AddDataSource(icon_source);
+ ChromePluginServiceFilter::GetInstance()->RegisterResourceContext(
+ PluginPrefs::GetForProfile(this), &GetResourceContext());
+
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
NewRunnableFunction(&NotifyOTRProfileCreatedOnIOThread, profile_, this));
@@ -127,6 +132,9 @@ class OffTheRecordProfileImpl : public Profile,
chrome::NOTIFICATION_PROFILE_DESTROYED, Source<Profile>(this),
NotificationService::NoDetails());
+ ChromePluginServiceFilter::GetInstance()->UnregisterResourceContext(
+ &GetResourceContext());
+
ProfileDependencyManager::GetInstance()->DestroyProfileServices(this);
BrowserThread::PostTask(
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 1ddbd12..db3a11c 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browsing_data_remover.h"
+#include "chrome/browser/chrome_plugin_service_filter.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "chrome/browser/defaults.h"
@@ -49,6 +50,7 @@
#include "chrome/browser/net/pref_proxy_config_service.h"
#include "chrome/browser/net/ssl_config_service_manager.h"
#include "chrome/browser/password_manager/password_store_default.h"
+#include "chrome/browser/plugin_prefs.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/pref_value_store.h"
@@ -438,6 +440,9 @@ void ProfileImpl::DoFinalInit() {
cache_max_size, media_cache_path, media_cache_max_size,
extensions_cookie_path, app_path);
+ ChromePluginServiceFilter::GetInstance()->RegisterResourceContext(
+ PluginPrefs::GetForProfile(this), &GetResourceContext());
+
// Creation has been finished.
if (delegate_)
delegate_->OnProfileCreated(this, true);
@@ -687,6 +692,9 @@ ProfileImpl::~ProfileImpl() {
// of the cleanup below.
sync_service_.reset();
+ ChromePluginServiceFilter::GetInstance()->UnregisterResourceContext(
+ &GetResourceContext());
+
ProfileDependencyManager::GetInstance()->DestroyProfileServices(this);
if (db_tracker_) {
diff --git a/chrome/browser/ui/webui/plugins_ui.cc b/chrome/browser/ui/webui/plugins_ui.cc
index 78a3c18..f2fc958 100644
--- a/chrome/browser/ui/webui/plugins_ui.cc
+++ b/chrome/browser/ui/webui/plugins_ui.cc
@@ -22,6 +22,7 @@
#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
#include "chrome/browser/ui/webui/chrome_web_ui_data_source.h"
#include "chrome/common/chrome_content_client.h"
+#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
@@ -150,7 +151,7 @@ class PluginsDOMHandler : public WebUIMessageHandler,
PluginsDOMHandler::PluginsDOMHandler()
: ALLOW_THIS_IN_INITIALIZER_LIST(get_plugins_factory_(this)) {
registrar_.Add(this,
- content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
+ chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
NotificationService::AllSources());
}
@@ -248,7 +249,7 @@ void PluginsDOMHandler::HandleGetShowDetails(const ListValue* args) {
void PluginsDOMHandler::Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) {
- DCHECK_EQ(content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, type);
+ DCHECK_EQ(chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, type);
LoadPlugins();
}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index c221df0..b29075b 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -341,6 +341,8 @@
'browser/chrome_content_browser_client.h',
'browser/chrome_plugin_message_filter.cc',
'browser/chrome_plugin_message_filter.h',
+ 'browser/chrome_plugin_service_filter.cc',
+ 'browser/chrome_plugin_service_filter.h',
'browser/chrome_quota_permission_context.cc',
'browser/chrome_quota_permission_context.h',
'browser/chrome_worker_message_filter.cc',
diff --git a/chrome/common/chrome_notification_types.h b/chrome/common/chrome_notification_types.h
index b213792..f1101cc 100644
--- a/chrome/common/chrome_notification_types.h
+++ b/chrome/common/chrome_notification_types.h
@@ -887,6 +887,10 @@ enum NotificationType {
// Sent when the browser enters or exits fullscreen mode.
NOTIFICATION_FULLSCREEN_CHANGED,
+ // Sent by the PluginPrefs when there is a change of plugin
+ // enable/disable status.
+ NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
+
// Note:-
// Currently only Content and Chrome define and use notifications.
// Custom notifications not belonging to Content and Chrome should start
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 858d5ad..7becf4a 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -298,8 +298,6 @@ WebPlugin* ChromeContentRendererClient::CreatePluginImpl(
if (!found)
return NULL;
- if (!webkit::IsPluginEnabled(info))
- return NULL;
*is_default_plugin =
info.path.value() == webkit::npapi::kDefaultPluginLibraryName;
diff --git a/content/browser/plugin_process_host.h b/content/browser/plugin_process_host.h
index 7fdba4d..3c5f116 100644
--- a/content/browser/plugin_process_host.h
+++ b/content/browser/plugin_process_host.h
@@ -19,6 +19,10 @@
#include "webkit/plugins/webplugininfo.h"
#include "ui/gfx/native_widget_types.h"
+namespace content {
+class ResourceContext;
+}
+
namespace gfx {
class Rect;
}
@@ -41,9 +45,11 @@ class PluginProcessHost : public BrowserChildProcessHost {
public:
class Client {
public:
- // Returns a opaque unique identifier for the process requesting
+ // Returns an opaque unique identifier for the process requesting
// the channel.
virtual int ID() = 0;
+ // Returns the resource context for the renderer requesting the channel.
+ virtual const content::ResourceContext& GetResourceContext() = 0;
virtual bool OffTheRecord() = 0;
virtual void SetPluginInfo(const webkit::WebPluginInfo& info) = 0;
// The client should delete itself when one of these methods is called.
diff --git a/content/browser/plugin_service.cc b/content/browser/plugin_service.cc
index 7ca5b22..86670db 100644
--- a/content/browser/plugin_service.cc
+++ b/content/browser/plugin_service.cc
@@ -6,6 +6,7 @@
#include "base/command_line.h"
#include "base/compiler_specific.h"
+#include "base/file_path.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/synchronization/waitable_event.h"
@@ -14,6 +15,7 @@
#include "base/values.h"
#include "content/browser/browser_thread.h"
#include "content/browser/content_browser_client.h"
+#include "content/browser/plugin_service_filter.h"
#include "content/browser/ppapi_plugin_process_host.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
@@ -32,6 +34,8 @@
using ::base::files::FilePathWatcher;
#endif
+using content::PluginServiceFilter;
+
#if defined(OS_MACOSX)
static void NotifyPluginsOfActivation() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -65,7 +69,8 @@ PluginService* PluginService::GetInstance() {
PluginService::PluginService()
: ui_locale_(
- content::GetContentClient()->browser()->GetApplicationLocale()) {
+ content::GetContentClient()->browser()->GetApplicationLocale()),
+ filter_(NULL) {
RegisterPepperPlugins();
// Load any specified on the command line as well.
@@ -77,6 +82,27 @@ PluginService::PluginService()
if (!path.empty())
webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(path);
+#if defined(OS_MACOSX)
+ // We need to know when the browser comes forward so we can bring modal plugin
+ // windows forward too.
+ registrar_.Add(this, content::NOTIFICATION_APP_ACTIVATED,
+ NotificationService::AllSources());
+#endif
+}
+
+PluginService::~PluginService() {
+#if defined(OS_WIN)
+ // Release the events since they're owned by RegKey, not WaitableEvent.
+ hkcu_watcher_.StopWatching();
+ hklm_watcher_.StopWatching();
+ if (hkcu_event_.get())
+ hkcu_event_->Release();
+ if (hklm_event_.get())
+ hklm_event_->Release();
+#endif
+}
+
+void PluginService::StartWatchingPlugins() {
// Start watching for changes in the plugin list. This means watching
// for changes in the Windows registry keys and on both Windows and POSIX
// watch for changes in the paths that are expected to contain plugins.
@@ -97,12 +123,7 @@ PluginService::PluginService()
hklm_watcher_.StartWatching(hklm_event_.get(), this);
}
}
-#elif defined(OS_MACOSX)
- // We need to know when the browser comes forward so we can bring modal plugin
- // windows forward too.
- registrar_.Add(this, content::NOTIFICATION_APP_ACTIVATED,
- NotificationService::AllSources());
-#elif defined(OS_POSIX)
+#elif defined(OS_POSIX) && !defined(OS_MACOSX)
// The FilePathWatcher produces too many false positives on MacOS (access time
// updates?) which will lead to enforcing updates of the plugins way too often.
// On ChromeOS the user can't install plugins anyway and on Windows all
@@ -132,23 +153,6 @@ PluginService::PluginService()
file_watchers_.push_back(watcher);
}
#endif
- registrar_.Add(this, content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
- NotificationService::AllSources());
- registrar_.Add(this,
- content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
- NotificationService::AllSources());
-}
-
-PluginService::~PluginService() {
-#if defined(OS_WIN)
- // Release the events since they're owned by RegKey, not WaitableEvent.
- hkcu_watcher_.StopWatching();
- hklm_watcher_.StopWatching();
- if (hkcu_event_.get())
- hkcu_event_->Release();
- if (hklm_event_.get())
- hklm_event_->Release();
-#endif
}
const std::string& PluginService::GetUILocale() {
@@ -278,6 +282,7 @@ void PluginService::OpenChannelToNpapiPlugin(
int render_process_id,
int render_view_id,
const GURL& url,
+ const GURL& page_url,
const std::string& mime_type,
PluginProcessHost::Client* client) {
// The PluginList::GetPluginInfo may need to load the plugins. Don't do it on
@@ -286,7 +291,8 @@ void PluginService::OpenChannelToNpapiPlugin(
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
this, &PluginService::GetAllowedPluginForOpenChannelToPlugin,
- render_process_id, render_view_id, url, mime_type, client));
+ render_process_id, render_view_id, url, page_url, mime_type,
+ client));
}
void PluginService::OpenChannelToPpapiPlugin(
@@ -314,15 +320,19 @@ void PluginService::GetAllowedPluginForOpenChannelToPlugin(
int render_process_id,
int render_view_id,
const GURL& url,
+ const GURL& page_url,
const std::string& mime_type,
PluginProcessHost::Client* client) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
webkit::WebPluginInfo info;
+ bool allow_wildcard = true;
bool found = GetPluginInfo(
- render_process_id, render_view_id, url, mime_type, &info, NULL);
+ render_process_id, render_view_id, client->GetResourceContext(),
+ url, page_url, mime_type, allow_wildcard,
+ NULL, &info, NULL);
FilePath plugin_path;
if (found)
- plugin_path = FilePath(info.path);
+ plugin_path = info.path;
// Now we jump back to the IO thread to finish opening the channel.
BrowserThread::PostTask(
@@ -346,34 +356,38 @@ void PluginService::FinishOpenChannelToPlugin(
bool PluginService::GetPluginInfo(int render_process_id,
int render_view_id,
+ const content::ResourceContext& context,
const GURL& url,
+ const GURL& page_url,
const std::string& mime_type,
+ bool allow_wildcard,
+ bool* use_stale,
webkit::WebPluginInfo* info,
std::string* actual_mime_type) {
+ webkit::npapi::PluginList* plugin_list =
+ webkit::npapi::PluginList::Singleton();
// GetPluginInfoArray may need to load the plugins, so we need to be
// on the FILE thread.
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- {
- base::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 ||
- overridden_plugins_[i].url.is_empty())) {
- if (actual_mime_type)
- *actual_mime_type = mime_type;
- *info = overridden_plugins_[i].plugin;
- return true;
- }
- }
- }
- bool allow_wildcard = true;
+ DCHECK(use_stale || BrowserThread::CurrentlyOn(BrowserThread::FILE));
std::vector<webkit::WebPluginInfo> plugins;
std::vector<std::string> mime_types;
- webkit::npapi::PluginList::Singleton()->GetPluginInfoArray(
- url, mime_type, allow_wildcard, NULL, &plugins, &mime_types);
+ plugin_list->GetPluginInfoArray(
+ url, mime_type, allow_wildcard, use_stale, &plugins, &mime_types);
+ if (plugins.size() > 1 &&
+ plugins.back().path ==
+ FilePath(webkit::npapi::kDefaultPluginLibraryName)) {
+ // If there is at least one plug-in handling the required MIME type (apart
+ // from the default plug-in), we don't need the default plug-in.
+ plugins.pop_back();
+ }
+
for (size_t i = 0; i < plugins.size(); ++i) {
- if (webkit::IsPluginEnabled(plugins[i])) {
+ if (!filter_ || filter_->ShouldUsePlugin(render_process_id,
+ render_view_id,
+ &context,
+ url,
+ page_url,
+ &plugins[i])) {
*info = plugins[i];
if (actual_mime_type)
*actual_mime_type = mime_types[i];
@@ -383,6 +397,31 @@ bool PluginService::GetPluginInfo(int render_process_id,
return false;
}
+void PluginService::GetPlugins(
+ const content::ResourceContext& context,
+ std::vector<webkit::WebPluginInfo>* plugins) {
+ // GetPlugins may need to load the plugins, so we need to be
+ // on the FILE thread.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ webkit::npapi::PluginList* plugin_list =
+ webkit::npapi::PluginList::Singleton();
+ std::vector<webkit::WebPluginInfo> all_plugins;
+ plugin_list->GetPlugins(&all_plugins);
+
+ int child_process_id = -1;
+ int routing_id = MSG_ROUTING_NONE;
+ for (size_t i = 0; i < all_plugins.size(); ++i) {
+ if (!filter_ || filter_->ShouldUsePlugin(child_process_id,
+ routing_id,
+ &context,
+ GURL(),
+ GURL(),
+ &all_plugins[i])) {
+ plugins->push_back(all_plugins[i]);
+ }
+ }
+}
+
void PluginService::OnWaitableEventSignaled(
base::WaitableEvent* waitable_event) {
#if defined(OS_WIN)
@@ -403,40 +442,14 @@ void PluginService::OnWaitableEventSignaled(
void PluginService::Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) {
- switch (type) {
#if defined(OS_MACOSX)
- case content::NOTIFICATION_APP_ACTIVATED: {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- NewRunnableFunction(&NotifyPluginsOfActivation));
- break;
- }
-#endif
-
- case content::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED: {
- webkit::npapi::PluginList::Singleton()->RefreshPlugins();
- PurgePluginListCache(false);
- break;
- }
- case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
- int render_process_id = Source<RenderProcessHost>(source).ptr()->id();
-
- base::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();
+ if (type == content::NOTIFICATION_APP_ACTIVATED) {
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ NewRunnableFunction(&NotifyPluginsOfActivation));
+ return;
}
-}
-
-void PluginService::OverridePluginForTab(const OverriddenPlugin& plugin) {
- base::AutoLock auto_lock(overridden_plugins_lock_);
- overridden_plugins_.push_back(plugin);
+#endif
+ NOTREACHED();
}
void PluginService::PurgePluginListCache(bool reload_pages) {
@@ -446,32 +459,6 @@ void PluginService::PurgePluginListCache(bool reload_pages) {
}
}
-void PluginService::RestrictPluginToUrl(const FilePath& plugin_path,
- const GURL& url) {
- base::AutoLock auto_lock(restricted_plugin_lock_);
- if (url.is_empty()) {
- restricted_plugin_.erase(plugin_path);
- } else {
- restricted_plugin_[plugin_path] = url;
- }
-}
-
-bool PluginService::PluginAllowedForURL(const FilePath& plugin_path,
- const GURL& url) {
- if (url.is_empty())
- return true; // Caller wants all plugins.
-
- base::AutoLock auto_lock(restricted_plugin_lock_);
-
- RestrictedPluginMap::iterator it = restricted_plugin_.find(plugin_path);
- if (it == restricted_plugin_.end())
- return true; // This plugin is not restricted, so it's allowed everywhere.
-
- const GURL& required_url = it->second;
- return (url.scheme() == required_url.scheme() &&
- url.host() == required_url.host());
-}
-
void PluginService::RegisterPepperPlugins() {
// TODO(abarth): It seems like the PepperPluginRegistry should do this work.
PepperPluginRegistry::ComputeList(&ppapi_plugins_);
diff --git a/content/browser/plugin_service.h b/content/browser/plugin_service.h
index 9cdbcad..8dbef70f 100644
--- a/content/browser/plugin_service.h
+++ b/content/browser/plugin_service.h
@@ -13,11 +13,8 @@
#include <vector>
#include "base/basictypes.h"
-#include "base/file_path.h"
-#include "base/hash_tables.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/singleton.h"
-#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event_watcher.h"
#include "build/build_config.h"
#include "content/browser/plugin_process_host.h"
@@ -41,6 +38,11 @@
struct PepperPluginInfo;
class PluginDirWatcherDelegate;
+namespace content {
+class ResourceContext;
+class PluginServiceFilter;
+}
+
// This must be created on the main thread but it's only called on the IO/file
// thread.
class PluginService
@@ -57,6 +59,9 @@ class PluginService
// Returns the PluginService singleton.
static PluginService* GetInstance();
+ // Starts watching for changes in the list of installed plug-ins.
+ void StartWatchingPlugins();
+
// Gets the browser's UI locale.
const std::string& GetUILocale();
@@ -85,6 +90,7 @@ class PluginService
void OpenChannelToNpapiPlugin(int render_process_id,
int render_view_id,
const GURL& url,
+ const GURL& page_url,
const std::string& mime_type,
PluginProcessHost::Client* client);
void OpenChannelToPpapiPlugin(const FilePath& path,
@@ -93,32 +99,32 @@ class PluginService
PpapiBrokerProcessHost::Client* client);
// Gets the plugin in the list of plugins that matches the given url and mime
- // type. Must be called on the FILE thread.
+ // type. Must be called on the FILE thread if |use_stale| is NULL.
bool GetPluginInfo(int render_process_id,
int render_view_id,
+ const content::ResourceContext& context,
const GURL& url,
+ const GURL& page_url,
const std::string& mime_type,
+ bool allow_wildcard,
+ bool* use_stale,
webkit::WebPluginInfo* info,
std::string* actual_mime_type);
- // Safe to be called from any thread.
- void OverridePluginForTab(const OverriddenPlugin& plugin);
-
- // Restricts the given plugin to the the scheme and host of the given url.
- // Call with an empty url to reset this.
- // Can be called on any thread.
- void RestrictPluginToUrl(const FilePath& plugin_path, const GURL& url);
-
- // Returns true if the given plugin is allowed to be used by a page with
- // the given URL.
- // Can be called on any thread.
- bool PluginAllowedForURL(const FilePath& plugin_path, const GURL& url);
+ // Returns a list of all plug-ins available to the resource context. Must be
+ // called on the FILE thread.
+ void GetPlugins(const content::ResourceContext& context,
+ std::vector<webkit::WebPluginInfo>* plugins);
// Tells all the renderer processes to throw away their cache of the plugin
// list, and optionally also reload all the pages with plugins.
// NOTE: can only be called on the UI thread.
static void PurgePluginListCache(bool reload_pages);
+ void set_filter(content::PluginServiceFilter* filter) {
+ filter_ = filter;
+ }
+
private:
friend struct DefaultSingletonTraits<PluginService>;
@@ -143,6 +149,7 @@ class PluginService
int render_process_id,
int render_view_id,
const GURL& url,
+ const GURL& page_url,
const std::string& mime_type,
PluginProcessHost::Client* client);
@@ -163,11 +170,6 @@ class PluginService
// The browser's UI locale.
const std::string ui_locale_;
- // Map of plugin paths to the origin they are restricted to.
- base::Lock restricted_plugin_lock_; // Guards access to restricted_plugin_.
- typedef base::hash_map<FilePath, GURL> RestrictedPluginMap;
- RestrictedPluginMap restricted_plugin_;
-
NotificationRegistrar registrar_;
#if defined(OS_WIN)
@@ -187,8 +189,8 @@ class PluginService
std::vector<PepperPluginInfo> ppapi_plugins_;
- std::vector<OverriddenPlugin> overridden_plugins_;
- base::Lock overridden_plugins_lock_;
+ // Weak pointer; outlives us.
+ content::PluginServiceFilter* filter_;
DISALLOW_COPY_AND_ASSIGN(PluginService);
};
diff --git a/content/browser/plugin_service_browsertest.cc b/content/browser/plugin_service_browsertest.cc
index 95ce4b6..c49a90b 100644
--- a/content/browser/plugin_service_browsertest.cc
+++ b/content/browser/plugin_service_browsertest.cc
@@ -6,9 +6,12 @@
#include "base/command_line.h"
#include "base/path_service.h"
+#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/browser_thread.h"
+#include "content/browser/resource_context.h"
#include "content/common/content_switches.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "webkit/plugins/npapi/plugin_list.h"
@@ -22,8 +25,9 @@ const char* kNPAPITestPluginMimeType = "application/vnd.npapi-test";
class MockPluginProcessHostClient : public PluginProcessHost::Client,
public IPC::Channel::Listener {
public:
- MockPluginProcessHostClient()
- : channel_(NULL),
+ MockPluginProcessHostClient(const content::ResourceContext& context)
+ : context_(context),
+ channel_(NULL),
set_plugin_info_called_(false) {
}
@@ -33,8 +37,11 @@ class MockPluginProcessHostClient : public PluginProcessHost::Client,
}
// Client implementation.
- int ID() { return 42; }
- bool OffTheRecord() { return false; }
+ virtual int ID() OVERRIDE { return 42; }
+ virtual bool OffTheRecord() OVERRIDE { return false; }
+ virtual const content::ResourceContext& GetResourceContext() OVERRIDE {
+ return context_;
+ }
void OnChannelOpened(const IPC::ChannelHandle& handle) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -63,6 +70,7 @@ class MockPluginProcessHostClient : public PluginProcessHost::Client,
MOCK_METHOD0(OnChannelListenError, void());
private:
+ const content::ResourceContext& context_;
IPC::Channel* channel_;
bool set_plugin_info_called_;
DISALLOW_COPY_AND_ASSIGN(MockPluginProcessHostClient);
@@ -87,8 +95,9 @@ class PluginServiceTest : public InProcessBrowserTest {
// Try to open a channel to the test plugin. Minimal plugin process spawning
// test for the PluginService interface.
IN_PROC_BROWSER_TEST_F(PluginServiceTest, OpenChannelToPlugin) {
- MockPluginProcessHostClient mock_client;
+ ::testing::StrictMock<MockPluginProcessHostClient> mock_client(
+ browser()->profile()->GetResourceContext());
PluginService::GetInstance()->OpenChannelToNpapiPlugin(
- 0, 0, GURL(), kNPAPITestPluginMimeType, &mock_client);
+ 0, 0, GURL(), GURL(), kNPAPITestPluginMimeType, &mock_client);
ui_test_utils::RunMessageLoop();
}
diff --git a/content/browser/plugin_service_filter.h b/content/browser/plugin_service_filter.h
new file mode 100644
index 0000000..790c501
--- /dev/null
+++ b/content/browser/plugin_service_filter.h
@@ -0,0 +1,37 @@
+// 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 CONTENT_BROWSER_PLUGIN_FILTER_H_
+#define CONTENT_BROWSER_PLUGIN_FILTER_H_
+#pragma once
+
+class GURL;
+
+namespace webkit {
+struct WebPluginInfo;
+}
+
+namespace content {
+
+class ResourceContext;
+
+// Callback class to let the client filter the list of all installed plug-ins.
+// This class is called on the FILE thread.
+class PluginServiceFilter {
+ public:
+ virtual ~PluginServiceFilter() {}
+ // Whether to use |plugin|. The client can return false to disallow the
+ // plugin, or return true and optionally change the passed in plugin.
+ virtual bool ShouldUsePlugin(
+ int render_process_id,
+ int render_view_id,
+ const void* context,
+ const GURL& url,
+ const GURL& policy_url,
+ webkit::WebPluginInfo* plugin) = 0;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_PLUGIN_FILTER_H_
diff --git a/content/browser/renderer_host/buffered_resource_handler.cc b/content/browser/renderer_host/buffered_resource_handler.cc
index 97b063f..026ce66 100644
--- a/content/browser/renderer_host/buffered_resource_handler.cc
+++ b/content/browser/renderer_host/buffered_resource_handler.cc
@@ -12,6 +12,7 @@
#include "content/browser/browser_thread.h"
#include "content/browser/content_browser_client.h"
#include "content/browser/download/download_resource_handler.h"
+#include "content/browser/plugin_service.h"
#include "content/browser/renderer_host/resource_dispatcher_host.h"
#include "content/browser/renderer_host/resource_dispatcher_host_delegate.h"
#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
@@ -397,10 +398,15 @@ bool BufferedResourceHandler::ShouldDownload(bool* need_plugin_list) {
// Finally, check the plugin list.
bool allow_wildcard = false;
+ ResourceDispatcherHostRequestInfo* info =
+ ResourceDispatcherHost::InfoForRequest(request_);
bool stale = false;
- std::vector<webkit::WebPluginInfo> plugins;
- webkit::npapi::PluginList::Singleton()->GetPluginInfoArray(
- request_->url(), type, allow_wildcard, &stale, &plugins, NULL);
+ webkit::WebPluginInfo plugin;
+ bool found = PluginService::GetInstance()->GetPluginInfo(
+ info->child_id(), info->route_id(), *info->context(),
+ request_->url(), GURL(), type, allow_wildcard,
+ &stale, &plugin, NULL);
+
if (need_plugin_list) {
if (stale) {
*need_plugin_list = true;
@@ -410,11 +416,7 @@ bool BufferedResourceHandler::ShouldDownload(bool* need_plugin_list) {
DCHECK(!stale);
}
- for (size_t i = 0; i < plugins.size(); ++i) {
- if (webkit::IsPluginEnabled(plugins[i]))
- return false;
- }
- return true;
+ return !found;
}
void BufferedResourceHandler::UseAlternateResourceHandler(
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 791dc9e..32180e3 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -70,6 +70,7 @@
#endif
using net::CookieStore;
+using content::PluginServiceFilter;
namespace {
@@ -121,27 +122,33 @@ class OpenChannelToNpapiPluginCallback : public RenderMessageCompletionCallback,
public PluginProcessHost::Client {
public:
OpenChannelToNpapiPluginCallback(RenderMessageFilter* filter,
+ const content::ResourceContext& context,
IPC::Message* reply_msg)
- : RenderMessageCompletionCallback(filter, reply_msg) {
+ : RenderMessageCompletionCallback(filter, reply_msg),
+ context_(context) {
}
- virtual int ID() {
+ virtual int ID() OVERRIDE {
return filter()->render_process_id();
}
- virtual bool OffTheRecord() {
+ virtual const content::ResourceContext& GetResourceContext() OVERRIDE {
+ return context_;
+ }
+
+ virtual bool OffTheRecord() OVERRIDE {
return filter()->OffTheRecord();
}
- virtual void SetPluginInfo(const webkit::WebPluginInfo& info) {
+ virtual void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE {
info_ = info;
}
- virtual void OnChannelOpened(const IPC::ChannelHandle& handle) {
+ virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE {
WriteReplyAndDeleteThis(handle);
}
- virtual void OnError() {
+ virtual void OnError() OVERRIDE {
WriteReplyAndDeleteThis(IPC::ChannelHandle());
}
@@ -152,6 +159,7 @@ class OpenChannelToNpapiPluginCallback : public RenderMessageCompletionCallback,
SendReplyAndDeleteThis();
}
+ const content::ResourceContext& context_;
webkit::WebPluginInfo info_;
};
@@ -536,38 +544,36 @@ void RenderMessageFilter::OnGetPlugins(
}
}
- std::vector<webkit::WebPluginInfo> all_plugins;
- webkit::npapi::PluginList::Singleton()->GetPlugins(&all_plugins);
- for (size_t i = 0; i < all_plugins.size(); ++i) {
- if (webkit::IsPluginEnabled(all_plugins[i]))
- plugins->push_back(all_plugins[i]);
- }
+ PluginService::GetInstance()->GetPlugins(resource_context_,
+ plugins);
}
void RenderMessageFilter::OnGetPluginInfo(
int routing_id,
const GURL& url,
- const GURL& policy_url,
+ const GURL& page_url,
const std::string& mime_type,
bool* found,
webkit::WebPluginInfo* info,
std::string* actual_mime_type) {
+ bool allow_wildcard = true;
*found = plugin_service_->GetPluginInfo(
- render_process_id_, routing_id, url, mime_type, info, actual_mime_type);
-
- if (*found) {
- if (!plugin_service_->PluginAllowedForURL(info->path, policy_url))
- info->enabled |= webkit::WebPluginInfo::POLICY_DISABLED;
- }
+ render_process_id_, routing_id, resource_context_,
+ url, page_url, mime_type, allow_wildcard,
+ NULL, info, actual_mime_type);
}
void RenderMessageFilter::OnOpenChannelToPlugin(int routing_id,
const GURL& url,
+ const GURL& policy_url,
const std::string& mime_type,
IPC::Message* reply_msg) {
plugin_service_->OpenChannelToNpapiPlugin(
- render_process_id_, routing_id, url, mime_type,
- new OpenChannelToNpapiPluginCallback(this, reply_msg));
+ render_process_id_, routing_id,
+ url, policy_url, mime_type,
+ new OpenChannelToNpapiPluginCallback(this,
+ resource_context_,
+ reply_msg));
}
void RenderMessageFilter::OnOpenChannelToPepperPlugin(
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h
index 946d144..247571e 100644
--- a/content/browser/renderer_host/render_message_filter.h
+++ b/content/browser/renderer_host/render_message_filter.h
@@ -27,7 +27,6 @@
#include "ui/gfx/surface/transport_dib.h"
struct FontDescriptor;
-class HostContentSettingsMap;
class RenderWidgetHelper;
struct ViewHostMsg_CreateWindow_Params;
struct ViewHostMsg_CreateWorker_Params;
@@ -157,6 +156,7 @@ class RenderMessageFilter : public BrowserMessageFilter {
std::string* actual_mime_type);
void OnOpenChannelToPlugin(int routing_id,
const GURL& url,
+ const GURL& policy_url,
const std::string& mime_type,
IPC::Message* reply_msg);
void OnOpenChannelToPepperPlugin(const FilePath& path,
diff --git a/content/common/content_notification_types.h b/content/common/content_notification_types.h
index 144ebb7..a193dac 100644
--- a/content/common/content_notification_types.h
+++ b/content/common/content_notification_types.h
@@ -412,10 +412,6 @@ enum NotificationType {
// in a Details<ChildProcessInfo>.
NOTIFICATION_CHILD_INSTANCE_CREATED,
- // Sent by the PluginUpdater when there is a change of plugin
- // enable/disable status.
- NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
-
// Download Notifications --------------------------------------------------
// Sent when a page generation to MHTML has finished.
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 395ff9e..c71b244 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -1613,16 +1613,14 @@ IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_GetPlugins,
std::vector<webkit::WebPluginInfo> /* plugins */)
// Return information about a plugin for the given URL and MIME
-// type. If there is no matching plugin, |found| is false. If
-// |enabled| in the WebPluginInfo struct is false, the plug-in is
-// treated as if it was not installed at all.
+// type. If there is no matching plugin, |found| is false.
// |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_CONTROL4_3(ViewHostMsg_GetPluginInfo,
int /* routing_id */,
GURL /* url */,
- GURL /* policy_url */,
+ GURL /* page_url */,
std::string /* mime_type */,
bool /* found */,
webkit::WebPluginInfo /* plugin info */,
@@ -1632,9 +1630,10 @@ IPC_SYNC_MESSAGE_CONTROL4_3(ViewHostMsg_GetPluginInfo,
// 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_CONTROL3_2(ViewHostMsg_OpenChannelToPlugin,
+IPC_SYNC_MESSAGE_CONTROL4_2(ViewHostMsg_OpenChannelToPlugin,
int /* routing_id */,
GURL /* url */,
+ GURL /* page_url */,
std::string /* mime_type */,
IPC::ChannelHandle /* channel_handle */,
webkit::WebPluginInfo /* info */)
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index a346ffe..60b9e49 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -294,6 +294,7 @@
'browser/plugin_process_host_mac.cc',
'browser/plugin_service.cc',
'browser/plugin_service.h',
+ 'browser/plugin_service_filter.h',
'browser/quota_permission_context.h',
'browser/renderer_host/accelerated_surface_container_mac.cc',
'browser/renderer_host/accelerated_surface_container_mac.h',
diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc
index 9ea7d42..c783312 100644
--- a/content/renderer/render_view.cc
+++ b/content/renderer/render_view.cc
@@ -581,7 +581,7 @@ WebPlugin* RenderView::CreatePluginNoCheck(WebFrame* frame,
Send(new ViewHostMsg_GetPluginInfo(
routing_id_, params.url, frame->top()->document().url(),
params.mimeType.utf8(), &found, &info, &mime_type));
- if (!found || !webkit::IsPluginEnabled(info))
+ if (!found)
return NULL;
bool pepper_plugin_was_registered = false;
diff --git a/content/renderer/render_view.h b/content/renderer/render_view.h
index 2df1088..cadbc81 100644
--- a/content/renderer/render_view.h
+++ b/content/renderer/render_view.h
@@ -88,10 +88,6 @@ namespace content {
class P2PSocketDispatcher;
} // namespace content
-namespace chrome {
-class ChromeContentRendererClient;
-} // namespace chrome
-
namespace gfx {
class Point;
class Rect;
@@ -99,10 +95,6 @@ class Rect;
namespace webkit {
-namespace npapi {
-class PluginGroup;
-} // namespace npapi
-
namespace ppapi {
class PluginInstance;
class PluginModule;
diff --git a/content/renderer/webplugin_delegate_proxy.cc b/content/renderer/webplugin_delegate_proxy.cc
index c9640b3..8ffd930 100644
--- a/content/renderer/webplugin_delegate_proxy.cc
+++ b/content/renderer/webplugin_delegate_proxy.cc
@@ -283,8 +283,8 @@ bool WebPluginDelegateProxy::Initialize(
bool load_manually) {
IPC::ChannelHandle channel_handle;
if (!RenderThread::current()->Send(new ViewHostMsg_OpenChannelToPlugin(
- render_view_->routing_id(), url, mime_type_, &channel_handle,
- &info_))) {
+ render_view_->routing_id(), url, page_url_, mime_type_,
+ &channel_handle, &info_))) {
return false;
}
diff --git a/webkit/plugins/npapi/plugin_list.cc b/webkit/plugins/npapi/plugin_list.cc
index 3f3e4e0..45160fc 100644
--- a/webkit/plugins/npapi/plugin_list.cc
+++ b/webkit/plugins/npapi/plugin_list.cc
@@ -519,13 +519,12 @@ void PluginList::GetPluginInfoArray(
std::set<FilePath> visited_plugins;
- // Add in enabled plugins by mime type.
+ // Add in plugins by mime type.
for (size_t i = 0; i < plugin_groups_.size(); ++i) {
const std::vector<webkit::WebPluginInfo>& plugins =
plugin_groups_[i]->web_plugins_info();
for (size_t i = 0; i < plugins.size(); ++i) {
- if (IsPluginEnabled(plugins[i]) && SupportsType(plugins[i],
- mime_type, allow_wildcard)) {
+ if (SupportsType(plugins[i], mime_type, allow_wildcard)) {
FilePath path = plugins[i].path;
if (path.value() != kDefaultPluginLibraryName &&
visited_plugins.insert(path).second) {
@@ -537,7 +536,7 @@ void PluginList::GetPluginInfoArray(
}
}
- // Add in enabled plugins by url.
+ // Add in plugins by url.
std::string path = url.path();
std::string::size_type last_dot = path.rfind('.');
if (last_dot != std::string::npos) {
@@ -547,8 +546,7 @@ void PluginList::GetPluginInfoArray(
const std::vector<webkit::WebPluginInfo>& plugins =
plugin_groups_[i]->web_plugins_info();
for (size_t i = 0; i < plugins.size(); ++i) {
- if (IsPluginEnabled(plugins[i]) &&
- SupportsExtension(plugins[i], extension, &actual_mime_type)) {
+ if (SupportsExtension(plugins[i], extension, &actual_mime_type)) {
FilePath path = plugins[i].path;
if (path.value() != kDefaultPluginLibraryName &&
visited_plugins.insert(path).second) {
@@ -561,24 +559,6 @@ void PluginList::GetPluginInfoArray(
}
}
- // Add in disabled plugins by mime type.
- for (size_t i = 0; i < plugin_groups_.size(); ++i) {
- const std::vector<webkit::WebPluginInfo>& plugins =
- plugin_groups_[i]->web_plugins_info();
- for (size_t i = 0; i < plugins.size(); ++i) {
- if (!IsPluginEnabled(plugins[i]) &&
- SupportsType(plugins[i], mime_type, allow_wildcard)) {
- FilePath path = plugins[i].path;
- if (path.value() != kDefaultPluginLibraryName &&
- visited_plugins.insert(path).second) {
- info->push_back(plugins[i]);
- if (actual_mime_types)
- actual_mime_types->push_back(mime_type);
- }
- }
- }
- }
-
// Add the default plugin at the end if it supports the mime type given,
// and the default plugin is enabled.
for (size_t i = 0; i < plugin_groups_.size(); ++i) {