OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/plugin_prefs.h" | 5 #include "chrome/browser/plugin_prefs.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/lazy_instance.h" | |
11 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
12 #include "base/memory/singleton.h" | 11 #include "base/memory/singleton.h" |
13 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
14 #include "base/path_service.h" | 13 #include "base/path_service.h" |
15 #include "base/string_util.h" | |
16 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
17 #include "base/values.h" | 15 #include "base/values.h" |
18 #include "base/version.h" | 16 #include "base/version.h" |
19 #include "chrome/browser/browser_process.h" | |
20 #include "chrome/browser/prefs/pref_service.h" | 17 #include "chrome/browser/prefs/pref_service.h" |
21 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 18 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
22 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
23 #include "chrome/browser/profiles/profile_dependency_manager.h" | 20 #include "chrome/browser/profiles/profile_dependency_manager.h" |
24 #include "chrome/browser/profiles/profile_keyed_service.h" | 21 #include "chrome/browser/profiles/profile_keyed_service.h" |
25 #include "chrome/browser/profiles/profile_keyed_service_factory.h" | 22 #include "chrome/browser/profiles/profile_keyed_service_factory.h" |
26 #include "chrome/browser/profiles/profile_manager.h" | |
27 #include "chrome/common/chrome_content_client.h" | 23 #include "chrome/common/chrome_content_client.h" |
28 #include "chrome/common/chrome_notification_types.h" | 24 #include "chrome/common/chrome_notification_types.h" |
29 #include "chrome/common/chrome_paths.h" | 25 #include "chrome/common/chrome_paths.h" |
30 #include "chrome/common/chrome_switches.h" | 26 #include "chrome/common/chrome_switches.h" |
31 #include "chrome/common/pref_names.h" | 27 #include "chrome/common/pref_names.h" |
32 #include "content/browser/browser_thread.h" | 28 #include "content/browser/browser_thread.h" |
33 #include "content/common/notification_service.h" | 29 #include "content/common/notification_service.h" |
34 #include "webkit/plugins/npapi/plugin_group.h" | |
35 #include "webkit/plugins/npapi/plugin_list.h" | 30 #include "webkit/plugins/npapi/plugin_list.h" |
36 #include "webkit/plugins/webplugininfo.h" | 31 #include "webkit/plugins/webplugininfo.h" |
37 | 32 |
38 namespace { | 33 namespace { |
39 | 34 |
40 class PluginPrefsWrapper : public ProfileKeyedService { | 35 class PluginPrefsWrapper : public ProfileKeyedService { |
41 public: | 36 public: |
42 explicit PluginPrefsWrapper(scoped_refptr<PluginPrefs> plugin_prefs) | 37 explicit PluginPrefsWrapper(scoped_refptr<PluginPrefs> plugin_prefs) |
43 : plugin_prefs_(plugin_prefs) {} | 38 : plugin_prefs_(plugin_prefs) {} |
44 virtual ~PluginPrefsWrapper() {} | 39 virtual ~PluginPrefsWrapper() {} |
45 | 40 |
46 PluginPrefs* plugin_prefs() { return plugin_prefs_.get(); } | 41 PluginPrefs* plugin_prefs() { return plugin_prefs_.get(); } |
47 | 42 |
48 private: | 43 private: |
49 // ProfileKeyedService methods: | 44 // ProfileKeyedService methods: |
50 virtual void Shutdown() OVERRIDE { | 45 virtual void Shutdown() OVERRIDE { |
51 plugin_prefs_->ShutdownOnUIThread(); | 46 plugin_prefs_->ShutdownOnUIThread(); |
52 } | 47 } |
53 | 48 |
54 scoped_refptr<PluginPrefs> plugin_prefs_; | 49 scoped_refptr<PluginPrefs> plugin_prefs_; |
55 }; | 50 }; |
56 | 51 |
57 // Default state for a plug-in (not state of the default plug-in!). | |
58 // Accessed only on the UI thread. | |
59 base::LazyInstance<std::map<FilePath, bool> > g_default_plugin_state( | |
60 base::LINKER_INITIALIZED); | |
61 | |
62 } | 52 } |
63 | 53 |
64 // How long to wait to save the plugin enabled information, which might need to | 54 // How long to wait to save the plugin enabled information, which might need to |
65 // go to disk. | 55 // go to disk. |
66 #define kPluginUpdateDelayMs (60 * 1000) | 56 #define kPluginUpdateDelayMs (60 * 1000) |
67 | 57 |
68 class PluginPrefs::Factory : public ProfileKeyedServiceFactory { | 58 class PluginPrefs::Factory : public ProfileKeyedServiceFactory { |
69 public: | 59 public: |
70 static Factory* GetInstance(); | 60 static Factory* GetInstance(); |
71 | 61 |
72 PluginPrefsWrapper* GetWrapperForProfile(Profile* profile); | 62 PluginPrefsWrapper* GetWrapperForProfile(Profile* profile); |
73 | 63 |
74 // Factory function for use with | |
75 // ProfileKeyedServiceFactory::SetTestingFactory. | |
76 static ProfileKeyedService* CreateWrapperForProfile(Profile* profile); | |
77 | |
78 private: | 64 private: |
79 friend struct DefaultSingletonTraits<Factory>; | 65 friend struct DefaultSingletonTraits<Factory>; |
80 | 66 |
81 Factory(); | 67 Factory(); |
82 virtual ~Factory() {} | 68 virtual ~Factory() {} |
83 | 69 |
84 // ProfileKeyedServiceFactory methods: | 70 // ProfileKeyedServiceFactory methods: |
85 virtual ProfileKeyedService* BuildServiceInstanceFor( | 71 virtual ProfileKeyedService* BuildServiceInstanceFor( |
86 Profile* profile) const OVERRIDE; | 72 Profile* profile) const OVERRIDE; |
87 virtual bool ServiceRedirectedInIncognito() OVERRIDE { return true; } | 73 virtual bool ServiceRedirectedInIncognito() OVERRIDE { return true; } |
88 virtual bool ServiceIsNULLWhileTesting() OVERRIDE { return true; } | 74 virtual bool ServiceIsNULLWhileTesting() OVERRIDE { return true; } |
89 virtual bool ServiceIsCreatedWithProfile() OVERRIDE { return true; } | 75 virtual bool ServiceIsCreatedWithProfile() OVERRIDE { return true; } |
90 }; | 76 }; |
91 | 77 |
92 // static | 78 // static |
93 void PluginPrefs::Initialize() { | 79 void PluginPrefs::Initialize() { |
94 Factory::GetInstance(); | 80 Factory::GetInstance(); |
95 } | 81 } |
96 | 82 |
97 // static | 83 // static |
98 PluginPrefs* PluginPrefs::GetForProfile(Profile* profile) { | 84 PluginPrefs* PluginPrefs::GetForProfile(Profile* profile) { |
99 PluginPrefsWrapper* wrapper = | 85 PluginPrefsWrapper* wrapper = |
100 Factory::GetInstance()->GetWrapperForProfile(profile); | 86 Factory::GetInstance()->GetWrapperForProfile(profile); |
101 if (!wrapper) | 87 if (!wrapper) |
102 return NULL; | 88 return NULL; |
103 return wrapper->plugin_prefs(); | 89 return wrapper->plugin_prefs(); |
104 } | 90 } |
105 | 91 |
106 // static | 92 DictionaryValue* PluginPrefs::CreatePluginFileSummary( |
107 PluginPrefs* PluginPrefs::GetForTestingProfile(Profile* profile) { | 93 const webkit::WebPluginInfo& plugin) { |
108 ProfileKeyedService* wrapper = | 94 DictionaryValue* data = new DictionaryValue(); |
109 Factory::GetInstance()->SetTestingFactoryAndUse( | 95 data->SetString("path", plugin.path.value()); |
110 profile, &Factory::CreateWrapperForProfile); | 96 data->SetString("name", plugin.name); |
111 return static_cast<PluginPrefsWrapper*>(wrapper)->plugin_prefs(); | 97 data->SetString("version", plugin.version); |
| 98 data->SetBoolean("enabled", IsPluginEnabled(plugin)); |
| 99 return data; |
112 } | 100 } |
113 | 101 |
114 void PluginPrefs::EnablePluginGroup(bool enabled, const string16& group_name) { | 102 void PluginPrefs::EnablePluginGroup(bool enable, const string16& group_name) { |
115 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { | 103 webkit::npapi::PluginList::Singleton()->EnableGroup(enable, group_name); |
116 BrowserThread::PostTask( | 104 NotifyPluginStatusChanged(); |
117 BrowserThread::FILE, FROM_HERE, | |
118 NewRunnableMethod(this, &PluginPrefs::EnablePluginGroup, | |
119 enabled, group_name)); | |
120 return; | |
121 } | |
122 | |
123 webkit::npapi::PluginList* plugin_list = | |
124 webkit::npapi::PluginList::Singleton(); | |
125 std::vector<webkit::npapi::PluginGroup> groups; | |
126 plugin_list->GetPluginGroups(true, &groups); | |
127 | |
128 base::AutoLock auto_lock(lock_); | |
129 | |
130 // Set the desired state for the group. | |
131 plugin_group_state_[group_name] = enabled; | |
132 | |
133 // Update the state for all plug-ins in the group. | |
134 for (size_t i = 0; i < groups.size(); ++i) { | |
135 if (groups[i].GetGroupName() != group_name) | |
136 continue; | |
137 const std::vector<webkit::WebPluginInfo>& plugins = | |
138 groups[i].web_plugin_infos(); | |
139 for (size_t j = 0; j < plugins.size(); ++j) | |
140 plugin_state_[plugins[j].path] = enabled; | |
141 break; | |
142 } | |
143 | |
144 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
145 NewRunnableMethod(this, &PluginPrefs::OnUpdatePreferences, groups)); | |
146 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
147 NewRunnableMethod(this, &PluginPrefs::NotifyPluginStatusChanged)); | |
148 } | 105 } |
149 | 106 |
150 void PluginPrefs::EnablePlugin(bool enabled, const FilePath& path) { | 107 void PluginPrefs::EnablePlugin(bool enable, const FilePath& path) { |
151 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { | 108 if (enable) |
152 BrowserThread::PostTask( | 109 webkit::npapi::PluginList::Singleton()->EnablePlugin(path); |
153 BrowserThread::FILE, FROM_HERE, | 110 else |
154 NewRunnableMethod(this, &PluginPrefs::EnablePlugin, enabled, path)); | 111 webkit::npapi::PluginList::Singleton()->DisablePlugin(path); |
155 return; | |
156 } | |
157 | 112 |
158 { | 113 NotifyPluginStatusChanged(); |
159 // Set the desired state for the plug-in. | |
160 base::AutoLock auto_lock(lock_); | |
161 plugin_state_[path] = enabled; | |
162 } | |
163 | |
164 webkit::npapi::PluginList* plugin_list = | |
165 webkit::npapi::PluginList::Singleton(); | |
166 std::vector<webkit::npapi::PluginGroup> groups; | |
167 plugin_list->GetPluginGroups(true, &groups); | |
168 | |
169 bool found_group = false; | |
170 for (size_t i = 0; i < groups.size(); ++i) { | |
171 bool all_disabled = true; | |
172 const std::vector<webkit::WebPluginInfo>& plugins = | |
173 groups[i].web_plugin_infos(); | |
174 for (size_t j = 0; j < plugins.size(); ++j) { | |
175 all_disabled = all_disabled && !IsPluginEnabled(plugins[j]); | |
176 if (plugins[j].path == path) { | |
177 found_group = true; | |
178 DCHECK_EQ(enabled, IsPluginEnabled(plugins[j])); | |
179 } | |
180 } | |
181 if (found_group) { | |
182 // Update the state for the corresponding plug-in group. | |
183 base::AutoLock auto_lock(lock_); | |
184 plugin_group_state_[groups[i].GetGroupName()] = !all_disabled; | |
185 break; | |
186 } | |
187 } | |
188 | |
189 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
190 NewRunnableMethod(this, &PluginPrefs::OnUpdatePreferences, groups)); | |
191 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
192 NewRunnableMethod(this, &PluginPrefs::NotifyPluginStatusChanged)); | |
193 } | |
194 | |
195 // static | |
196 void PluginPrefs::EnablePluginGlobally(bool enable, const FilePath& file_path) { | |
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
198 g_default_plugin_state.Get()[file_path] = enable; | |
199 std::vector<Profile*> profiles = | |
200 g_browser_process->profile_manager()->GetLoadedProfiles(); | |
201 for (std::vector<Profile*>::iterator it = profiles.begin(); | |
202 it != profiles.end(); ++it) { | |
203 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(*it); | |
204 DCHECK(plugin_prefs); | |
205 plugin_prefs->EnablePlugin(enable, file_path); | |
206 } | |
207 } | |
208 | |
209 PluginPrefs::PolicyStatus PluginPrefs::PolicyStatusForPlugin( | |
210 const string16& name) { | |
211 base::AutoLock auto_lock(lock_); | |
212 if (IsStringMatchedInSet(name, policy_enabled_plugin_patterns_)) { | |
213 return POLICY_ENABLED; | |
214 } else if (IsStringMatchedInSet(name, policy_disabled_plugin_patterns_) && | |
215 !IsStringMatchedInSet( | |
216 name, policy_disabled_plugin_exception_patterns_)) { | |
217 return POLICY_DISABLED; | |
218 } else { | |
219 return NO_POLICY; | |
220 } | |
221 } | 114 } |
222 | 115 |
223 bool PluginPrefs::IsPluginEnabled(const webkit::WebPluginInfo& plugin) { | 116 bool PluginPrefs::IsPluginEnabled(const webkit::WebPluginInfo& plugin) { |
224 scoped_ptr<webkit::npapi::PluginGroup> group( | |
225 webkit::npapi::PluginList::Singleton()->GetPluginGroup(plugin)); | |
226 string16 group_name = group->GetGroupName(); | |
227 | |
228 // Check if the plug-in or its group is enabled by policy. | |
229 PolicyStatus plugin_status = PolicyStatusForPlugin(plugin.name); | |
230 PolicyStatus group_status = PolicyStatusForPlugin(group_name); | |
231 if (plugin_status == POLICY_ENABLED || group_status == POLICY_ENABLED) | |
232 return true; | |
233 | |
234 // Check if the plug-in or its group is disabled by policy. | |
235 if (plugin_status == POLICY_DISABLED || group_status == POLICY_DISABLED) | |
236 return false; | |
237 | |
238 // If enabling NaCl, make sure the plugin is also enabled. See bug | 117 // If enabling NaCl, make sure the plugin is also enabled. See bug |
239 // http://code.google.com/p/chromium/issues/detail?id=81010 for more | 118 // http://code.google.com/p/chromium/issues/detail?id=81010 for more |
240 // information. | 119 // information. |
241 // TODO(dspringer): When NaCl is on by default, remove this code. | 120 // TODO(dspringer): When NaCl is on by default, remove this code. |
242 if ((plugin.name == | 121 if ((plugin.name == |
243 ASCIIToUTF16(chrome::ChromeContentClient::kNaClPluginName)) && | 122 ASCIIToUTF16(chrome::ChromeContentClient::kNaClPluginName)) && |
244 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaCl)) { | 123 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaCl)) { |
245 return true; | 124 return true; |
246 } | 125 } |
247 | 126 return webkit::IsPluginEnabled(plugin); |
248 base::AutoLock auto_lock(lock_); | |
249 // Check user preferences for the plug-in. | |
250 std::map<FilePath, bool>::iterator plugin_it = | |
251 plugin_state_.find(plugin.path); | |
252 if (plugin_it != plugin_state_.end()) | |
253 return plugin_it->second; | |
254 | |
255 // Check user preferences for the plug-in group. | |
256 std::map<string16, bool>::iterator group_it( | |
257 plugin_group_state_.find(plugin.name)); | |
258 if (group_it != plugin_group_state_.end()) | |
259 return group_it->second; | |
260 | |
261 // Default to enabled. | |
262 return true; | |
263 } | 127 } |
264 | 128 |
265 void PluginPrefs::Observe(int type, | 129 void PluginPrefs::Observe(int type, |
266 const NotificationSource& source, | 130 const NotificationSource& source, |
267 const NotificationDetails& details) { | 131 const NotificationDetails& details) { |
268 DCHECK_EQ(chrome::NOTIFICATION_PREF_CHANGED, type); | 132 DCHECK_EQ(chrome::NOTIFICATION_PREF_CHANGED, type); |
269 const std::string* pref_name = Details<std::string>(details).ptr(); | 133 const std::string* pref_name = Details<std::string>(details).ptr(); |
270 if (!pref_name) { | 134 if (!pref_name) { |
271 NOTREACHED(); | 135 NOTREACHED(); |
272 return; | 136 return; |
273 } | 137 } |
274 DCHECK_EQ(prefs_, Source<PrefService>(source).ptr()); | 138 DCHECK_EQ(prefs_, Source<PrefService>(source).ptr()); |
275 if (*pref_name == prefs::kPluginsDisabledPlugins) { | 139 if (*pref_name == prefs::kPluginsDisabledPlugins || |
276 base::AutoLock auto_lock(lock_); | 140 *pref_name == prefs::kPluginsDisabledPluginsExceptions || |
277 ListValueToStringSet(prefs_->GetList(prefs::kPluginsDisabledPlugins), | 141 *pref_name == prefs::kPluginsEnabledPlugins) { |
278 &policy_disabled_plugin_patterns_); | 142 const ListValue* disabled_list = |
279 } else if (*pref_name == prefs::kPluginsDisabledPluginsExceptions) { | 143 prefs_->GetList(prefs::kPluginsDisabledPlugins); |
280 base::AutoLock auto_lock(lock_); | 144 const ListValue* exceptions_list = |
281 ListValueToStringSet( | 145 prefs_->GetList(prefs::kPluginsDisabledPluginsExceptions); |
282 prefs_->GetList(prefs::kPluginsDisabledPluginsExceptions), | 146 const ListValue* enabled_list = |
283 &policy_disabled_plugin_exception_patterns_); | 147 prefs_->GetList(prefs::kPluginsEnabledPlugins); |
284 } else if (*pref_name == prefs::kPluginsEnabledPlugins) { | 148 UpdatePluginsStateFromPolicy(disabled_list, exceptions_list, enabled_list); |
285 base::AutoLock auto_lock(lock_); | |
286 ListValueToStringSet(prefs_->GetList(prefs::kPluginsEnabledPlugins), | |
287 &policy_enabled_plugin_patterns_); | |
288 } else { | |
289 NOTREACHED(); | |
290 } | 149 } |
| 150 } |
| 151 |
| 152 void PluginPrefs::UpdatePluginsStateFromPolicy( |
| 153 const ListValue* disabled_list, |
| 154 const ListValue* exceptions_list, |
| 155 const ListValue* enabled_list) { |
| 156 std::set<string16> disabled_plugin_patterns; |
| 157 std::set<string16> disabled_plugin_exception_patterns; |
| 158 std::set<string16> enabled_plugin_patterns; |
| 159 |
| 160 ListValueToStringSet(disabled_list, &disabled_plugin_patterns); |
| 161 ListValueToStringSet(exceptions_list, &disabled_plugin_exception_patterns); |
| 162 ListValueToStringSet(enabled_list, &enabled_plugin_patterns); |
| 163 |
| 164 webkit::npapi::PluginGroup::SetPolicyEnforcedPluginPatterns( |
| 165 disabled_plugin_patterns, |
| 166 disabled_plugin_exception_patterns, |
| 167 enabled_plugin_patterns); |
| 168 |
291 NotifyPluginStatusChanged(); | 169 NotifyPluginStatusChanged(); |
292 } | 170 } |
293 | 171 |
294 /*static*/ | |
295 bool PluginPrefs::IsStringMatchedInSet(const string16& name, | |
296 const std::set<string16>& pattern_set) { | |
297 std::set<string16>::const_iterator pattern(pattern_set.begin()); | |
298 while (pattern != pattern_set.end()) { | |
299 if (MatchPattern(name, *pattern)) | |
300 return true; | |
301 ++pattern; | |
302 } | |
303 | |
304 return false; | |
305 } | |
306 | |
307 /* static */ | |
308 void PluginPrefs::ListValueToStringSet(const ListValue* src, | 172 void PluginPrefs::ListValueToStringSet(const ListValue* src, |
309 std::set<string16>* dest) { | 173 std::set<string16>* dest) { |
310 DCHECK(src); | 174 DCHECK(src); |
311 DCHECK(dest); | 175 DCHECK(dest); |
312 ListValue::const_iterator end(src->end()); | 176 ListValue::const_iterator end(src->end()); |
313 for (ListValue::const_iterator current(src->begin()); | 177 for (ListValue::const_iterator current(src->begin()); |
314 current != end; ++current) { | 178 current != end; ++current) { |
315 string16 plugin_name; | 179 string16 plugin_name; |
316 if ((*current)->GetAsString(&plugin_name)) { | 180 if ((*current)->GetAsString(&plugin_name)) { |
317 dest->insert(plugin_name); | 181 dest->insert(plugin_name); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 } | 270 } |
407 | 271 |
408 internal_pdf_enabled = enabled; | 272 internal_pdf_enabled = enabled; |
409 } else if (FilePath::CompareIgnoreCase(path, nacl_path_str) == 0) { | 273 } else if (FilePath::CompareIgnoreCase(path, nacl_path_str) == 0) { |
410 if (!enabled && force_enable_nacl) { | 274 if (!enabled && force_enable_nacl) { |
411 enabled = true; | 275 enabled = true; |
412 plugin->SetBoolean("enabled", true); | 276 plugin->SetBoolean("enabled", true); |
413 } | 277 } |
414 } | 278 } |
415 | 279 |
416 plugin_state_[plugin_path] = enabled; | 280 if (!enabled) |
| 281 webkit::npapi::PluginList::Singleton()->DisablePlugin(plugin_path); |
417 } else if (!enabled && plugin->GetString("name", &group_name)) { | 282 } else if (!enabled && plugin->GetString("name", &group_name)) { |
418 // Don't disable this group if it's for the pdf or nacl plugins and | 283 // Don't disable this group if it's for the pdf or nacl plugins and |
419 // we just forced it on. | 284 // we just forced it on. |
420 if (force_enable_internal_pdf && pdf_group_name == group_name) | 285 if (force_enable_internal_pdf && pdf_group_name == group_name) |
421 continue; | 286 continue; |
422 if (force_enable_nacl && (nacl_group_name == group_name || | 287 if (force_enable_nacl && (nacl_group_name == group_name || |
423 old_nacl_group_name == group_name)) | 288 old_nacl_group_name == group_name)) |
424 continue; | 289 continue; |
425 | 290 |
426 // Otherwise this is a list of groups. | 291 // Otherwise this is a list of groups. |
427 plugin_group_state_[group_name] = false; | 292 EnablePluginGroup(false, group_name); |
428 } | 293 } |
429 } | 294 } |
430 } else { | 295 } else { |
431 // If the saved plugin list is empty, then the call to UpdatePreferences() | 296 // If the saved plugin list is empty, then the call to UpdatePreferences() |
432 // below failed in an earlier run, possibly because the user closed the | 297 // below failed in an earlier run, possibly because the user closed the |
433 // browser too quickly. Try to force enable the internal PDF and nacl | 298 // browser too quickly. Try to force enable the internal PDF and nacl |
434 // plugins again. | 299 // plugins again. |
435 force_enable_internal_pdf = true; | 300 force_enable_internal_pdf = true; |
436 force_enable_nacl = true; | 301 force_enable_nacl = true; |
437 } | 302 } |
438 } // Scoped update of prefs::kPluginsPluginsList. | 303 } // Scoped update of prefs::kPluginsPluginsList. |
439 | 304 |
440 // Build the set of policy enabled/disabled plugin patterns once and cache it. | 305 // Build the set of policy enabled/disabled plugin patterns once and cache it. |
441 // Don't do this in the constructor, there's no profile available there. | 306 // Don't do this in the constructor, there's no profile available there. |
442 ListValueToStringSet(prefs_->GetList(prefs::kPluginsDisabledPlugins), | 307 const ListValue* disabled_plugins = |
443 &policy_disabled_plugin_patterns_); | 308 prefs_->GetList(prefs::kPluginsDisabledPlugins); |
444 ListValueToStringSet( | 309 const ListValue* disabled_exception_plugins = |
445 prefs_->GetList(prefs::kPluginsDisabledPluginsExceptions), | 310 prefs_->GetList(prefs::kPluginsDisabledPluginsExceptions); |
446 &policy_disabled_plugin_exception_patterns_); | 311 const ListValue* enabled_plugins = |
447 ListValueToStringSet(prefs_->GetList(prefs::kPluginsEnabledPlugins), | 312 prefs_->GetList(prefs::kPluginsEnabledPlugins); |
448 &policy_enabled_plugin_patterns_); | 313 UpdatePluginsStateFromPolicy(disabled_plugins, |
| 314 disabled_exception_plugins, |
| 315 enabled_plugins); |
449 | 316 |
| 317 registrar_.RemoveAll(); |
450 registrar_.Init(prefs_); | 318 registrar_.Init(prefs_); |
451 registrar_.Add(prefs::kPluginsDisabledPlugins, this); | 319 registrar_.Add(prefs::kPluginsDisabledPlugins, this); |
452 registrar_.Add(prefs::kPluginsDisabledPluginsExceptions, this); | 320 registrar_.Add(prefs::kPluginsDisabledPluginsExceptions, this); |
453 registrar_.Add(prefs::kPluginsEnabledPlugins, this); | 321 registrar_.Add(prefs::kPluginsEnabledPlugins, this); |
454 | 322 |
455 if (force_enable_internal_pdf || internal_pdf_enabled) { | 323 if (force_enable_internal_pdf || internal_pdf_enabled) { |
456 // See http://crbug.com/50105 for background. | 324 // See http://crbug.com/50105 for background. |
457 plugin_group_state_[ASCIIToUTF16( | 325 EnablePluginGroup(false, ASCIIToUTF16( |
458 webkit::npapi::PluginGroup::kAdobeReaderGroupName)] = false; | 326 webkit::npapi::PluginGroup::kAdobeReaderGroupName)); |
459 } | 327 } |
460 | 328 |
461 if (force_enable_internal_pdf || force_enable_nacl) { | 329 if (force_enable_internal_pdf || force_enable_nacl) { |
462 // We want to save this, but doing so requires loading the list of plugins, | 330 // We want to save this, but doing so requires loading the list of plugins, |
463 // so do it after a minute as to not impact startup performance. Note that | 331 // so do it after a minute as to not impact startup performance. Note that |
464 // plugins are loaded after 30s by the metrics service. | 332 // plugins are loaded after 30s by the metrics service. |
465 BrowserThread::PostDelayedTask( | 333 UpdatePreferences(kPluginUpdateDelayMs); |
466 BrowserThread::FILE, | |
467 FROM_HERE, | |
468 NewRunnableMethod(this, &PluginPrefs::GetPreferencesDataOnFileThread), | |
469 kPluginUpdateDelayMs); | |
470 } | 334 } |
471 | |
472 NotifyPluginStatusChanged(); | |
473 } | 335 } |
474 | 336 |
475 void PluginPrefs::ShutdownOnUIThread() { | 337 void PluginPrefs::ShutdownOnUIThread() { |
476 prefs_ = NULL; | 338 prefs_ = NULL; |
477 registrar_.RemoveAll(); | 339 registrar_.RemoveAll(); |
478 } | 340 } |
479 | 341 |
480 // static | 342 // static |
481 PluginPrefs::Factory* PluginPrefs::Factory::GetInstance() { | 343 PluginPrefs::Factory* PluginPrefs::Factory::GetInstance() { |
482 return Singleton<PluginPrefs::Factory>::get(); | 344 return Singleton<PluginPrefs::Factory>::get(); |
483 } | 345 } |
484 | 346 |
485 PluginPrefsWrapper* PluginPrefs::Factory::GetWrapperForProfile( | 347 PluginPrefsWrapper* PluginPrefs::Factory::GetWrapperForProfile( |
486 Profile* profile) { | 348 Profile* profile) { |
487 return static_cast<PluginPrefsWrapper*>(GetServiceForProfile(profile, true)); | 349 return static_cast<PluginPrefsWrapper*>(GetServiceForProfile(profile, true)); |
488 } | 350 } |
489 | 351 |
490 // static | |
491 ProfileKeyedService* PluginPrefs::Factory::CreateWrapperForProfile( | |
492 Profile* profile) { | |
493 return GetInstance()->BuildServiceInstanceFor(profile); | |
494 } | |
495 | |
496 PluginPrefs::Factory::Factory() | 352 PluginPrefs::Factory::Factory() |
497 : ProfileKeyedServiceFactory(ProfileDependencyManager::GetInstance()) { | 353 : ProfileKeyedServiceFactory(ProfileDependencyManager::GetInstance()) { |
498 } | 354 } |
499 | 355 |
500 ProfileKeyedService* PluginPrefs::Factory::BuildServiceInstanceFor( | 356 ProfileKeyedService* PluginPrefs::Factory::BuildServiceInstanceFor( |
501 Profile* profile) const { | 357 Profile* profile) const { |
502 scoped_refptr<PluginPrefs> plugin_prefs(new PluginPrefs()); | 358 scoped_refptr<PluginPrefs> plugin_prefs(new PluginPrefs()); |
503 plugin_prefs->SetPrefs(profile->GetPrefs()); | 359 plugin_prefs->SetPrefs(profile->GetPrefs()); |
504 return new PluginPrefsWrapper(plugin_prefs); | 360 return new PluginPrefsWrapper(plugin_prefs); |
505 } | 361 } |
506 | 362 |
507 PluginPrefs::PluginPrefs() : plugin_state_(g_default_plugin_state.Get()), | 363 PluginPrefs::PluginPrefs() : prefs_(NULL), notify_pending_(false) { |
508 prefs_(NULL) { | |
509 } | 364 } |
510 | 365 |
511 PluginPrefs::~PluginPrefs() { | 366 PluginPrefs::~PluginPrefs() { |
512 } | 367 } |
513 | 368 |
514 void PluginPrefs::SetPolicyEnforcedPluginPatterns( | 369 void PluginPrefs::UpdatePreferences(int delay_ms) { |
515 const std::set<string16>& disabled_patterns, | 370 BrowserThread::PostDelayedTask( |
516 const std::set<string16>& disabled_exception_patterns, | 371 BrowserThread::FILE, |
517 const std::set<string16>& enabled_patterns) { | 372 FROM_HERE, |
518 policy_disabled_plugin_patterns_ = disabled_patterns; | 373 NewRunnableMethod(this, &PluginPrefs::GetPreferencesDataOnFileThread), |
519 policy_disabled_plugin_exception_patterns_ = disabled_exception_patterns; | 374 delay_ms); |
520 policy_enabled_plugin_patterns_ = enabled_patterns; | |
521 } | 375 } |
522 | 376 |
523 void PluginPrefs::GetPreferencesDataOnFileThread() { | 377 void PluginPrefs::GetPreferencesDataOnFileThread() { |
| 378 std::vector<webkit::WebPluginInfo> plugins; |
524 std::vector<webkit::npapi::PluginGroup> groups; | 379 std::vector<webkit::npapi::PluginGroup> groups; |
525 | 380 |
526 webkit::npapi::PluginList* plugin_list = | 381 webkit::npapi::PluginList* plugin_list = |
527 webkit::npapi::PluginList::Singleton(); | 382 webkit::npapi::PluginList::Singleton(); |
| 383 plugin_list->GetPlugins(&plugins); |
528 plugin_list->GetPluginGroups(false, &groups); | 384 plugin_list->GetPluginGroups(false, &groups); |
529 | 385 |
530 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 386 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
531 NewRunnableMethod(this, &PluginPrefs::OnUpdatePreferences, groups)); | 387 NewRunnableMethod(this, &PluginPrefs::OnUpdatePreferences, |
| 388 plugins, groups)); |
532 } | 389 } |
533 | 390 |
534 void PluginPrefs::OnUpdatePreferences( | 391 void PluginPrefs::OnUpdatePreferences( |
| 392 std::vector<webkit::WebPluginInfo> plugins, |
535 std::vector<webkit::npapi::PluginGroup> groups) { | 393 std::vector<webkit::npapi::PluginGroup> groups) { |
536 if (!prefs_) | 394 if (!prefs_) |
537 return; | 395 return; |
538 | 396 |
539 ListPrefUpdate update(prefs_, prefs::kPluginsPluginsList); | 397 ListPrefUpdate update(prefs_, prefs::kPluginsPluginsList); |
540 ListValue* plugins_list = update.Get(); | 398 ListValue* plugins_list = update.Get(); |
541 plugins_list->Clear(); | 399 plugins_list->Clear(); |
542 | 400 |
543 FilePath internal_dir; | 401 FilePath internal_dir; |
544 if (PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &internal_dir)) | 402 if (PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &internal_dir)) |
545 prefs_->SetFilePath(prefs::kPluginsLastInternalDirectory, internal_dir); | 403 prefs_->SetFilePath(prefs::kPluginsLastInternalDirectory, internal_dir); |
546 | 404 |
547 base::AutoLock auto_lock(lock_); | 405 // Add the plugin files. |
| 406 for (size_t i = 0; i < plugins.size(); ++i) { |
| 407 DictionaryValue* summary = CreatePluginFileSummary(plugins[i]); |
| 408 // If the plugin is managed by policy, store the user preferred state |
| 409 // instead. |
| 410 if (plugins[i].enabled & webkit::WebPluginInfo::MANAGED_MASK) { |
| 411 bool user_enabled = |
| 412 (plugins[i].enabled & webkit::WebPluginInfo::USER_MASK) == |
| 413 webkit::WebPluginInfo::USER_ENABLED; |
| 414 summary->SetBoolean("enabled", user_enabled); |
| 415 } |
| 416 plugins_list->Append(summary); |
| 417 } |
548 | 418 |
549 // Add the plug-in groups. | 419 // Add the groups as well. |
550 for (size_t i = 0; i < groups.size(); ++i) { | 420 for (size_t i = 0; i < groups.size(); ++i) { |
551 // Add the plugin files to the same list. | 421 DictionaryValue* summary = groups[i].GetSummary(); |
552 const std::vector<webkit::WebPluginInfo>& plugins = | 422 // If the plugin is disabled only by policy don't store this state in the |
553 groups[i].web_plugin_infos(); | 423 // user pref store. |
554 for (size_t j = 0; j < plugins.size(); ++j) { | 424 if (!groups[i].Enabled() && |
555 DictionaryValue* summary = new DictionaryValue(); | 425 webkit::npapi::PluginGroup::IsPluginNameDisabledByPolicy( |
556 summary->SetString("path", plugins[j].path.value()); | 426 groups[i].GetGroupName())) |
557 summary->SetString("name", plugins[j].name); | 427 summary->SetBoolean("enabled", true); |
558 summary->SetString("version", plugins[j].version); | |
559 bool enabled = true; | |
560 std::map<FilePath, bool>::iterator it = | |
561 plugin_state_.find(plugins[j].path); | |
562 if (it != plugin_state_.end()) | |
563 enabled = it->second; | |
564 summary->SetBoolean("enabled", enabled); | |
565 plugins_list->Append(summary); | 428 plugins_list->Append(summary); |
566 } | |
567 | |
568 DictionaryValue* summary = new DictionaryValue(); | |
569 string16 name = groups[i].GetGroupName(); | |
570 summary->SetString("name", name); | |
571 bool enabled = true; | |
572 std::map<string16, bool>::iterator it = | |
573 plugin_group_state_.find(name); | |
574 if (it != plugin_group_state_.end()) | |
575 enabled = it->second; | |
576 summary->SetBoolean("enabled", enabled); | |
577 plugins_list->Append(summary); | |
578 } | 429 } |
579 } | 430 } |
580 | 431 |
581 void PluginPrefs::NotifyPluginStatusChanged() { | 432 void PluginPrefs::NotifyPluginStatusChanged() { |
582 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 433 if (notify_pending_) |
| 434 return; |
| 435 notify_pending_ = true; |
| 436 MessageLoop::current()->PostTask( |
| 437 FROM_HERE, |
| 438 NewRunnableMethod(this, &PluginPrefs::OnNotifyPluginStatusChanged)); |
| 439 } |
| 440 |
| 441 void PluginPrefs::OnNotifyPluginStatusChanged() { |
| 442 notify_pending_ = false; |
583 NotificationService::current()->Notify( | 443 NotificationService::current()->Notify( |
584 chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, | 444 chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, |
585 Source<PluginPrefs>(this), | 445 Source<PluginPrefs>(this), |
586 NotificationService::NoDetails()); | 446 NotificationService::NoDetails()); |
587 } | 447 } |
588 | 448 |
589 /*static*/ | 449 /*static*/ |
590 void PluginPrefs::RegisterPrefs(PrefService* prefs) { | 450 void PluginPrefs::RegisterPrefs(PrefService* prefs) { |
591 FilePath internal_dir; | 451 FilePath internal_dir; |
592 PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &internal_dir); | 452 PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &internal_dir); |
593 prefs->RegisterFilePathPref(prefs::kPluginsLastInternalDirectory, | 453 prefs->RegisterFilePathPref(prefs::kPluginsLastInternalDirectory, |
594 internal_dir, | 454 internal_dir, |
595 PrefService::UNSYNCABLE_PREF); | 455 PrefService::UNSYNCABLE_PREF); |
596 prefs->RegisterBooleanPref(prefs::kPluginsEnabledInternalPDF, | 456 prefs->RegisterBooleanPref(prefs::kPluginsEnabledInternalPDF, |
597 false, | 457 false, |
598 PrefService::UNSYNCABLE_PREF); | 458 PrefService::UNSYNCABLE_PREF); |
599 prefs->RegisterBooleanPref(prefs::kPluginsEnabledNaCl, | 459 prefs->RegisterBooleanPref(prefs::kPluginsEnabledNaCl, |
600 false, | 460 false, |
601 PrefService::UNSYNCABLE_PREF); | 461 PrefService::UNSYNCABLE_PREF); |
602 prefs->RegisterListPref(prefs::kPluginsPluginsList, | 462 prefs->RegisterListPref(prefs::kPluginsPluginsList, |
603 PrefService::UNSYNCABLE_PREF); | 463 PrefService::UNSYNCABLE_PREF); |
604 prefs->RegisterListPref(prefs::kPluginsDisabledPlugins, | 464 prefs->RegisterListPref(prefs::kPluginsDisabledPlugins, |
605 PrefService::UNSYNCABLE_PREF); | 465 PrefService::UNSYNCABLE_PREF); |
606 prefs->RegisterListPref(prefs::kPluginsDisabledPluginsExceptions, | 466 prefs->RegisterListPref(prefs::kPluginsDisabledPluginsExceptions, |
607 PrefService::UNSYNCABLE_PREF); | 467 PrefService::UNSYNCABLE_PREF); |
608 prefs->RegisterListPref(prefs::kPluginsEnabledPlugins, | 468 prefs->RegisterListPref(prefs::kPluginsEnabledPlugins, |
609 PrefService::UNSYNCABLE_PREF); | 469 PrefService::UNSYNCABLE_PREF); |
610 } | 470 } |
OLD | NEW |