| Index: content/browser/plugin_service.cc
|
| diff --git a/content/browser/plugin_service.cc b/content/browser/plugin_service.cc
|
| index 7ca5b2220d11e0fe3dee44e7215f602c046b0a65..86670db8e48773b5d2180a8f3161fe82a1750245 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_);
|
|
|