1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
7 #include "base/logging.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/plugins/plugin_metadata.h"
11 #include "chrome/browser/plugins/plugin_prefs.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/plugin_service.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/resource_context.h"
19 using content::BrowserThread;
20 using content::PluginService;
23 ChromePluginServiceFilter* ChromePluginServiceFilter::GetInstance() {
24 return Singleton<ChromePluginServiceFilter>::get();
27 void ChromePluginServiceFilter::RegisterResourceContext(
28 PluginPrefs* plugin_prefs,
29 const void* context) {
30 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
31 base::AutoLock lock(lock_);
32 resource_context_map_[context] = plugin_prefs;
35 void ChromePluginServiceFilter::UnregisterResourceContext(
36 const void* context) {
37 base::AutoLock lock(lock_);
38 resource_context_map_.erase(context);
41 void ChromePluginServiceFilter::OverridePluginForTab(
42 int render_process_id,
45 const content::WebPluginInfo& plugin) {
46 base::AutoLock auto_lock(lock_);
47 ProcessDetails* details = GetOrRegisterProcess(render_process_id);
48 OverriddenPlugin overridden_plugin;
49 overridden_plugin.render_view_id = render_view_id;
50 overridden_plugin.url = url;
51 overridden_plugin.plugin = plugin;
52 details->overridden_plugins.push_back(overridden_plugin);
55 void ChromePluginServiceFilter::RestrictPluginToProfileAndOrigin(
56 const base::FilePath& plugin_path,
59 base::AutoLock auto_lock(lock_);
60 restricted_plugins_[plugin_path] =
61 std::make_pair(PluginPrefs::GetForProfile(profile).get(), origin);
64 void ChromePluginServiceFilter::UnrestrictPlugin(
65 const base::FilePath& plugin_path) {
66 base::AutoLock auto_lock(lock_);
67 restricted_plugins_.erase(plugin_path);
70 bool ChromePluginServiceFilter::IsPluginRestricted(
71 const base::FilePath& plugin_path) {
72 base::AutoLock auto_lock(lock_);
73 return restricted_plugins_.find(plugin_path) != restricted_plugins_.end();
76 bool ChromePluginServiceFilter::IsPluginAvailable(
77 int render_process_id,
81 const GURL& policy_url,
82 content::WebPluginInfo* plugin) {
83 base::AutoLock auto_lock(lock_);
84 const ProcessDetails* details = GetProcess(render_process_id);
86 // Check whether the plugin is overridden.
88 for (size_t i = 0; i < details->overridden_plugins.size(); ++i) {
89 if (details->overridden_plugins[i].render_view_id == render_view_id &&
90 (details->overridden_plugins[i].url == url ||
91 details->overridden_plugins[i].url.is_empty())) {
93 bool use = details->overridden_plugins[i].plugin.path == plugin->path;
95 *plugin = details->overridden_plugins[i].plugin;
101 // Check whether the plugin is disabled.
102 ResourceContextMap::iterator prefs_it =
103 resource_context_map_.find(context);
104 if (prefs_it == resource_context_map_.end())
107 PluginPrefs* plugin_prefs = prefs_it->second.get();
108 if (!plugin_prefs->IsPluginEnabled(*plugin))
111 // Check whether the plugin is restricted to a URL.
112 RestrictedPluginMap::const_iterator it =
113 restricted_plugins_.find(plugin->path);
114 if (it != restricted_plugins_.end()) {
115 if (it->second.first != plugin_prefs)
117 const GURL& origin = it->second.second;
118 if (!origin.is_empty() &&
119 (policy_url.scheme() != origin.scheme() ||
120 policy_url.host() != origin.host() ||
121 policy_url.port() != origin.port())) {
129 bool ChromePluginServiceFilter::CanLoadPlugin(int render_process_id,
130 const base::FilePath& path) {
131 // The browser itself sometimes loads plug-ins to e.g. clear plug-in data.
132 // We always grant the browser permission.
133 if (!render_process_id)
136 base::AutoLock auto_lock(lock_);
137 const ProcessDetails* details = GetProcess(render_process_id);
141 if (details->authorized_plugins.find(path) ==
142 details->authorized_plugins.end() &&
143 details->authorized_plugins.find(base::FilePath()) ==
144 details->authorized_plugins.end()) {
151 void ChromePluginServiceFilter::AuthorizePlugin(
152 int render_process_id,
153 const base::FilePath& plugin_path) {
154 base::AutoLock auto_lock(lock_);
155 ProcessDetails* details = GetOrRegisterProcess(render_process_id);
156 details->authorized_plugins.insert(plugin_path);
159 void ChromePluginServiceFilter::AuthorizeAllPlugins(int render_process_id) {
160 AuthorizePlugin(render_process_id, base::FilePath());
163 ChromePluginServiceFilter::ChromePluginServiceFilter() {
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
165 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
166 content::NotificationService::AllSources());
167 registrar_.Add(this, chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
168 content::NotificationService::AllSources());
171 ChromePluginServiceFilter::~ChromePluginServiceFilter() {
174 void ChromePluginServiceFilter::Observe(
176 const content::NotificationSource& source,
177 const content::NotificationDetails& details) {
178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
180 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
181 int render_process_id =
182 content::Source<content::RenderProcessHost>(source).ptr()->GetID();
184 base::AutoLock auto_lock(lock_);
185 plugin_details_.erase(render_process_id);
188 case chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED: {
189 Profile* profile = content::Source<Profile>(source).ptr();
190 PluginService::GetInstance()->PurgePluginListCache(profile, false);
191 if (profile && profile->HasOffTheRecordProfile()) {
192 PluginService::GetInstance()->PurgePluginListCache(
193 profile->GetOffTheRecordProfile(), false);
203 ChromePluginServiceFilter::ProcessDetails*
204 ChromePluginServiceFilter::GetOrRegisterProcess(
205 int render_process_id) {
206 return &plugin_details_[render_process_id];
209 const ChromePluginServiceFilter::ProcessDetails*
210 ChromePluginServiceFilter::GetProcess(
211 int render_process_id) const {
212 std::map<int, ProcessDetails>::const_iterator it =
213 plugin_details_.find(render_process_id);
214 if (it == plugin_details_.end())
219 ChromePluginServiceFilter::OverriddenPlugin::OverriddenPlugin()
220 : render_view_id(MSG_ROUTING_NONE) {
223 ChromePluginServiceFilter::OverriddenPlugin::~OverriddenPlugin() {
226 ChromePluginServiceFilter::ProcessDetails::ProcessDetails() {
229 ChromePluginServiceFilter::ProcessDetails::~ProcessDetails() {