Chromium Code Reviews| Index: chrome/browser/chrome_plugin_service_helper.cc |
| diff --git a/chrome/browser/chrome_plugin_service_helper.cc b/chrome/browser/chrome_plugin_service_helper.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a106e084390952c298a16bc917d165c849eac7b3 |
| --- /dev/null |
| +++ b/chrome/browser/chrome_plugin_service_helper.cc |
| @@ -0,0 +1,193 @@ |
| +// 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_helper.h" |
| + |
| +#include "base/logging.h" |
| +#include "chrome/common/chrome_notification_types.h" |
| +#include "content/browser/browser_thread.h" |
| +#include "content/browser/plugin_filter.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" |
| +#include "webkit/plugins/npapi/webplugininfo.h" |
| + |
| +namespace { |
| + |
| +class ChromePluginFilter : public PluginFilter { |
| + public: |
| + ChromePluginFilter(int render_process_id, |
| + int render_view_id, |
| + const content::ResourceContext& context, |
| + const GURL& url, |
| + const GURL& policy_url); |
| + virtual ~ChromePluginFilter(); |
| + |
| + // PluginService::Filter implementation: |
| + virtual bool ShouldUsePlugin(webkit::npapi::WebPluginInfo* plugin) OVERRIDE; |
| + |
| + private: |
| + GURL policy_url_; |
| + |
| + scoped_ptr<webkit::npapi::WebPluginInfo> overridden_plugin_; |
| + bool use_default_plugin_; |
| +}; |
| + |
| +ChromePluginFilter::ChromePluginFilter( |
| + int render_process_id, |
| + int render_view_id, |
| + const content::ResourceContext& resource_context, |
| + const GURL& url, |
| + const GURL& policy_url) |
| + : policy_url_(policy_url), |
| + use_default_plugin_(true) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + ChromePluginServiceHelper* helper = ChromePluginServiceHelper::GetInstance(); |
| + overridden_plugin_.reset(helper->FindOverriddenPluginForTab( |
| + render_process_id, render_view_id, url)); |
| +} |
| + |
| +ChromePluginFilter::~ChromePluginFilter() { |
| +} |
| + |
| +bool ChromePluginFilter::ShouldUsePlugin(webkit::npapi::WebPluginInfo* plugin) { |
| + // Check whether the plugin is overridden. |
| + if (overridden_plugin_.get()) { |
| + if (overridden_plugin_->path != plugin->path) |
| + return false; |
| + *plugin = *overridden_plugin_; |
|
jam
2011/08/02 04:18:18
why is this line needed? i.e. under what condition
Bernhard Bauer
2011/08/02 12:45:08
When we want to use an out-of-date version of Read
|
| + return true; |
| + } |
| + |
| + // Check whether the plugin is disabled. |
| + if (!webkit::npapi::IsPluginEnabled(*plugin)) { |
| + // Don't use the default plug-in to handle a disabled plug-in (because |
| + // offering to install an already installed plug-in would be confusing to |
| + // the user). |
| + // TODO(bauerb): Implement the default plug-in functionality directly |
|
jam
2011/08/01 17:25:04
I don't understand this comment? Why do you think
Bernhard Bauer
2011/08/01 18:07:39
Using a plug-in that handles MIME type "*" is a ni
|
| + // without using a plug-in and get rid of all this hackery. |
| + use_default_plugin_ = false; |
| + return false; |
| + } |
| + |
| + if (!use_default_plugin_ && |
| + plugin->path.value() == webkit::npapi::kDefaultPluginLibraryName) { |
| + return false; |
| + } |
| + |
| + // Check whether the plugin is restricted to a URL. |
|
jam
2011/08/02 04:18:18
btw, now that this code lives in chrome, we can ge
Bernhard Bauer
2011/08/02 12:45:08
Hmm, ExtensionService currently lives on the UI th
|
| + ChromePluginServiceHelper* helper = ChromePluginServiceHelper::GetInstance(); |
| + GURL restricted_url = helper->FindRestrictedURLForPlugin(plugin->path); |
| + if (!restricted_url.is_empty() && |
| + (policy_url_.scheme() != restricted_url.scheme() || |
| + policy_url_.host() != restricted_url.host())) { |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +} // namespace |
| + |
| +// static |
| +ChromePluginServiceHelper* ChromePluginServiceHelper::GetInstance() { |
| + return Singleton<ChromePluginServiceHelper>::get(); |
| +} |
| + |
| +void ChromePluginServiceHelper::OverridePluginForTab( |
| + int render_process_id, |
| + int render_view_id, |
| + const GURL& url, |
| + const webkit::npapi::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); |
| +} |
| + |
| +webkit::npapi::WebPluginInfo* |
| + ChromePluginServiceHelper::FindOverriddenPluginForTab( |
| + int render_process_id, |
| + int render_view_id, |
| + const GURL& url) { |
| + 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_[i].render_view_id == render_view_id && |
| + overridden_plugins_[i].url == url) { |
| + return new webkit::npapi::WebPluginInfo(overridden_plugins_[i].plugin); |
| + } |
| + } |
| + return NULL; |
| +} |
| + |
| +void ChromePluginServiceHelper::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; |
| +} |
| + |
| +GURL ChromePluginServiceHelper::FindRestrictedURLForPlugin( |
| + const FilePath& plugin_path) { |
| + base::AutoLock auto_lock(lock_); |
| + RestrictedPluginMap::iterator it = restricted_plugins_.find(plugin_path); |
| + if (it != restricted_plugins_.end()) |
| + return it->second; |
| + return GURL(); |
| +} |
| + |
| +PluginFilter* ChromePluginServiceHelper::CreatePluginFilter( |
| + int render_process_id, |
| + int render_view_id, |
| + const content::ResourceContext& resource_context, |
| + const GURL& url, |
| + const GURL& policy_url) { |
| + return new ChromePluginFilter( |
| + render_process_id, render_view_id, resource_context, url, policy_url); |
| +} |
| + |
| +ChromePluginServiceHelper::ChromePluginServiceHelper() { |
| + 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()); |
| +} |
| + |
| +ChromePluginServiceHelper::~ChromePluginServiceHelper() { |
| +} |
| + |
| +void ChromePluginServiceHelper::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(); |
| + } |
| + } |
| +} |