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. 4 5 #include "chrome/browser/plugins/plugin_prefs.h" 6 7 #include "base/at_exit.h" 8 #include "base/bind.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/path_service.h" 11 #include "base/run_loop.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "chrome/common/chrome_constants.h" 14 #include "chrome/common/chrome_paths.h" 15 #include "content/public/browser/plugin_service.h" 16 #include "content/public/browser/render_process_host.h" 17 #include "content/public/common/webplugininfo.h" 18 #include "content/public/test/test_browser_thread.h" 19 #include "content/public/test/test_utils.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 22 using content::BrowserThread; 23 using content::PluginService; 24 25 namespace { 26 27 void CanEnablePluginCallback(const base::Closure& quit_closure, 28 bool expected_can_change, 29 bool did_change) { 30 EXPECT_EQ(expected_can_change, did_change); 31 quit_closure.Run(); 32 } 33 34 #if !(defined(OS_LINUX) && defined(USE_AURA)) 35 base::FilePath GetComponentUpdatedPepperFlashPath( 36 const base::FilePath::StringType& version) { 37 base::FilePath path; 38 EXPECT_TRUE(PathService::Get( 39 chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, &path)); 40 path = path.Append(version); 41 path = path.Append(chrome::kPepperFlashPluginFilename); 42 return path; 43 } 44 45 base::FilePath GetBundledPepperFlashPath() { 46 base::FilePath path; 47 EXPECT_TRUE(PathService::Get(chrome::FILE_PEPPER_FLASH_PLUGIN, &path)); 48 return path; 49 } 50 #endif // !(defined(OS_LINUX) && defined(USE_AURA)) 51 52 void GotPlugins(const base::Closure& quit_closure, 53 const std::vector<content::WebPluginInfo>& plugins) { 54 quit_closure.Run(); 55 } 56 57 } // namespace 58 59 class PluginPrefsTest : public ::testing::Test { 60 public: 61 virtual void SetUp() OVERRIDE { 62 plugin_prefs_ = new PluginPrefs(); 63 } 64 65 void SetPolicyEnforcedPluginPatterns( 66 const std::set<base::string16>& disabled, 67 const std::set<base::string16>& disabled_exceptions, 68 const std::set<base::string16>& enabled) { 69 plugin_prefs_->SetPolicyEnforcedPluginPatterns( 70 disabled, disabled_exceptions, enabled); 71 } 72 73 protected: 74 void EnablePluginSynchronously(bool enabled, 75 const base::FilePath& path, 76 bool expected_can_change) { 77 base::RunLoop run_loop; 78 plugin_prefs_->EnablePlugin( 79 enabled, path, 80 base::Bind(&CanEnablePluginCallback, run_loop.QuitClosure(), 81 expected_can_change)); 82 run_loop.Run(); 83 } 84 85 void RefreshPluginsSynchronously() { 86 PluginService::GetInstance()->RefreshPlugins(); 87 #if !defined(OS_WIN) 88 // Can't go out of process in unit tests. 89 content::RenderProcessHost::SetRunRendererInProcess(true); 90 #endif 91 scoped_refptr<content::MessageLoopRunner> runner = 92 new content::MessageLoopRunner; 93 PluginService::GetInstance()->GetPlugins( 94 base::Bind(&GotPlugins, runner->QuitClosure())); 95 runner->Run(); 96 #if !defined(OS_WIN) 97 content::RenderProcessHost::SetRunRendererInProcess(false); 98 #endif 99 } 100 101 scoped_refptr<PluginPrefs> plugin_prefs_; 102 }; 103 104 TEST_F(PluginPrefsTest, DisabledByPolicy) { 105 std::set<base::string16> disabled_plugins; 106 disabled_plugins.insert(ASCIIToUTF16("Disable this!")); 107 disabled_plugins.insert(ASCIIToUTF16("*Google*")); 108 SetPolicyEnforcedPluginPatterns(disabled_plugins, 109 std::set<base::string16>(), 110 std::set<base::string16>()); 111 112 EXPECT_EQ(PluginPrefs::NO_POLICY, 113 plugin_prefs_->PolicyStatusForPlugin(ASCIIToUTF16("42"))); 114 EXPECT_EQ(PluginPrefs::POLICY_DISABLED, 115 plugin_prefs_->PolicyStatusForPlugin( 116 ASCIIToUTF16("Disable this!"))); 117 EXPECT_EQ(PluginPrefs::POLICY_DISABLED, 118 plugin_prefs_->PolicyStatusForPlugin(ASCIIToUTF16("Google Earth"))); 119 } 120 121 TEST_F(PluginPrefsTest, EnabledByPolicy) { 122 std::set<base::string16> enabled_plugins; 123 enabled_plugins.insert(ASCIIToUTF16("Enable that!")); 124 enabled_plugins.insert(ASCIIToUTF16("PDF*")); 125 SetPolicyEnforcedPluginPatterns(std::set<base::string16>(), 126 std::set<base::string16>(), 127 enabled_plugins); 128 129 EXPECT_EQ(PluginPrefs::NO_POLICY, 130 plugin_prefs_->PolicyStatusForPlugin(ASCIIToUTF16("42"))); 131 EXPECT_EQ(PluginPrefs::POLICY_ENABLED, 132 plugin_prefs_->PolicyStatusForPlugin(ASCIIToUTF16("Enable that!"))); 133 EXPECT_EQ(PluginPrefs::POLICY_ENABLED, 134 plugin_prefs_->PolicyStatusForPlugin(ASCIIToUTF16("PDF Reader"))); 135 } 136 137 TEST_F(PluginPrefsTest, EnabledAndDisabledByPolicy) { 138 const base::string16 k42(ASCIIToUTF16("42")); 139 const base::string16 kEnabled(ASCIIToUTF16("Enabled")); 140 const base::string16 kEnabled2(ASCIIToUTF16("Enabled 2")); 141 const base::string16 kEnabled3(ASCIIToUTF16("Enabled 3")); 142 const base::string16 kException(ASCIIToUTF16("Exception")); 143 const base::string16 kException2(ASCIIToUTF16("Exception 2")); 144 const base::string16 kGoogleMars(ASCIIToUTF16("Google Mars")); 145 const base::string16 kGoogleEarth(ASCIIToUTF16("Google Earth")); 146 147 std::set<base::string16> disabled_plugins; 148 std::set<base::string16> disabled_plugins_exceptions; 149 std::set<base::string16> enabled_plugins; 150 151 disabled_plugins.insert(kEnabled); 152 disabled_plugins_exceptions.insert(kEnabled); 153 enabled_plugins.insert(kEnabled); 154 155 disabled_plugins_exceptions.insert(kException); 156 157 disabled_plugins.insert(kEnabled2); 158 enabled_plugins.insert(kEnabled2); 159 160 disabled_plugins.insert(kException2); 161 disabled_plugins_exceptions.insert(kException2); 162 163 disabled_plugins_exceptions.insert(kEnabled3); 164 enabled_plugins.insert(kEnabled3); 165 166 SetPolicyEnforcedPluginPatterns(disabled_plugins, 167 disabled_plugins_exceptions, 168 enabled_plugins); 169 170 EXPECT_EQ(PluginPrefs::NO_POLICY, plugin_prefs_->PolicyStatusForPlugin(k42)); 171 172 EXPECT_EQ(PluginPrefs::POLICY_ENABLED, 173 plugin_prefs_->PolicyStatusForPlugin(kEnabled)); 174 EXPECT_EQ(PluginPrefs::POLICY_ENABLED, 175 plugin_prefs_->PolicyStatusForPlugin(kEnabled2)); 176 EXPECT_EQ(PluginPrefs::POLICY_ENABLED, 177 plugin_prefs_->PolicyStatusForPlugin(kEnabled3)); 178 179 EXPECT_EQ(PluginPrefs::NO_POLICY, 180 plugin_prefs_->PolicyStatusForPlugin(kException)); 181 EXPECT_EQ(PluginPrefs::NO_POLICY, 182 plugin_prefs_->PolicyStatusForPlugin(kException2)); 183 184 disabled_plugins.clear(); 185 disabled_plugins_exceptions.clear(); 186 enabled_plugins.clear(); 187 188 disabled_plugins.insert(ASCIIToUTF16("*")); 189 disabled_plugins_exceptions.insert(ASCIIToUTF16("*Google*")); 190 enabled_plugins.insert(kGoogleEarth); 191 192 SetPolicyEnforcedPluginPatterns(disabled_plugins, 193 disabled_plugins_exceptions, 194 enabled_plugins); 195 196 EXPECT_EQ(PluginPrefs::POLICY_ENABLED, 197 plugin_prefs_->PolicyStatusForPlugin(kGoogleEarth)); 198 EXPECT_EQ(PluginPrefs::NO_POLICY, 199 plugin_prefs_->PolicyStatusForPlugin(kGoogleMars)); 200 EXPECT_EQ(PluginPrefs::POLICY_DISABLED, 201 plugin_prefs_->PolicyStatusForPlugin(k42)); 202 } 203 204 // Linux Aura doesn't support NPAPI. 205 #if !(defined(OS_LINUX) && defined(USE_AURA)) 206 207 TEST_F(PluginPrefsTest, UnifiedPepperFlashState) { 208 base::ShadowingAtExitManager at_exit_manager_; // Destroys the PluginService. 209 210 base::MessageLoop message_loop; 211 content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop); 212 PluginService::GetInstance()->Init(); 213 PluginService::GetInstance()->DisablePluginsDiscoveryForTesting(); 214 215 base::string16 component_updated_plugin_name( 216 ASCIIToUTF16("Component-updated Pepper Flash")); 217 content::WebPluginInfo component_updated_plugin_1( 218 component_updated_plugin_name, 219 GetComponentUpdatedPepperFlashPath(FILE_PATH_LITERAL("11.3.31.227")), 220 ASCIIToUTF16("11.3.31.227"), 221 ASCIIToUTF16("")); 222 content::WebPluginInfo component_updated_plugin_2( 223 component_updated_plugin_name, 224 GetComponentUpdatedPepperFlashPath(FILE_PATH_LITERAL("11.3.31.228")), 225 ASCIIToUTF16("11.3.31.228"), 226 ASCIIToUTF16("")); 227 content::WebPluginInfo bundled_plugin(ASCIIToUTF16("Pepper Flash"), 228 GetBundledPepperFlashPath(), 229 ASCIIToUTF16("11.3.31.229"), 230 ASCIIToUTF16("")); 231 232 PluginService::GetInstance()->RegisterInternalPlugin( 233 component_updated_plugin_1, false); 234 PluginService::GetInstance()->RegisterInternalPlugin( 235 component_updated_plugin_2, false); 236 PluginService::GetInstance()->RegisterInternalPlugin(bundled_plugin, false); 237 238 RefreshPluginsSynchronously(); 239 240 // Set the state of any of the three plugins will affect the others. 241 EnablePluginSynchronously(true, component_updated_plugin_1.path, true); 242 EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1)); 243 EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2)); 244 EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(bundled_plugin)); 245 246 EnablePluginSynchronously(false, bundled_plugin.path, true); 247 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1)); 248 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2)); 249 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(bundled_plugin)); 250 251 EnablePluginSynchronously(true, component_updated_plugin_2.path, true); 252 EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1)); 253 EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2)); 254 EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(bundled_plugin)); 255 256 std::set<base::string16> disabled_plugins; 257 disabled_plugins.insert(component_updated_plugin_name); 258 SetPolicyEnforcedPluginPatterns(disabled_plugins, 259 std::set<base::string16>(), 260 std::set<base::string16>()); 261 262 // Policy settings should be respected. 263 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1)); 264 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2)); 265 EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(bundled_plugin)); 266 267 EnablePluginSynchronously(false, bundled_plugin.path, true); 268 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(bundled_plugin)); 269 270 // Trying to change the state of a policy-enforced plugin should not take 271 // effect. And it shouldn't change the state of other plugins either, even if 272 // they are not restricted by any policy. 273 EnablePluginSynchronously(true, component_updated_plugin_1.path, false); 274 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1)); 275 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2)); 276 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(bundled_plugin)); 277 278 EnablePluginSynchronously(true, bundled_plugin.path, true); 279 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1)); 280 EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2)); 281 EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(bundled_plugin)); 282 } 283 284 #endif 285