[email protected] | f8c85dd | 2012-01-12 02:26:43 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 5 | #include "chrome/browser/plugin_prefs.h" |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 6 | |
| 7 | #include <string> |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 8 | |
[email protected] | ff4fa71 | 2011-09-28 22:05:13 | [diff] [blame] | 9 | #include "base/bind.h" |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 10 | #include "base/command_line.h" |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 11 | #include "base/lazy_instance.h" |
[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 12 | #include "base/memory/scoped_ptr.h" |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 13 | #include "base/memory/singleton.h" |
[email protected] | a446a53 | 2010-10-11 17:24:52 | [diff] [blame] | 14 | #include "base/message_loop.h" |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 15 | #include "base/path_service.h" |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 16 | #include "base/string_util.h" |
[email protected] | cceaf85 | 2010-10-07 22:01:13 | [diff] [blame] | 17 | #include "base/utf_string_conversions.h" |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 18 | #include "base/values.h" |
[email protected] | daf66aa | 2010-08-06 06:24:28 | [diff] [blame] | 19 | #include "base/version.h" |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 20 | #include "chrome/browser/browser_process.h" |
[email protected] | a42f2e2 | 2011-10-10 22:28:17 | [diff] [blame] | 21 | #include "chrome/browser/plugin_prefs_factory.h" |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 22 | #include "chrome/browser/prefs/scoped_user_pref_update.h" |
[email protected] | 8ecad5e | 2010-12-02 21:18:33 | [diff] [blame] | 23 | #include "chrome/browser/profiles/profile.h" |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 24 | #include "chrome/browser/profiles/profile_keyed_service.h" |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 25 | #include "chrome/browser/profiles/profile_manager.h" |
[email protected] | cebc3dc | 2011-04-18 17:15:00 | [diff] [blame] | 26 | #include "chrome/common/chrome_content_client.h" |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 27 | #include "chrome/common/chrome_notification_types.h" |
[email protected] | ed17c7b | 2010-07-14 12:03:33 | [diff] [blame] | 28 | #include "chrome/common/chrome_paths.h" |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 29 | #include "chrome/common/chrome_switches.h" |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 30 | #include "chrome/common/pref_names.h" |
[email protected] | c38831a1 | 2011-10-28 12:44:49 | [diff] [blame] | 31 | #include "content/public/browser/browser_thread.h" |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 32 | #include "content/public/browser/notification_service.h" |
[email protected] | 3a5180ae | 2011-12-21 02:39:38 | [diff] [blame] | 33 | #include "content/public/browser/plugin_service.h" |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 34 | #include "webkit/plugins/npapi/plugin_group.h" |
[email protected] | 191eb3f7 | 2010-12-21 06:27:50 | [diff] [blame] | 35 | #include "webkit/plugins/npapi/plugin_list.h" |
[email protected] | 91d9f3d | 2011-08-14 05:24:44 | [diff] [blame] | 36 | #include "webkit/plugins/webplugininfo.h" |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 37 | |
[email protected] | 631bb74 | 2011-11-02 11:29:39 | [diff] [blame] | 38 | using content::BrowserThread; |
[email protected] | 3a5180ae | 2011-12-21 02:39:38 | [diff] [blame] | 39 | using content::PluginService; |
[email protected] | 631bb74 | 2011-11-02 11:29:39 | [diff] [blame] | 40 | |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 41 | namespace { |
| 42 | |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 43 | // Default state for a plug-in (not state of the default plug-in!). |
| 44 | // Accessed only on the UI thread. |
[email protected] | 6de0fd1d | 2011-11-15 13:31:49 | [diff] [blame] | 45 | base::LazyInstance<std::map<FilePath, bool> > g_default_plugin_state = |
| 46 | LAZY_INSTANCE_INITIALIZER; |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 47 | |
[email protected] | a42f2e2 | 2011-10-10 22:28:17 | [diff] [blame] | 48 | } // namespace |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 49 | |
[email protected] | 41a9a3d | 2010-10-27 19:25:43 | [diff] [blame] | 50 | // How long to wait to save the plugin enabled information, which might need to |
| 51 | // go to disk. |
| 52 | #define kPluginUpdateDelayMs (60 * 1000) |
| 53 | |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 54 | // static |
| 55 | PluginPrefs* PluginPrefs::GetForProfile(Profile* profile) { |
[email protected] | 476a2703 | 2011-09-13 13:40:49 | [diff] [blame] | 56 | PluginPrefsWrapper* wrapper = |
[email protected] | a42f2e2 | 2011-10-10 22:28:17 | [diff] [blame] | 57 | PluginPrefsFactory::GetInstance()->GetWrapperForProfile(profile); |
[email protected] | 476a2703 | 2011-09-13 13:40:49 | [diff] [blame] | 58 | if (!wrapper) |
| 59 | return NULL; |
| 60 | return wrapper->plugin_prefs(); |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 61 | } |
| 62 | |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 63 | // static |
| 64 | PluginPrefs* PluginPrefs::GetForTestingProfile(Profile* profile) { |
| 65 | ProfileKeyedService* wrapper = |
[email protected] | a42f2e2 | 2011-10-10 22:28:17 | [diff] [blame] | 66 | PluginPrefsFactory::GetInstance()->SetTestingFactoryAndUse( |
| 67 | profile, &PluginPrefsFactory::CreateWrapperForProfile); |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 68 | return static_cast<PluginPrefsWrapper*>(wrapper)->plugin_prefs(); |
[email protected] | ed17c7b | 2010-07-14 12:03:33 | [diff] [blame] | 69 | } |
| 70 | |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 71 | void PluginPrefs::SetPluginListForTesting( |
| 72 | webkit::npapi::PluginList* plugin_list) { |
| 73 | plugin_list_ = plugin_list; |
| 74 | } |
| 75 | |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 76 | void PluginPrefs::EnablePluginGroup(bool enabled, const string16& group_name) { |
[email protected] | 183d4b8 | 2011-11-11 18:50:26 | [diff] [blame] | 77 | PluginService::GetInstance()->GetPluginGroups( |
| 78 | base::Bind(&PluginPrefs::EnablePluginGroupInternal, |
| 79 | this, enabled, group_name)); |
| 80 | } |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 81 | |
[email protected] | 183d4b8 | 2011-11-11 18:50:26 | [diff] [blame] | 82 | void PluginPrefs::EnablePluginGroupInternal( |
| 83 | bool enabled, |
| 84 | const string16& group_name, |
| 85 | const std::vector<webkit::npapi::PluginGroup>& groups) { |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 86 | base::AutoLock auto_lock(lock_); |
| 87 | |
| 88 | // Set the desired state for the group. |
| 89 | plugin_group_state_[group_name] = enabled; |
| 90 | |
| 91 | // Update the state for all plug-ins in the group. |
| 92 | for (size_t i = 0; i < groups.size(); ++i) { |
| 93 | if (groups[i].GetGroupName() != group_name) |
| 94 | continue; |
| 95 | const std::vector<webkit::WebPluginInfo>& plugins = |
| 96 | groups[i].web_plugin_infos(); |
| 97 | for (size_t j = 0; j < plugins.size(); ++j) |
| 98 | plugin_state_[plugins[j].path] = enabled; |
| 99 | break; |
| 100 | } |
| 101 | |
| 102 | BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
[email protected] | ff4fa71 | 2011-09-28 22:05:13 | [diff] [blame] | 103 | base::Bind(&PluginPrefs::OnUpdatePreferences, this, groups)); |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 104 | BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
[email protected] | ff4fa71 | 2011-09-28 22:05:13 | [diff] [blame] | 105 | base::Bind(&PluginPrefs::NotifyPluginStatusChanged, this)); |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 106 | } |
| 107 | |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 108 | bool PluginPrefs::EnablePlugin(bool enabled, const FilePath& path) { |
| 109 | // Do policy checks first. These don't need to run on the FILE thread. |
| 110 | webkit::npapi::PluginList* plugin_list = GetPluginList(); |
| 111 | webkit::WebPluginInfo plugin; |
[email protected] | 88ca491 | 2011-10-12 14:00:43 | [diff] [blame] | 112 | if (PluginService::GetInstance()->GetPluginInfoByPath(path, &plugin)) { |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 113 | scoped_ptr<webkit::npapi::PluginGroup> group( |
| 114 | plugin_list->GetPluginGroup(plugin)); |
| 115 | PolicyStatus plugin_status = PolicyStatusForPlugin(plugin.name); |
| 116 | PolicyStatus group_status = PolicyStatusForPlugin(group->GetGroupName()); |
| 117 | if (enabled) { |
| 118 | if (plugin_status == POLICY_DISABLED || group_status == POLICY_DISABLED) |
| 119 | return false; |
| 120 | } else { |
| 121 | if (plugin_status == POLICY_ENABLED || group_status == POLICY_ENABLED) |
| 122 | return false; |
| 123 | } |
| 124 | } |
| 125 | |
[email protected] | 183d4b8 | 2011-11-11 18:50:26 | [diff] [blame] | 126 | PluginService::GetInstance()->GetPluginGroups( |
| 127 | base::Bind(&PluginPrefs::EnablePluginInternal, this, enabled, path)); |
[email protected] | ff4fa71 | 2011-09-28 22:05:13 | [diff] [blame] | 128 | return true; |
| 129 | } |
[email protected] | 492d214 | 2010-09-10 13:55:18 | [diff] [blame] | 130 | |
[email protected] | 183d4b8 | 2011-11-11 18:50:26 | [diff] [blame] | 131 | void PluginPrefs::EnablePluginInternal( |
| 132 | bool enabled, |
| 133 | const FilePath& path, |
| 134 | const std::vector<webkit::npapi::PluginGroup>& groups) { |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 135 | { |
| 136 | // Set the desired state for the plug-in. |
| 137 | base::AutoLock auto_lock(lock_); |
| 138 | plugin_state_[path] = enabled; |
| 139 | } |
| 140 | |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 141 | bool found_group = false; |
| 142 | for (size_t i = 0; i < groups.size(); ++i) { |
| 143 | bool all_disabled = true; |
| 144 | const std::vector<webkit::WebPluginInfo>& plugins = |
| 145 | groups[i].web_plugin_infos(); |
| 146 | for (size_t j = 0; j < plugins.size(); ++j) { |
| 147 | all_disabled = all_disabled && !IsPluginEnabled(plugins[j]); |
| 148 | if (plugins[j].path == path) { |
| 149 | found_group = true; |
| 150 | DCHECK_EQ(enabled, IsPluginEnabled(plugins[j])); |
| 151 | } |
| 152 | } |
| 153 | if (found_group) { |
| 154 | // Update the state for the corresponding plug-in group. |
| 155 | base::AutoLock auto_lock(lock_); |
| 156 | plugin_group_state_[groups[i].GetGroupName()] = !all_disabled; |
| 157 | break; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
[email protected] | ff4fa71 | 2011-09-28 22:05:13 | [diff] [blame] | 162 | base::Bind(&PluginPrefs::OnUpdatePreferences, this, groups)); |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 163 | BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
[email protected] | ff4fa71 | 2011-09-28 22:05:13 | [diff] [blame] | 164 | base::Bind(&PluginPrefs::NotifyPluginStatusChanged, this)); |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 165 | } |
| 166 | |
| 167 | // static |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 168 | bool PluginPrefs::EnablePluginGlobally(bool enable, const FilePath& file_path) { |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 169 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 170 | g_default_plugin_state.Get()[file_path] = enable; |
| 171 | std::vector<Profile*> profiles = |
| 172 | g_browser_process->profile_manager()->GetLoadedProfiles(); |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 173 | bool result = true; |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 174 | for (std::vector<Profile*>::iterator it = profiles.begin(); |
| 175 | it != profiles.end(); ++it) { |
| 176 | PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(*it); |
| 177 | DCHECK(plugin_prefs); |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 178 | if (!plugin_prefs->EnablePlugin(enable, file_path)) |
| 179 | result = false; |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 180 | } |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 181 | return result; |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 182 | } |
| 183 | |
| 184 | PluginPrefs::PolicyStatus PluginPrefs::PolicyStatusForPlugin( |
[email protected] | f8c85dd | 2012-01-12 02:26:43 | [diff] [blame] | 185 | const string16& name) const { |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 186 | base::AutoLock auto_lock(lock_); |
| 187 | if (IsStringMatchedInSet(name, policy_enabled_plugin_patterns_)) { |
| 188 | return POLICY_ENABLED; |
| 189 | } else if (IsStringMatchedInSet(name, policy_disabled_plugin_patterns_) && |
| 190 | !IsStringMatchedInSet( |
| 191 | name, policy_disabled_plugin_exception_patterns_)) { |
| 192 | return POLICY_DISABLED; |
| 193 | } else { |
| 194 | return NO_POLICY; |
| 195 | } |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 196 | } |
| 197 | |
[email protected] | f8c85dd | 2012-01-12 02:26:43 | [diff] [blame] | 198 | bool PluginPrefs::IsPluginEnabled(const webkit::WebPluginInfo& plugin) const { |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 199 | scoped_ptr<webkit::npapi::PluginGroup> group( |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 200 | GetPluginList()->GetPluginGroup(plugin)); |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 201 | string16 group_name = group->GetGroupName(); |
| 202 | |
| 203 | // Check if the plug-in or its group is enabled by policy. |
| 204 | PolicyStatus plugin_status = PolicyStatusForPlugin(plugin.name); |
| 205 | PolicyStatus group_status = PolicyStatusForPlugin(group_name); |
| 206 | if (plugin_status == POLICY_ENABLED || group_status == POLICY_ENABLED) |
| 207 | return true; |
| 208 | |
| 209 | // Check if the plug-in or its group is disabled by policy. |
| 210 | if (plugin_status == POLICY_DISABLED || group_status == POLICY_DISABLED) |
| 211 | return false; |
| 212 | |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 213 | // If enabling NaCl, make sure the plugin is also enabled. See bug |
| 214 | // http://code.google.com/p/chromium/issues/detail?id=81010 for more |
| 215 | // information. |
| 216 | // TODO(dspringer): When NaCl is on by default, remove this code. |
| 217 | if ((plugin.name == |
| 218 | ASCIIToUTF16(chrome::ChromeContentClient::kNaClPluginName)) && |
| 219 | CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaCl)) { |
| 220 | return true; |
| 221 | } |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 222 | |
| 223 | base::AutoLock auto_lock(lock_); |
| 224 | // Check user preferences for the plug-in. |
[email protected] | f8c85dd | 2012-01-12 02:26:43 | [diff] [blame] | 225 | std::map<FilePath, bool>::const_iterator plugin_it = |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 226 | plugin_state_.find(plugin.path); |
| 227 | if (plugin_it != plugin_state_.end()) |
| 228 | return plugin_it->second; |
| 229 | |
| 230 | // Check user preferences for the plug-in group. |
[email protected] | f8c85dd | 2012-01-12 02:26:43 | [diff] [blame] | 231 | std::map<string16, bool>::const_iterator group_it( |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 232 | plugin_group_state_.find(plugin.name)); |
| 233 | if (group_it != plugin_group_state_.end()) |
| 234 | return group_it->second; |
| 235 | |
| 236 | // Default to enabled. |
| 237 | return true; |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 238 | } |
| 239 | |
| 240 | void PluginPrefs::Observe(int type, |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 241 | const content::NotificationSource& source, |
| 242 | const content::NotificationDetails& details) { |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 243 | DCHECK_EQ(chrome::NOTIFICATION_PREF_CHANGED, type); |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 244 | const std::string* pref_name = content::Details<std::string>(details).ptr(); |
[email protected] | 492d214 | 2010-09-10 13:55:18 | [diff] [blame] | 245 | if (!pref_name) { |
| 246 | NOTREACHED(); |
| 247 | return; |
| 248 | } |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 249 | DCHECK_EQ(prefs_, content::Source<PrefService>(source).ptr()); |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 250 | if (*pref_name == prefs::kPluginsDisabledPlugins) { |
| 251 | base::AutoLock auto_lock(lock_); |
| 252 | ListValueToStringSet(prefs_->GetList(prefs::kPluginsDisabledPlugins), |
| 253 | &policy_disabled_plugin_patterns_); |
| 254 | } else if (*pref_name == prefs::kPluginsDisabledPluginsExceptions) { |
| 255 | base::AutoLock auto_lock(lock_); |
| 256 | ListValueToStringSet( |
| 257 | prefs_->GetList(prefs::kPluginsDisabledPluginsExceptions), |
| 258 | &policy_disabled_plugin_exception_patterns_); |
| 259 | } else if (*pref_name == prefs::kPluginsEnabledPlugins) { |
| 260 | base::AutoLock auto_lock(lock_); |
| 261 | ListValueToStringSet(prefs_->GetList(prefs::kPluginsEnabledPlugins), |
| 262 | &policy_enabled_plugin_patterns_); |
| 263 | } else { |
| 264 | NOTREACHED(); |
[email protected] | 492d214 | 2010-09-10 13:55:18 | [diff] [blame] | 265 | } |
[email protected] | a446a53 | 2010-10-11 17:24:52 | [diff] [blame] | 266 | NotifyPluginStatusChanged(); |
[email protected] | 492d214 | 2010-09-10 13:55:18 | [diff] [blame] | 267 | } |
| 268 | |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 269 | /*static*/ |
| 270 | bool PluginPrefs::IsStringMatchedInSet(const string16& name, |
| 271 | const std::set<string16>& pattern_set) { |
| 272 | std::set<string16>::const_iterator pattern(pattern_set.begin()); |
| 273 | while (pattern != pattern_set.end()) { |
| 274 | if (MatchPattern(name, *pattern)) |
| 275 | return true; |
| 276 | ++pattern; |
| 277 | } |
| 278 | |
| 279 | return false; |
| 280 | } |
| 281 | |
| 282 | /* static */ |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 283 | void PluginPrefs::ListValueToStringSet(const ListValue* src, |
| 284 | std::set<string16>* dest) { |
[email protected] | 24ff43d7 | 2011-03-01 13:28:58 | [diff] [blame] | 285 | DCHECK(src); |
| 286 | DCHECK(dest); |
| 287 | ListValue::const_iterator end(src->end()); |
| 288 | for (ListValue::const_iterator current(src->begin()); |
| 289 | current != end; ++current) { |
| 290 | string16 plugin_name; |
| 291 | if ((*current)->GetAsString(&plugin_name)) { |
| 292 | dest->insert(plugin_name); |
| 293 | } |
| 294 | } |
| 295 | } |
| 296 | |
[email protected] | e0379d5 | 2011-09-02 20:08:47 | [diff] [blame] | 297 | void PluginPrefs::SetPrefs(PrefService* prefs) { |
| 298 | prefs_ = prefs; |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 299 | bool update_internal_dir = false; |
| 300 | FilePath last_internal_dir = |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 301 | prefs_->GetFilePath(prefs::kPluginsLastInternalDirectory); |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 302 | FilePath cur_internal_dir; |
| 303 | if (PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &cur_internal_dir) && |
| 304 | cur_internal_dir != last_internal_dir) { |
| 305 | update_internal_dir = true; |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 306 | prefs_->SetFilePath( |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 307 | prefs::kPluginsLastInternalDirectory, cur_internal_dir); |
| 308 | } |
| 309 | |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 310 | bool force_enable_internal_pdf = false; |
[email protected] | 47a87ca | 2011-02-14 18:54:39 | [diff] [blame] | 311 | bool internal_pdf_enabled = false; |
[email protected] | cebc3dc | 2011-04-18 17:15:00 | [diff] [blame] | 312 | string16 pdf_group_name = |
| 313 | ASCIIToUTF16(chrome::ChromeContentClient::kPDFPluginName); |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 314 | FilePath pdf_path; |
| 315 | PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_path); |
| 316 | FilePath::StringType pdf_path_str = pdf_path.value(); |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 317 | if (!prefs_->GetBoolean(prefs::kPluginsEnabledInternalPDF)) { |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 318 | // We switched to the internal pdf plugin being on by default, and so we |
| 319 | // need to force it to be enabled. We only want to do it this once though, |
| 320 | // i.e. we don't want to enable it again if the user disables it afterwards. |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 321 | prefs_->SetBoolean(prefs::kPluginsEnabledInternalPDF, true); |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 322 | force_enable_internal_pdf = true; |
| 323 | } |
| 324 | |
[email protected] | aa6a3933 | 2011-08-26 01:22:49 | [diff] [blame] | 325 | bool force_enable_nacl = false; |
| 326 | string16 nacl_group_name = |
| 327 | ASCIIToUTF16(chrome::ChromeContentClient::kNaClPluginName); |
| 328 | // Since the NaCl Plugin changed names between Chrome 13 and 14, we need to |
| 329 | // check for both because either could be stored as the plugin group name. |
| 330 | string16 old_nacl_group_name = |
| 331 | ASCIIToUTF16(chrome::ChromeContentClient::kNaClOldPluginName); |
| 332 | FilePath nacl_path; |
| 333 | PathService::Get(chrome::FILE_NACL_PLUGIN, &nacl_path); |
| 334 | FilePath::StringType nacl_path_str = nacl_path.value(); |
| 335 | if (!prefs_->GetBoolean(prefs::kPluginsEnabledNaCl)) { |
| 336 | // We switched to the nacl plugin being on by default, and so we need to |
| 337 | // force it to be enabled. We only want to do it this once though, i.e. |
| 338 | // we don't want to enable it again if the user disables it afterwards. |
| 339 | prefs_->SetBoolean(prefs::kPluginsEnabledNaCl, true); |
| 340 | force_enable_nacl = true; |
| 341 | } |
| 342 | |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 343 | { // Scoped update of prefs::kPluginsPluginsList. |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 344 | ListPrefUpdate update(prefs_, prefs::kPluginsPluginsList); |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 345 | ListValue* saved_plugins_list = update.Get(); |
[email protected] | a027e51 | 2011-06-21 03:57:05 | [diff] [blame] | 346 | if (saved_plugins_list && !saved_plugins_list->empty()) { |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 347 | for (ListValue::const_iterator it = saved_plugins_list->begin(); |
| 348 | it != saved_plugins_list->end(); |
| 349 | ++it) { |
| 350 | if (!(*it)->IsType(Value::TYPE_DICTIONARY)) { |
| 351 | LOG(WARNING) << "Invalid entry in " << prefs::kPluginsPluginsList; |
| 352 | continue; // Oops, don't know what to do with this item. |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 353 | } |
| 354 | |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 355 | DictionaryValue* plugin = static_cast<DictionaryValue*>(*it); |
| 356 | string16 group_name; |
[email protected] | 4c4eb778 | 2011-06-22 07:51:58 | [diff] [blame] | 357 | bool enabled; |
| 358 | if (!plugin->GetBoolean("enabled", &enabled)) |
| 359 | enabled = true; |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 360 | |
| 361 | FilePath::StringType path; |
| 362 | // The plugin list constains all the plugin files in addition to the |
| 363 | // plugin groups. |
| 364 | if (plugin->GetString("path", &path)) { |
| 365 | // Files have a path attribute, groups don't. |
| 366 | FilePath plugin_path(path); |
| 367 | if (update_internal_dir && |
| 368 | FilePath::CompareIgnoreCase(plugin_path.DirName().value(), |
| 369 | last_internal_dir.value()) == 0) { |
| 370 | // If the internal plugin directory has changed and if the plugin |
| 371 | // looks internal, update its path in the prefs. |
| 372 | plugin_path = cur_internal_dir.Append(plugin_path.BaseName()); |
| 373 | path = plugin_path.value(); |
| 374 | plugin->SetString("path", path); |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 375 | } |
[email protected] | 47a87ca | 2011-02-14 18:54:39 | [diff] [blame] | 376 | |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 377 | if (FilePath::CompareIgnoreCase(path, pdf_path_str) == 0) { |
| 378 | if (!enabled && force_enable_internal_pdf) { |
| 379 | enabled = true; |
| 380 | plugin->SetBoolean("enabled", true); |
| 381 | } |
| 382 | |
| 383 | internal_pdf_enabled = enabled; |
[email protected] | aa6a3933 | 2011-08-26 01:22:49 | [diff] [blame] | 384 | } else if (FilePath::CompareIgnoreCase(path, nacl_path_str) == 0) { |
| 385 | if (!enabled && force_enable_nacl) { |
| 386 | enabled = true; |
| 387 | plugin->SetBoolean("enabled", true); |
| 388 | } |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 389 | } |
| 390 | |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 391 | plugin_state_[plugin_path] = enabled; |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 392 | } else if (!enabled && plugin->GetString("name", &group_name)) { |
[email protected] | aa6a3933 | 2011-08-26 01:22:49 | [diff] [blame] | 393 | // Don't disable this group if it's for the pdf or nacl plugins and |
| 394 | // we just forced it on. |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 395 | if (force_enable_internal_pdf && pdf_group_name == group_name) |
| 396 | continue; |
[email protected] | aa6a3933 | 2011-08-26 01:22:49 | [diff] [blame] | 397 | if (force_enable_nacl && (nacl_group_name == group_name || |
| 398 | old_nacl_group_name == group_name)) |
| 399 | continue; |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 400 | |
| 401 | // Otherwise this is a list of groups. |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 402 | plugin_group_state_[group_name] = false; |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 403 | } |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 404 | } |
[email protected] | a027e51 | 2011-06-21 03:57:05 | [diff] [blame] | 405 | } else { |
| 406 | // If the saved plugin list is empty, then the call to UpdatePreferences() |
| 407 | // below failed in an earlier run, possibly because the user closed the |
[email protected] | aa6a3933 | 2011-08-26 01:22:49 | [diff] [blame] | 408 | // browser too quickly. Try to force enable the internal PDF and nacl |
| 409 | // plugins again. |
[email protected] | a027e51 | 2011-06-21 03:57:05 | [diff] [blame] | 410 | force_enable_internal_pdf = true; |
[email protected] | aa6a3933 | 2011-08-26 01:22:49 | [diff] [blame] | 411 | force_enable_nacl = true; |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 412 | } |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 413 | } // Scoped update of prefs::kPluginsPluginsList. |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 414 | |
[email protected] | 24ff43d7 | 2011-03-01 13:28:58 | [diff] [blame] | 415 | // Build the set of policy enabled/disabled plugin patterns once and cache it. |
[email protected] | e541d9f | 2010-07-15 16:04:49 | [diff] [blame] | 416 | // Don't do this in the constructor, there's no profile available there. |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 417 | ListValueToStringSet(prefs_->GetList(prefs::kPluginsDisabledPlugins), |
| 418 | &policy_disabled_plugin_patterns_); |
| 419 | ListValueToStringSet( |
| 420 | prefs_->GetList(prefs::kPluginsDisabledPluginsExceptions), |
| 421 | &policy_disabled_plugin_exception_patterns_); |
| 422 | ListValueToStringSet(prefs_->GetList(prefs::kPluginsEnabledPlugins), |
| 423 | &policy_enabled_plugin_patterns_); |
[email protected] | e541d9f | 2010-07-15 16:04:49 | [diff] [blame] | 424 | |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 425 | registrar_.Init(prefs_); |
[email protected] | 732d5af | 2011-04-28 11:36:30 | [diff] [blame] | 426 | registrar_.Add(prefs::kPluginsDisabledPlugins, this); |
| 427 | registrar_.Add(prefs::kPluginsDisabledPluginsExceptions, this); |
| 428 | registrar_.Add(prefs::kPluginsEnabledPlugins, this); |
| 429 | |
[email protected] | 47a87ca | 2011-02-14 18:54:39 | [diff] [blame] | 430 | if (force_enable_internal_pdf || internal_pdf_enabled) { |
[email protected] | a446a53 | 2010-10-11 17:24:52 | [diff] [blame] | 431 | // See http://crbug.com/50105 for background. |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 432 | plugin_group_state_[ASCIIToUTF16( |
| 433 | webkit::npapi::PluginGroup::kAdobeReaderGroupName)] = false; |
[email protected] | 47a87ca | 2011-02-14 18:54:39 | [diff] [blame] | 434 | } |
[email protected] | 41a9a3d | 2010-10-27 19:25:43 | [diff] [blame] | 435 | |
[email protected] | aa6a3933 | 2011-08-26 01:22:49 | [diff] [blame] | 436 | if (force_enable_internal_pdf || force_enable_nacl) { |
[email protected] | 41a9a3d | 2010-10-27 19:25:43 | [diff] [blame] | 437 | // We want to save this, but doing so requires loading the list of plugins, |
| 438 | // so do it after a minute as to not impact startup performance. Note that |
| 439 | // plugins are loaded after 30s by the metrics service. |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 440 | BrowserThread::PostDelayedTask( |
| 441 | BrowserThread::FILE, |
| 442 | FROM_HERE, |
[email protected] | ff4fa71 | 2011-09-28 22:05:13 | [diff] [blame] | 443 | base::Bind(&PluginPrefs::GetPreferencesDataOnFileThread, this), |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 444 | kPluginUpdateDelayMs); |
[email protected] | a446a53 | 2010-10-11 17:24:52 | [diff] [blame] | 445 | } |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 446 | |
| 447 | NotifyPluginStatusChanged(); |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 448 | } |
| 449 | |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 450 | void PluginPrefs::ShutdownOnUIThread() { |
| 451 | prefs_ = NULL; |
[email protected] | 732d5af | 2011-04-28 11:36:30 | [diff] [blame] | 452 | registrar_.RemoveAll(); |
| 453 | } |
| 454 | |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 455 | PluginPrefs::PluginPrefs() : plugin_state_(g_default_plugin_state.Get()), |
[email protected] | 45a22e6 | 2011-10-12 09:48:02 | [diff] [blame] | 456 | profile_(NULL), |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 457 | prefs_(NULL), |
| 458 | plugin_list_(NULL) { |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 459 | } |
| 460 | |
| 461 | PluginPrefs::~PluginPrefs() { |
| 462 | } |
| 463 | |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 464 | void PluginPrefs::SetPolicyEnforcedPluginPatterns( |
| 465 | const std::set<string16>& disabled_patterns, |
| 466 | const std::set<string16>& disabled_exception_patterns, |
| 467 | const std::set<string16>& enabled_patterns) { |
| 468 | policy_disabled_plugin_patterns_ = disabled_patterns; |
| 469 | policy_disabled_plugin_exception_patterns_ = disabled_exception_patterns; |
| 470 | policy_enabled_plugin_patterns_ = enabled_patterns; |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 471 | } |
| 472 | |
[email protected] | f8c85dd | 2012-01-12 02:26:43 | [diff] [blame] | 473 | webkit::npapi::PluginList* PluginPrefs::GetPluginList() const { |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 474 | if (plugin_list_) |
| 475 | return plugin_list_; |
[email protected] | 3a5180ae | 2011-12-21 02:39:38 | [diff] [blame] | 476 | return PluginService::GetInstance()->GetPluginList(); |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 477 | } |
| 478 | |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 479 | void PluginPrefs::GetPreferencesDataOnFileThread() { |
[email protected] | 191eb3f7 | 2010-12-21 06:27:50 | [diff] [blame] | 480 | std::vector<webkit::npapi::PluginGroup> groups; |
[email protected] | a446a53 | 2010-10-11 17:24:52 | [diff] [blame] | 481 | |
[email protected] | 672b2c6f | 2011-09-27 02:34:25 | [diff] [blame] | 482 | webkit::npapi::PluginList* plugin_list = GetPluginList(); |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 483 | plugin_list->GetPluginGroups(false, &groups); |
| 484 | |
| 485 | BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
[email protected] | ff4fa71 | 2011-09-28 22:05:13 | [diff] [blame] | 486 | base::Bind(&PluginPrefs::OnUpdatePreferences, this, groups)); |
[email protected] | a446a53 | 2010-10-11 17:24:52 | [diff] [blame] | 487 | } |
| 488 | |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 489 | void PluginPrefs::OnUpdatePreferences( |
[email protected] | 35635b2b | 2012-01-24 21:44:41 | [diff] [blame] | 490 | const std::vector<webkit::npapi::PluginGroup>& groups) { |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 491 | if (!prefs_) |
| 492 | return; |
| 493 | |
| 494 | ListPrefUpdate update(prefs_, prefs::kPluginsPluginsList); |
[email protected] | 805cd37 | 2011-04-04 12:39:56 | [diff] [blame] | 495 | ListValue* plugins_list = update.Get(); |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 496 | plugins_list->Clear(); |
| 497 | |
| 498 | FilePath internal_dir; |
| 499 | if (PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &internal_dir)) |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 500 | prefs_->SetFilePath(prefs::kPluginsLastInternalDirectory, internal_dir); |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 501 | |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 502 | base::AutoLock auto_lock(lock_); |
[email protected] | 3eff9e2 | 2011-09-15 09:42:23 | [diff] [blame] | 503 | |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 504 | // Add the plug-in groups. |
[email protected] | 3eff9e2 | 2011-09-15 09:42:23 | [diff] [blame] | 505 | for (size_t i = 0; i < groups.size(); ++i) { |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 506 | // Add the plugin files to the same list. |
| 507 | const std::vector<webkit::WebPluginInfo>& plugins = |
| 508 | groups[i].web_plugin_infos(); |
| 509 | for (size_t j = 0; j < plugins.size(); ++j) { |
| 510 | DictionaryValue* summary = new DictionaryValue(); |
| 511 | summary->SetString("path", plugins[j].path.value()); |
| 512 | summary->SetString("name", plugins[j].name); |
| 513 | summary->SetString("version", plugins[j].version); |
| 514 | bool enabled = true; |
| 515 | std::map<FilePath, bool>::iterator it = |
| 516 | plugin_state_.find(plugins[j].path); |
| 517 | if (it != plugin_state_.end()) |
| 518 | enabled = it->second; |
| 519 | summary->SetBoolean("enabled", enabled); |
[email protected] | 3eff9e2 | 2011-09-15 09:42:23 | [diff] [blame] | 520 | plugins_list->Append(summary); |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 521 | } |
| 522 | |
| 523 | DictionaryValue* summary = new DictionaryValue(); |
| 524 | string16 name = groups[i].GetGroupName(); |
| 525 | summary->SetString("name", name); |
| 526 | bool enabled = true; |
| 527 | std::map<string16, bool>::iterator it = |
| 528 | plugin_group_state_.find(name); |
| 529 | if (it != plugin_group_state_.end()) |
| 530 | enabled = it->second; |
| 531 | summary->SetBoolean("enabled", enabled); |
| 532 | plugins_list->Append(summary); |
[email protected] | 3eff9e2 | 2011-09-15 09:42:23 | [diff] [blame] | 533 | } |
[email protected] | 0a8b1e2 | 2010-07-02 09:31:11 | [diff] [blame] | 534 | } |
[email protected] | ed17c7b | 2010-07-14 12:03:33 | [diff] [blame] | 535 | |
[email protected] | 8a271368 | 2011-08-19 10:36:59 | [diff] [blame] | 536 | void PluginPrefs::NotifyPluginStatusChanged() { |
[email protected] | f7be2cba | 2011-09-15 15:33:45 | [diff] [blame] | 537 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 538 | content::NotificationService::current()->Notify( |
[email protected] | dfba876 | 2011-09-02 12:49:54 | [diff] [blame] | 539 | chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 540 | content::Source<Profile>(profile_), |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 541 | content::NotificationService::NoDetails()); |
[email protected] | a446a53 | 2010-10-11 17:24:52 | [diff] [blame] | 542 | } |