普通文本  |  285行  |  11.04 KB

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/plugins/plugin_prefs.h"

#include "base/at_exit.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

using content::BrowserThread;
using content::PluginService;

namespace {

void CanEnablePluginCallback(const base::Closure& quit_closure,
                             bool expected_can_change,
                             bool did_change) {
  EXPECT_EQ(expected_can_change, did_change);
  quit_closure.Run();
}

#if !(defined(OS_LINUX) && defined(USE_AURA))
base::FilePath GetComponentUpdatedPepperFlashPath(
    const base::FilePath::StringType& version) {
  base::FilePath path;
  EXPECT_TRUE(PathService::Get(
      chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, &path));
  path = path.Append(version);
  path = path.Append(chrome::kPepperFlashPluginFilename);
  return path;
}

base::FilePath GetBundledPepperFlashPath() {
  base::FilePath path;
  EXPECT_TRUE(PathService::Get(chrome::FILE_PEPPER_FLASH_PLUGIN, &path));
  return path;
}
#endif  // !(defined(OS_LINUX) && defined(USE_AURA))

void GotPlugins(const base::Closure& quit_closure,
                const std::vector<content::WebPluginInfo>& plugins) {
  quit_closure.Run();
}

}  // namespace

class PluginPrefsTest : public ::testing::Test {
 public:
  virtual void SetUp() OVERRIDE {
    plugin_prefs_ = new PluginPrefs();
  }

  void SetPolicyEnforcedPluginPatterns(
      const std::set<base::string16>& disabled,
      const std::set<base::string16>& disabled_exceptions,
      const std::set<base::string16>& enabled) {
    plugin_prefs_->SetPolicyEnforcedPluginPatterns(
        disabled, disabled_exceptions, enabled);
  }

 protected:
  void EnablePluginSynchronously(bool enabled,
                                 const base::FilePath& path,
                                 bool expected_can_change) {
    base::RunLoop run_loop;
    plugin_prefs_->EnablePlugin(
        enabled, path,
        base::Bind(&CanEnablePluginCallback, run_loop.QuitClosure(),
                   expected_can_change));
    run_loop.Run();
  }

  void RefreshPluginsSynchronously() {
    PluginService::GetInstance()->RefreshPlugins();
#if !defined(OS_WIN)
    // Can't go out of process in unit tests.
    content::RenderProcessHost::SetRunRendererInProcess(true);
#endif
    scoped_refptr<content::MessageLoopRunner> runner =
        new content::MessageLoopRunner;
    PluginService::GetInstance()->GetPlugins(
        base::Bind(&GotPlugins, runner->QuitClosure()));
    runner->Run();
#if !defined(OS_WIN)
    content::RenderProcessHost::SetRunRendererInProcess(false);
#endif
  }

  scoped_refptr<PluginPrefs> plugin_prefs_;
};

TEST_F(PluginPrefsTest, DisabledByPolicy) {
  std::set<base::string16> disabled_plugins;
  disabled_plugins.insert(ASCIIToUTF16("Disable this!"));
  disabled_plugins.insert(ASCIIToUTF16("*Google*"));
  SetPolicyEnforcedPluginPatterns(disabled_plugins,
                                  std::set<base::string16>(),
                                  std::set<base::string16>());

  EXPECT_EQ(PluginPrefs::NO_POLICY,
            plugin_prefs_->PolicyStatusForPlugin(ASCIIToUTF16("42")));
  EXPECT_EQ(PluginPrefs::POLICY_DISABLED,
            plugin_prefs_->PolicyStatusForPlugin(
                ASCIIToUTF16("Disable this!")));
  EXPECT_EQ(PluginPrefs::POLICY_DISABLED,
            plugin_prefs_->PolicyStatusForPlugin(ASCIIToUTF16("Google Earth")));
}

TEST_F(PluginPrefsTest, EnabledByPolicy) {
  std::set<base::string16> enabled_plugins;
  enabled_plugins.insert(ASCIIToUTF16("Enable that!"));
  enabled_plugins.insert(ASCIIToUTF16("PDF*"));
  SetPolicyEnforcedPluginPatterns(std::set<base::string16>(),
                                  std::set<base::string16>(),
                                  enabled_plugins);

  EXPECT_EQ(PluginPrefs::NO_POLICY,
            plugin_prefs_->PolicyStatusForPlugin(ASCIIToUTF16("42")));
  EXPECT_EQ(PluginPrefs::POLICY_ENABLED,
            plugin_prefs_->PolicyStatusForPlugin(ASCIIToUTF16("Enable that!")));
  EXPECT_EQ(PluginPrefs::POLICY_ENABLED,
            plugin_prefs_->PolicyStatusForPlugin(ASCIIToUTF16("PDF Reader")));
}

TEST_F(PluginPrefsTest, EnabledAndDisabledByPolicy) {
  const base::string16 k42(ASCIIToUTF16("42"));
  const base::string16 kEnabled(ASCIIToUTF16("Enabled"));
  const base::string16 kEnabled2(ASCIIToUTF16("Enabled 2"));
  const base::string16 kEnabled3(ASCIIToUTF16("Enabled 3"));
  const base::string16 kException(ASCIIToUTF16("Exception"));
  const base::string16 kException2(ASCIIToUTF16("Exception 2"));
  const base::string16 kGoogleMars(ASCIIToUTF16("Google Mars"));
  const base::string16 kGoogleEarth(ASCIIToUTF16("Google Earth"));

  std::set<base::string16> disabled_plugins;
  std::set<base::string16> disabled_plugins_exceptions;
  std::set<base::string16> enabled_plugins;

  disabled_plugins.insert(kEnabled);
  disabled_plugins_exceptions.insert(kEnabled);
  enabled_plugins.insert(kEnabled);

  disabled_plugins_exceptions.insert(kException);

  disabled_plugins.insert(kEnabled2);
  enabled_plugins.insert(kEnabled2);

  disabled_plugins.insert(kException2);
  disabled_plugins_exceptions.insert(kException2);

  disabled_plugins_exceptions.insert(kEnabled3);
  enabled_plugins.insert(kEnabled3);

  SetPolicyEnforcedPluginPatterns(disabled_plugins,
                                  disabled_plugins_exceptions,
                                  enabled_plugins);

  EXPECT_EQ(PluginPrefs::NO_POLICY, plugin_prefs_->PolicyStatusForPlugin(k42));

  EXPECT_EQ(PluginPrefs::POLICY_ENABLED,
            plugin_prefs_->PolicyStatusForPlugin(kEnabled));
  EXPECT_EQ(PluginPrefs::POLICY_ENABLED,
            plugin_prefs_->PolicyStatusForPlugin(kEnabled2));
  EXPECT_EQ(PluginPrefs::POLICY_ENABLED,
            plugin_prefs_->PolicyStatusForPlugin(kEnabled3));

  EXPECT_EQ(PluginPrefs::NO_POLICY,
            plugin_prefs_->PolicyStatusForPlugin(kException));
  EXPECT_EQ(PluginPrefs::NO_POLICY,
            plugin_prefs_->PolicyStatusForPlugin(kException2));

  disabled_plugins.clear();
  disabled_plugins_exceptions.clear();
  enabled_plugins.clear();

  disabled_plugins.insert(ASCIIToUTF16("*"));
  disabled_plugins_exceptions.insert(ASCIIToUTF16("*Google*"));
  enabled_plugins.insert(kGoogleEarth);

  SetPolicyEnforcedPluginPatterns(disabled_plugins,
                                  disabled_plugins_exceptions,
                                  enabled_plugins);

  EXPECT_EQ(PluginPrefs::POLICY_ENABLED,
            plugin_prefs_->PolicyStatusForPlugin(kGoogleEarth));
  EXPECT_EQ(PluginPrefs::NO_POLICY,
            plugin_prefs_->PolicyStatusForPlugin(kGoogleMars));
  EXPECT_EQ(PluginPrefs::POLICY_DISABLED,
            plugin_prefs_->PolicyStatusForPlugin(k42));
}

// Linux Aura doesn't support NPAPI.
#if !(defined(OS_LINUX) && defined(USE_AURA))

TEST_F(PluginPrefsTest, UnifiedPepperFlashState) {
  base::ShadowingAtExitManager at_exit_manager_;  // Destroys the PluginService.

  base::MessageLoop message_loop;
  content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
  PluginService::GetInstance()->Init();
  PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();

  base::string16 component_updated_plugin_name(
      ASCIIToUTF16("Component-updated Pepper Flash"));
  content::WebPluginInfo component_updated_plugin_1(
      component_updated_plugin_name,
      GetComponentUpdatedPepperFlashPath(FILE_PATH_LITERAL("11.3.31.227")),
      ASCIIToUTF16("11.3.31.227"),
      ASCIIToUTF16(""));
  content::WebPluginInfo component_updated_plugin_2(
      component_updated_plugin_name,
      GetComponentUpdatedPepperFlashPath(FILE_PATH_LITERAL("11.3.31.228")),
      ASCIIToUTF16("11.3.31.228"),
      ASCIIToUTF16(""));
  content::WebPluginInfo bundled_plugin(ASCIIToUTF16("Pepper Flash"),
                                        GetBundledPepperFlashPath(),
                                        ASCIIToUTF16("11.3.31.229"),
                                        ASCIIToUTF16(""));

  PluginService::GetInstance()->RegisterInternalPlugin(
      component_updated_plugin_1, false);
  PluginService::GetInstance()->RegisterInternalPlugin(
      component_updated_plugin_2, false);
  PluginService::GetInstance()->RegisterInternalPlugin(bundled_plugin, false);

  RefreshPluginsSynchronously();

  // Set the state of any of the three plugins will affect the others.
  EnablePluginSynchronously(true, component_updated_plugin_1.path, true);
  EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1));
  EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2));
  EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(bundled_plugin));

  EnablePluginSynchronously(false, bundled_plugin.path, true);
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1));
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2));
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(bundled_plugin));

  EnablePluginSynchronously(true, component_updated_plugin_2.path, true);
  EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1));
  EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2));
  EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(bundled_plugin));

  std::set<base::string16> disabled_plugins;
  disabled_plugins.insert(component_updated_plugin_name);
  SetPolicyEnforcedPluginPatterns(disabled_plugins,
                                  std::set<base::string16>(),
                                  std::set<base::string16>());

  // Policy settings should be respected.
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1));
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2));
  EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(bundled_plugin));

  EnablePluginSynchronously(false, bundled_plugin.path, true);
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(bundled_plugin));

  // Trying to change the state of a policy-enforced plugin should not take
  // effect. And it shouldn't change the state of other plugins either, even if
  // they are not restricted by any policy.
  EnablePluginSynchronously(true, component_updated_plugin_1.path, false);
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1));
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2));
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(bundled_plugin));

  EnablePluginSynchronously(true, bundled_plugin.path, true);
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1));
  EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2));
  EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(bundled_plugin));
}

#endif