<commit_before>// 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();
}

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;
}

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<string16>& disabled,
      const std::set<string16>& disabled_exceptions,
      const std::set<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();
  }

  scoped_refptr<PluginPrefs> plugin_prefs_;
};

TEST_F(PluginPrefsTest, DisabledByPolicy) {
  std::set<string16> disabled_plugins;
  disabled_plugins.insert(ASCIIToUTF16("Disable this!"));
  disabled_plugins.insert(ASCIIToUTF16("*Google*"));
  SetPolicyEnforcedPluginPatterns(disabled_plugins,
                                  std::set<string16>(),
                                  std::set<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<string16> enabled_plugins;
  enabled_plugins.insert(ASCIIToUTF16("Enable that!"));
  enabled_plugins.insert(ASCIIToUTF16("PDF*"));
  SetPolicyEnforcedPluginPatterns(std::set<string16>(),
                                  std::set<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 string16 k42(ASCIIToUTF16("42"));
  const string16 kEnabled(ASCIIToUTF16("Enabled"));
  const string16 kEnabled2(ASCIIToUTF16("Enabled 2"));
  const string16 kEnabled3(ASCIIToUTF16("Enabled 3"));
  const string16 kException(ASCIIToUTF16("Exception"));
  const string16 kException2(ASCIIToUTF16("Exception 2"));
  const string16 kGoogleMars(ASCIIToUTF16("Google Mars"));
  const string16 kGoogleEarth(ASCIIToUTF16("Google Earth"));

  std::set<string16> disabled_plugins;
  std::set<string16> disabled_plugins_exceptions;
  std::set<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();

  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);

#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

  // 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<string16> disabled_plugins;
  disabled_plugins.insert(component_updated_plugin_name);
  SetPolicyEnforcedPluginPatterns(disabled_plugins,
                                  std::set<string16>(),
                                  std::set<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
<commit_msg>Make PluginPrefsTest more robust.<commit_after>// 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();
}

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;
}

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<string16>& disabled,
      const std::set<string16>& disabled_exceptions,
      const std::set<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<string16> disabled_plugins;
  disabled_plugins.insert(ASCIIToUTF16("Disable this!"));
  disabled_plugins.insert(ASCIIToUTF16("*Google*"));
  SetPolicyEnforcedPluginPatterns(disabled_plugins,
                                  std::set<string16>(),
                                  std::set<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<string16> enabled_plugins;
  enabled_plugins.insert(ASCIIToUTF16("Enable that!"));
  enabled_plugins.insert(ASCIIToUTF16("PDF*"));
  SetPolicyEnforcedPluginPatterns(std::set<string16>(),
                                  std::set<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 string16 k42(ASCIIToUTF16("42"));
  const string16 kEnabled(ASCIIToUTF16("Enabled"));
  const string16 kEnabled2(ASCIIToUTF16("Enabled 2"));
  const string16 kEnabled3(ASCIIToUTF16("Enabled 3"));
  const string16 kException(ASCIIToUTF16("Exception"));
  const string16 kException2(ASCIIToUTF16("Exception 2"));
  const string16 kGoogleMars(ASCIIToUTF16("Google Mars"));
  const string16 kGoogleEarth(ASCIIToUTF16("Google Earth"));

  std::set<string16> disabled_plugins;
  std::set<string16> disabled_plugins_exceptions;
  std::set<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();

  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<string16> disabled_plugins;
  disabled_plugins.insert(component_updated_plugin_name);
  SetPolicyEnforcedPluginPatterns(disabled_plugins,
                                  std::set<string16>(),
                                  std::set<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
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 <map>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/test/test_timeouts.h"
#include "base/test/trace_event_analyzer.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/javascript_test_util.h"
#include "chrome/test/ui/ui_perf_test.h"
#include "net/base/net_util.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_switches.h"

namespace {

enum FrameRateTestFlags {
  kUseGpu             = 1 << 0, // Only execute test if --enable-gpu, and verify
                                // that test ran on GPU. This is required for
                                // tests that run on GPU.
  kForceGpuComposited = 1 << 1, // Force the test to use the compositor.
  kDisableVsync       = 1 << 2, // Do not limit framerate to vertical refresh.
                                // when on GPU, nor to 60hz when not on GPU.
  kUseReferenceBuild  = 1 << 3, // Run test using the reference chrome build.
  kInternal           = 1 << 4, // Test uses internal test data.
  kHasRedirect        = 1 << 5, // Test page contains an HTML redirect.
};

class FrameRateTest
  : public UIPerfTest
  , public ::testing::WithParamInterface<int> {
 public:
  FrameRateTest() {
    show_window_ = true;
    dom_automation_enabled_ = true;
  }

  bool HasFlag(FrameRateTestFlags flag) const {
    return (GetParam() & flag) == flag;
  }

  bool IsGpuAvailable() const {
    return CommandLine::ForCurrentProcess()->HasSwitch("enable-gpu");
  }

  std::string GetSuffixForTestFlags() {
    std::string suffix;
    if (HasFlag(kForceGpuComposited))
      suffix += "_comp";
    if (HasFlag(kUseGpu))
      suffix += "_gpu";
    if (HasFlag(kDisableVsync))
      suffix += "_novsync";
    if (HasFlag(kUseReferenceBuild))
      suffix += "_ref";
    return suffix;
  }

  virtual FilePath GetDataPath(const std::string& name) {
    // Make sure the test data is checked out.
    FilePath test_path;
    PathService::Get(chrome::DIR_TEST_DATA, &test_path);
    test_path = test_path.Append(FILE_PATH_LITERAL("perf"));
    test_path = test_path.Append(FILE_PATH_LITERAL("frame_rate"));
    if (HasFlag(kInternal)) {
      test_path = test_path.Append(FILE_PATH_LITERAL("private"));
    } else {
      test_path = test_path.Append(FILE_PATH_LITERAL("content"));
    }
    test_path = test_path.AppendASCII(name);
    return test_path;
  }

  virtual void SetUp() {
    if (HasFlag(kUseReferenceBuild))
      UseReferenceBuild();

    // Turn on chrome.Interval to get higher-resolution timestamps on frames.
    launch_arguments_.AppendSwitch(switches::kEnableBenchmarking);

    // Required additional argument to make the kEnableBenchmarking switch work.
    launch_arguments_.AppendSwitch(switches::kEnableStatsTable);

    // UI tests boot up render views starting from about:blank. This causes
    // the renderer to start up thinking it cannot use the GPU. To work
    // around that, and allow the frame rate test to use the GPU, we must
    // pass kAllowWebUICompositing.
    launch_arguments_.AppendSwitch(switches::kAllowWebUICompositing);

    // Some of the tests may launch http requests through JSON or AJAX
    // which causes a security error (cross domain request) when the page
    // is loaded from the local file system ( file:// ). The following switch
    // fixes that error.
    launch_arguments_.AppendSwitch(switches::kAllowFileAccessFromFiles);

    if (!HasFlag(kUseGpu)) {
      launch_arguments_.AppendSwitch(switches::kDisableAcceleratedCompositing);
      launch_arguments_.AppendSwitch(switches::kDisableExperimentalWebGL);
      launch_arguments_.AppendSwitch(switches::kDisableAccelerated2dCanvas);
    } else {
      // This switch is required for enabling the accelerated 2d canvas on
      // Chrome versions prior to Chrome 15, which may be the case for the
      // reference build.
      launch_arguments_.AppendSwitch(switches::kEnableAccelerated2dCanvas);
    }

    if (HasFlag(kDisableVsync))
      launch_arguments_.AppendSwitch(switches::kDisableGpuVsync);

    UIPerfTest::SetUp();
  }

  bool DidRunOnGpu(const std::string& json_events) {
    using namespace trace_analyzer;

    // Check trace for GPU accleration.
    scoped_ptr<TraceAnalyzer> analyzer(TraceAnalyzer::Create(json_events));

    gfx::GLImplementation gl_impl = gfx::kGLImplementationNone;
    const TraceEvent* gpu_event = analyzer->FindOneEvent(
        Query(EVENT_NAME) == Query::String("SwapBuffers") &&
        Query(EVENT_HAS_NUMBER_ARG, "GLImpl"));
    if (gpu_event)
      gl_impl = static_cast<gfx::GLImplementation>(
          gpu_event->GetKnownArgAsInt("GLImpl"));
    return (gl_impl == gfx::kGLImplementationDesktopGL ||
            gl_impl == gfx::kGLImplementationEGLGLES2);
  }

  void RunTest(const std::string& name) {
    if (HasFlag(kUseGpu) && !IsGpuAvailable()) {
      printf("Test skipped: requires gpu. Pass --enable-gpu on the command "
             "line if use of GPU is desired.\n");
      return;
    }

    // Verify flag combinations.
    ASSERT_TRUE(HasFlag(kUseGpu) || !HasFlag(kForceGpuComposited));
    ASSERT_TRUE(!HasFlag(kUseGpu) || IsGpuAvailable());

    FilePath test_path = GetDataPath(name);
    ASSERT_TRUE(file_util::DirectoryExists(test_path))
        << "Missing test directory: " << test_path.value();

    test_path = test_path.Append(FILE_PATH_LITERAL("test.html"));

    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    // TODO(jbates): remove this check when ref builds are updated.
    if (!HasFlag(kUseReferenceBuild))
      ASSERT_TRUE(automation()->BeginTracing("test_gpu"));

    if (HasFlag(kHasRedirect)) {
      // If the test file is known to contain an html redirect, we must block
      // until the second navigation is complete and reacquire the active tab
      // in order to avoid a race condition.
      // If the following assertion is triggered due to a timeout, it is
      // possible that the current test does not re-direct and therefore should
      // not have the kHasRedirect flag turned on.
      ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
        tab->NavigateToURLBlockUntilNavigationsComplete(
        net::FilePathToFileURL(test_path), 2));
      tab = GetActiveTab();
      ASSERT_TRUE(tab.get());
    } else {
      ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
        tab->NavigateToURL(net::FilePathToFileURL(test_path)));
    }

    // Block until initialization completes
    // If the following assertion fails intermittently, it could be due to a
    // race condition caused by an html redirect. If that is the case, verify
    // that flag kHasRedirect is enabled for the current test.
    ASSERT_TRUE(WaitUntilJavaScriptCondition(
      tab, L"", L"window.domAutomationController.send(__initialized);",
      TestTimeouts::large_test_timeout_ms()));

    if (HasFlag(kForceGpuComposited)) {
      ASSERT_TRUE(tab->NavigateToURLAsync(
        GURL("javascript:__make_body_composited();")));
    }

    // Start the tests.
    ASSERT_TRUE(tab->NavigateToURLAsync(GURL("javascript:__start_all();")));

    // Block until the tests completes.
    ASSERT_TRUE(WaitUntilJavaScriptCondition(
        tab, L"", L"window.domAutomationController.send(!__running_all);",
        TestTimeouts::large_test_timeout_ms()));

    // TODO(jbates): remove this check when ref builds are updated.
    if (!HasFlag(kUseReferenceBuild)) {
      std::string json_events;
      ASSERT_TRUE(automation()->EndTracing(&json_events));

      bool did_run_on_gpu = DidRunOnGpu(json_events);
      bool expect_gpu = HasFlag(kUseGpu);
      EXPECT_EQ(expect_gpu, did_run_on_gpu);
    }

    // Read out the results.
    std::wstring json;
    ASSERT_TRUE(tab->ExecuteAndExtractString(
        L"",
        L"window.domAutomationController.send("
        L"JSON.stringify(__calc_results_total()));",
        &json));

    std::map<std::string, std::string> results;
    ASSERT_TRUE(JsonDictionaryToMap(WideToUTF8(json), &results));

    ASSERT_TRUE(results.find("mean") != results.end());
    ASSERT_TRUE(results.find("sigma") != results.end());
    ASSERT_TRUE(results.find("gestures") != results.end());
    ASSERT_TRUE(results.find("means") != results.end());
    ASSERT_TRUE(results.find("sigmas") != results.end());

    std::string trace_name = "interval" + GetSuffixForTestFlags();
    printf("GESTURES %s: %s= [%s] [%s] [%s]\n", name.c_str(),
                                                trace_name.c_str(),
                                                results["gestures"].c_str(),
                                                results["means"].c_str(),
                                                results["sigmas"].c_str());

    std::string mean_and_error = results["mean"] + "," + results["sigma"];
    PrintResultMeanAndError(name, "", trace_name, mean_and_error,
                            "frames-per-second", true);
  }
};

// Must use a different class name to avoid test instantiation conflicts
// with FrameRateTest. An alias is good enough. The alias names must match
// the pattern FrameRate*Test* for them to get picked up by the test bots.
typedef FrameRateTest FrameRateCompositingTest;

// Tests that trigger compositing with a -webkit-translateZ(0)
#define FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(content) \
TEST_P(FrameRateCompositingTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateCompositingTest, ::testing::Values(
                        0,
                        kUseGpu | kForceGpuComposited,
                        kUseReferenceBuild,
                        kUseReferenceBuild | kUseGpu | kForceGpuComposited));

FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(blank);
FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(googleblog);

typedef FrameRateTest FrameRateNoVsyncCanvasInternalTest;

// Tests for animated 2D canvas content with and without disabling vsync
#define INTERNAL_FRAME_RATE_TEST_CANVAS_WITH_AND_WITHOUT_NOVSYNC(content) \
TEST_P(FrameRateNoVsyncCanvasInternalTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateNoVsyncCanvasInternalTest, ::testing::Values(
    kInternal | kHasRedirect,
    kInternal | kHasRedirect | kUseGpu,
    kInternal | kHasRedirect | kUseGpu | kDisableVsync,
    kUseReferenceBuild | kInternal | kHasRedirect,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu | kDisableVsync));

INTERNAL_FRAME_RATE_TEST_CANVAS_WITH_AND_WITHOUT_NOVSYNC(DISABLED_fishbowl)

typedef FrameRateTest FrameRateGpuCanvasInternalTest;

// Tests for animated 2D canvas content to be tested only with GPU
// acceleration.
// tests are run with and without Vsync
#define INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(content) \
TEST_P(FrameRateGpuCanvasInternalTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateGpuCanvasInternalTest, ::testing::Values(
    kInternal | kHasRedirect | kUseGpu,
    kInternal | kHasRedirect | kUseGpu | kDisableVsync,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu | kDisableVsync));

INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(fireflies)
INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(FishIE)
INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(speedreading)

}  // namespace
<commit_msg>Disable gpu_frame_rate_test fireflies as it TIMEOUT on gpu bots.<commit_after>// Copyright (c) 2011 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 <map>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/test/test_timeouts.h"
#include "base/test/trace_event_analyzer.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/javascript_test_util.h"
#include "chrome/test/ui/ui_perf_test.h"
#include "net/base/net_util.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_switches.h"

namespace {

enum FrameRateTestFlags {
  kUseGpu             = 1 << 0, // Only execute test if --enable-gpu, and verify
                                // that test ran on GPU. This is required for
                                // tests that run on GPU.
  kForceGpuComposited = 1 << 1, // Force the test to use the compositor.
  kDisableVsync       = 1 << 2, // Do not limit framerate to vertical refresh.
                                // when on GPU, nor to 60hz when not on GPU.
  kUseReferenceBuild  = 1 << 3, // Run test using the reference chrome build.
  kInternal           = 1 << 4, // Test uses internal test data.
  kHasRedirect        = 1 << 5, // Test page contains an HTML redirect.
};

class FrameRateTest
  : public UIPerfTest
  , public ::testing::WithParamInterface<int> {
 public:
  FrameRateTest() {
    show_window_ = true;
    dom_automation_enabled_ = true;
  }

  bool HasFlag(FrameRateTestFlags flag) const {
    return (GetParam() & flag) == flag;
  }

  bool IsGpuAvailable() const {
    return CommandLine::ForCurrentProcess()->HasSwitch("enable-gpu");
  }

  std::string GetSuffixForTestFlags() {
    std::string suffix;
    if (HasFlag(kForceGpuComposited))
      suffix += "_comp";
    if (HasFlag(kUseGpu))
      suffix += "_gpu";
    if (HasFlag(kDisableVsync))
      suffix += "_novsync";
    if (HasFlag(kUseReferenceBuild))
      suffix += "_ref";
    return suffix;
  }

  virtual FilePath GetDataPath(const std::string& name) {
    // Make sure the test data is checked out.
    FilePath test_path;
    PathService::Get(chrome::DIR_TEST_DATA, &test_path);
    test_path = test_path.Append(FILE_PATH_LITERAL("perf"));
    test_path = test_path.Append(FILE_PATH_LITERAL("frame_rate"));
    if (HasFlag(kInternal)) {
      test_path = test_path.Append(FILE_PATH_LITERAL("private"));
    } else {
      test_path = test_path.Append(FILE_PATH_LITERAL("content"));
    }
    test_path = test_path.AppendASCII(name);
    return test_path;
  }

  virtual void SetUp() {
    if (HasFlag(kUseReferenceBuild))
      UseReferenceBuild();

    // Turn on chrome.Interval to get higher-resolution timestamps on frames.
    launch_arguments_.AppendSwitch(switches::kEnableBenchmarking);

    // Required additional argument to make the kEnableBenchmarking switch work.
    launch_arguments_.AppendSwitch(switches::kEnableStatsTable);

    // UI tests boot up render views starting from about:blank. This causes
    // the renderer to start up thinking it cannot use the GPU. To work
    // around that, and allow the frame rate test to use the GPU, we must
    // pass kAllowWebUICompositing.
    launch_arguments_.AppendSwitch(switches::kAllowWebUICompositing);

    // Some of the tests may launch http requests through JSON or AJAX
    // which causes a security error (cross domain request) when the page
    // is loaded from the local file system ( file:// ). The following switch
    // fixes that error.
    launch_arguments_.AppendSwitch(switches::kAllowFileAccessFromFiles);

    if (!HasFlag(kUseGpu)) {
      launch_arguments_.AppendSwitch(switches::kDisableAcceleratedCompositing);
      launch_arguments_.AppendSwitch(switches::kDisableExperimentalWebGL);
      launch_arguments_.AppendSwitch(switches::kDisableAccelerated2dCanvas);
    } else {
      // This switch is required for enabling the accelerated 2d canvas on
      // Chrome versions prior to Chrome 15, which may be the case for the
      // reference build.
      launch_arguments_.AppendSwitch(switches::kEnableAccelerated2dCanvas);
    }

    if (HasFlag(kDisableVsync))
      launch_arguments_.AppendSwitch(switches::kDisableGpuVsync);

    UIPerfTest::SetUp();
  }

  bool DidRunOnGpu(const std::string& json_events) {
    using namespace trace_analyzer;

    // Check trace for GPU accleration.
    scoped_ptr<TraceAnalyzer> analyzer(TraceAnalyzer::Create(json_events));

    gfx::GLImplementation gl_impl = gfx::kGLImplementationNone;
    const TraceEvent* gpu_event = analyzer->FindOneEvent(
        Query(EVENT_NAME) == Query::String("SwapBuffers") &&
        Query(EVENT_HAS_NUMBER_ARG, "GLImpl"));
    if (gpu_event)
      gl_impl = static_cast<gfx::GLImplementation>(
          gpu_event->GetKnownArgAsInt("GLImpl"));
    return (gl_impl == gfx::kGLImplementationDesktopGL ||
            gl_impl == gfx::kGLImplementationEGLGLES2);
  }

  void RunTest(const std::string& name) {
    if (HasFlag(kUseGpu) && !IsGpuAvailable()) {
      printf("Test skipped: requires gpu. Pass --enable-gpu on the command "
             "line if use of GPU is desired.\n");
      return;
    }

    // Verify flag combinations.
    ASSERT_TRUE(HasFlag(kUseGpu) || !HasFlag(kForceGpuComposited));
    ASSERT_TRUE(!HasFlag(kUseGpu) || IsGpuAvailable());

    FilePath test_path = GetDataPath(name);
    ASSERT_TRUE(file_util::DirectoryExists(test_path))
        << "Missing test directory: " << test_path.value();

    test_path = test_path.Append(FILE_PATH_LITERAL("test.html"));

    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    // TODO(jbates): remove this check when ref builds are updated.
    if (!HasFlag(kUseReferenceBuild))
      ASSERT_TRUE(automation()->BeginTracing("test_gpu"));

    if (HasFlag(kHasRedirect)) {
      // If the test file is known to contain an html redirect, we must block
      // until the second navigation is complete and reacquire the active tab
      // in order to avoid a race condition.
      // If the following assertion is triggered due to a timeout, it is
      // possible that the current test does not re-direct and therefore should
      // not have the kHasRedirect flag turned on.
      ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
        tab->NavigateToURLBlockUntilNavigationsComplete(
        net::FilePathToFileURL(test_path), 2));
      tab = GetActiveTab();
      ASSERT_TRUE(tab.get());
    } else {
      ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
        tab->NavigateToURL(net::FilePathToFileURL(test_path)));
    }

    // Block until initialization completes
    // If the following assertion fails intermittently, it could be due to a
    // race condition caused by an html redirect. If that is the case, verify
    // that flag kHasRedirect is enabled for the current test.
    ASSERT_TRUE(WaitUntilJavaScriptCondition(
      tab, L"", L"window.domAutomationController.send(__initialized);",
      TestTimeouts::large_test_timeout_ms()));

    if (HasFlag(kForceGpuComposited)) {
      ASSERT_TRUE(tab->NavigateToURLAsync(
        GURL("javascript:__make_body_composited();")));
    }

    // Start the tests.
    ASSERT_TRUE(tab->NavigateToURLAsync(GURL("javascript:__start_all();")));

    // Block until the tests completes.
    ASSERT_TRUE(WaitUntilJavaScriptCondition(
        tab, L"", L"window.domAutomationController.send(!__running_all);",
        TestTimeouts::large_test_timeout_ms()));

    // TODO(jbates): remove this check when ref builds are updated.
    if (!HasFlag(kUseReferenceBuild)) {
      std::string json_events;
      ASSERT_TRUE(automation()->EndTracing(&json_events));

      bool did_run_on_gpu = DidRunOnGpu(json_events);
      bool expect_gpu = HasFlag(kUseGpu);
      EXPECT_EQ(expect_gpu, did_run_on_gpu);
    }

    // Read out the results.
    std::wstring json;
    ASSERT_TRUE(tab->ExecuteAndExtractString(
        L"",
        L"window.domAutomationController.send("
        L"JSON.stringify(__calc_results_total()));",
        &json));

    std::map<std::string, std::string> results;
    ASSERT_TRUE(JsonDictionaryToMap(WideToUTF8(json), &results));

    ASSERT_TRUE(results.find("mean") != results.end());
    ASSERT_TRUE(results.find("sigma") != results.end());
    ASSERT_TRUE(results.find("gestures") != results.end());
    ASSERT_TRUE(results.find("means") != results.end());
    ASSERT_TRUE(results.find("sigmas") != results.end());

    std::string trace_name = "interval" + GetSuffixForTestFlags();
    printf("GESTURES %s: %s= [%s] [%s] [%s]\n", name.c_str(),
                                                trace_name.c_str(),
                                                results["gestures"].c_str(),
                                                results["means"].c_str(),
                                                results["sigmas"].c_str());

    std::string mean_and_error = results["mean"] + "," + results["sigma"];
    PrintResultMeanAndError(name, "", trace_name, mean_and_error,
                            "frames-per-second", true);
  }
};

// Must use a different class name to avoid test instantiation conflicts
// with FrameRateTest. An alias is good enough. The alias names must match
// the pattern FrameRate*Test* for them to get picked up by the test bots.
typedef FrameRateTest FrameRateCompositingTest;

// Tests that trigger compositing with a -webkit-translateZ(0)
#define FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(content) \
TEST_P(FrameRateCompositingTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateCompositingTest, ::testing::Values(
                        0,
                        kUseGpu | kForceGpuComposited,
                        kUseReferenceBuild,
                        kUseReferenceBuild | kUseGpu | kForceGpuComposited));

FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(blank);
FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(googleblog);

typedef FrameRateTest FrameRateNoVsyncCanvasInternalTest;

// Tests for animated 2D canvas content with and without disabling vsync
#define INTERNAL_FRAME_RATE_TEST_CANVAS_WITH_AND_WITHOUT_NOVSYNC(content) \
TEST_P(FrameRateNoVsyncCanvasInternalTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateNoVsyncCanvasInternalTest, ::testing::Values(
    kInternal | kHasRedirect,
    kInternal | kHasRedirect | kUseGpu,
    kInternal | kHasRedirect | kUseGpu | kDisableVsync,
    kUseReferenceBuild | kInternal | kHasRedirect,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu | kDisableVsync));

INTERNAL_FRAME_RATE_TEST_CANVAS_WITH_AND_WITHOUT_NOVSYNC(DISABLED_fishbowl)

typedef FrameRateTest FrameRateGpuCanvasInternalTest;

// Tests for animated 2D canvas content to be tested only with GPU
// acceleration.
// tests are run with and without Vsync
#define INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(content) \
TEST_P(FrameRateGpuCanvasInternalTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateGpuCanvasInternalTest, ::testing::Values(
    kInternal | kHasRedirect | kUseGpu,
    kInternal | kHasRedirect | kUseGpu | kDisableVsync,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu | kDisableVsync));

INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(DISABLED_fireflies)
INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(FishIE)
INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(speedreading)

}  // namespace
<|endoftext|>


<commit_before>/*
 * File:   CudaRtHandler.cpp
 * Author: cjg
 *
 * Created on October 10, 2009, 10:51 PM
 */

#include <host_defines.h>
#include <builtin_types.h>
#include <driver_types.h>
#include <GL/gl.h>
#include <cuda_runtime_api.h>
#include <cstring>
#include "CudaUtil.h"
#include "CudaRtHandler.h"

using namespace std;

map<string, CudaRtHandler::CudaRoutineHandler> *CudaRtHandler::mspHandlers = NULL;

CudaRtHandler::CudaRtHandler() {
    mpDeviceMemory = new map<string, void *>();
    Initialize();
}

CudaRtHandler::~CudaRtHandler() {

}

static cudaError_t GetDeviceCount(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaGetDeviceCount(int *count) */

    int *count = (int *) in_buffer;

    cudaError_t result = cudaGetDeviceCount(count);

    if (result == cudaSuccess) {
        *out_buffer_size = sizeof (int);
        *out_buffer = new char[*out_buffer_size];
        memmove(*out_buffer, count, sizeof (int));
    }

    return result;
}

static cudaError_t GetDeviceProperties(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaGetDeviceCount(struct cudaDeviceProp *prop,
       int device) */
    struct cudaDeviceProp *prop = (struct cudaDeviceProp *) in_buffer;
    int device = *((int *) (in_buffer + sizeof (struct cudaDeviceProp)));

    cudaError_t result = cudaGetDeviceProperties(prop, device);

    if (result == cudaSuccess) {
        *out_buffer_size = sizeof (struct cudaDeviceProp);
        *out_buffer = new char[*out_buffer_size];
        memmove(*out_buffer, prop, sizeof (struct cudaDeviceProp));
    }

    return result;
}

static cudaError_t Free(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaFree(void *devPtr) */
    void *devPtr = pThis->GetDevicePointer(in_buffer);
    cudaError_t result = cudaFree(devPtr);
    pThis->UnregisterDevicePointer(in_buffer);

    if(result == cudaSuccess) {
        *out_buffer_size = 0;
        *out_buffer = NULL;
    }

    return result;
}

static cudaError_t Malloc(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaMalloc(void **devPtr, size_t size) */
    void *devPtr = NULL;
    size_t size = *((size_t *) (in_buffer + sizeof (void *) * 2 + 3));

    cudaError_t result = cudaMalloc(&devPtr, size);
    pThis->RegisterDevicePointer(in_buffer, devPtr);

    if (result == cudaSuccess) {
        *out_buffer_size = 0;
        *out_buffer = NULL;
    }

    return result;
}

static cudaError_t Memcpy(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaError_t cudaMemcpy(void *dst, const void *src,
        size_t count, cudaMemcpyKind kind) */
    void *dst = NULL;
    void *src = NULL;
    size_t count = *((size_t *) (in_buffer + in_buffer_size
            - sizeof(size_t) - sizeof(cudaMemcpyKind)));
    cudaMemcpyKind kind = *((cudaMemcpyKind *) (in_buffer + in_buffer_size
            - sizeof(cudaMemcpyKind)));
    cudaError_t result;

    switch(kind) {
        case cudaMemcpyHostToHost:
            // This should nevere happer
            break;
        case cudaMemcpyHostToDevice:
            dst = pThis->GetDevicePointer(in_buffer);
            src = in_buffer + CudaUtil::MarshaledDevicePointerSize;
            result = cudaMemcpy(dst, src, count, kind);
            if(result == cudaSuccess) {
                *out_buffer_size = 0;
                *out_buffer = NULL;
            }
            break;
        case cudaMemcpyDeviceToHost:
            *out_buffer_size = count;
            *out_buffer = new char[*out_buffer_size];
            dst = *out_buffer;
            src = pThis->GetDevicePointer(in_buffer);
            result = cudaMemcpy(dst, src, count, kind);
            break;
        case cudaMemcpyDeviceToDevice:
            dst = pThis->GetDevicePointer(in_buffer);
            src = pThis->GetDevicePointer(in_buffer
                    + CudaUtil::MarshaledDevicePointerSize);
            result = cudaMemcpy(dst, src, count, kind);
            if(result == cudaSuccess) {
                *out_buffer_size = 0;
                *out_buffer = NULL;
            }
            break;
    }
    return result;
}

static cudaError_t ThreadSynchronize(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaThreadSynchronize(void) */
    cudaError_t result = cudaThreadSynchronize();

    if(result == cudaSuccess) {
        *out_buffer_size = 0;
        *out_buffer = NULL;
    }

    return result;
}

static cudaError_t GetLastError(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaThreadSynchronize(void) */
    cudaError_t result = cudaGetLastError();

    if(result == cudaSuccess) {
        *out_buffer_size = 0;
        *out_buffer = NULL;
    }

    return result;
}

void CudaRtHandler::RegisterDevicePointer(std::string& handler, void* devPtr) {
    map<string, void *>::iterator it = mpDeviceMemory->find(handler);
    if (it != mpDeviceMemory->end()) {
        /* FIXME: think about freeing memory */
        mpDeviceMemory->erase(it);
    }
    mpDeviceMemory->insert(make_pair(handler, devPtr));
    cout << "Registered DevicePointer " << devPtr << " with handler " << handler << endl;
}

void CudaRtHandler::RegisterDevicePointer(const char* handler, void* devPtr) {
    string tmp(handler);
    RegisterDevicePointer(tmp, devPtr);
}

void * CudaRtHandler::GetDevicePointer(string & handler) {
    map<string, void *>::iterator it = mpDeviceMemory->find(handler);
    if (it == mpDeviceMemory->end())
        throw "Device Pointer '" + handler + "' not found";
    return it->second;
}

void * CudaRtHandler::GetDevicePointer(const char * handler) {
    string tmp(handler);
    return GetDevicePointer(tmp);
}

void CudaRtHandler::UnregisterDevicePointer(std::string& handler) {
    map<string, void *>::iterator it = mpDeviceMemory->find(handler);
    if (it == mpDeviceMemory->end()) {
        /* FIXME: think about throwing an exception */
        return;
    }
    /* FIXME: think about freeing memory */
    cout << "Registered DevicePointer " << it->second << " with handler " << handler << endl;
    mpDeviceMemory->erase(it);
}

void CudaRtHandler::UnregisterDevicePointer(const char* handler) {
    string tmp(handler);
    UnregisterDevicePointer(tmp);
}

cudaError_t CudaRtHandler::Execute(std::string routine, char* in_buffer,
    size_t in_buffer_size, char** out_buffer, size_t* out_buffer_size) {
    map<string, CudaRtHandler::CudaRoutineHandler>::iterator it;
    it = mspHandlers->find(routine);
    if(it == mspHandlers->end())
        throw "No handler for '" + routine + "' found!";
    return it->second(this, in_buffer, in_buffer_size, out_buffer,
        out_buffer_size);
}

void CudaRtHandler::Initialize() {
    if(mspHandlers != NULL)
        return;
    mspHandlers = new map<string, CudaRtHandler::CudaRoutineHandler>();

    /* Thread Management */
    mspHandlers->insert(make_pair("cudaThreadSynchronize", ThreadSynchronize));

    /* Error Handling */
    mspHandlers->insert(make_pair("cudaGetLastError", GetLastError));

    /* Memory Management */
    mspHandlers->insert(make_pair("cudaFree", Free));
    mspHandlers->insert(make_pair("cudaMalloc", Malloc));
    mspHandlers->insert(make_pair("cudaMemcpy", Memcpy));

    mspHandlers->insert(make_pair("cudaGetDeviceCount", GetDeviceCount));
    mspHandlers->insert(make_pair("cudaGetDeviceProperties", GetDeviceProperties));

}<commit_msg>fixed memcpy handler<commit_after>/*
 * File:   CudaRtHandler.cpp
 * Author: cjg
 *
 * Created on October 10, 2009, 10:51 PM
 */

#include <host_defines.h>
#include <builtin_types.h>
#include <driver_types.h>
#include <GL/gl.h>
#include <cuda_runtime_api.h>
#include <cstring>
#include "CudaUtil.h"
#include "CudaRtHandler.h"

using namespace std;

map<string, CudaRtHandler::CudaRoutineHandler> *CudaRtHandler::mspHandlers = NULL;

CudaRtHandler::CudaRtHandler() {
    mpDeviceMemory = new map<string, void *>();
    Initialize();
}

CudaRtHandler::~CudaRtHandler() {

}

static cudaError_t GetDeviceCount(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaGetDeviceCount(int *count) */

    int *count = (int *) in_buffer;

    cudaError_t result = cudaGetDeviceCount(count);

    if (result == cudaSuccess) {
        *out_buffer_size = sizeof (int);
        *out_buffer = new char[*out_buffer_size];
        memmove(*out_buffer, count, sizeof (int));
    }

    return result;
}

static cudaError_t GetDeviceProperties(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaGetDeviceCount(struct cudaDeviceProp *prop,
       int device) */
    struct cudaDeviceProp *prop = (struct cudaDeviceProp *) in_buffer;
    int device = *((int *) (in_buffer + sizeof (struct cudaDeviceProp)));

    cudaError_t result = cudaGetDeviceProperties(prop, device);

    if (result == cudaSuccess) {
        *out_buffer_size = sizeof (struct cudaDeviceProp);
        *out_buffer = new char[*out_buffer_size];
        memmove(*out_buffer, prop, sizeof (struct cudaDeviceProp));
    }

    return result;
}

static cudaError_t Free(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaFree(void *devPtr) */
    void *devPtr = pThis->GetDevicePointer(in_buffer);
    cudaError_t result = cudaFree(devPtr);
    pThis->UnregisterDevicePointer(in_buffer);

    if(result == cudaSuccess) {
        *out_buffer_size = 0;
        *out_buffer = NULL;
    }

    return result;
}

static cudaError_t Malloc(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaMalloc(void **devPtr, size_t size) */
    void *devPtr = NULL;
    size_t size = *((size_t *) (in_buffer + sizeof (void *) * 2 + 3));

    cudaError_t result = cudaMalloc(&devPtr, size);
    pThis->RegisterDevicePointer(in_buffer, devPtr);

    if (result == cudaSuccess) {
        *out_buffer_size = 0;
        *out_buffer = NULL;
    }

    return result;
}

static cudaError_t Memcpy(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaError_t cudaMemcpy(void *dst, const void *src,
        size_t count, cudaMemcpyKind kind) */
    void *dst = NULL;
    void *src = NULL;
    size_t count = *((size_t *) (in_buffer + in_buffer_size
            - sizeof(size_t) - sizeof(cudaMemcpyKind)));
    cudaMemcpyKind kind = *((cudaMemcpyKind *) (in_buffer + in_buffer_size
            - sizeof(cudaMemcpyKind)));
    cudaError_t result;

    switch(kind) {
        case cudaMemcpyHostToHost:
            // This should nevere happer
            break;
        case cudaMemcpyHostToDevice:
            dst = pThis->GetDevicePointer(in_buffer);
            src = in_buffer + CudaUtil::MarshaledDevicePointerSize;
            result = cudaMemcpy(dst, src, count, kind);
            if(result == cudaSuccess) {
                *out_buffer_size = 0;
                *out_buffer = NULL;
            }
            break;
        case cudaMemcpyDeviceToHost:
            *out_buffer_size = count;
            *out_buffer = new char[*out_buffer_size];
            dst = *out_buffer;
            /* adding +1 for fake host pointer */
            src = pThis->GetDevicePointer(in_buffer + 1);
            result = cudaMemcpy(dst, src, count, kind);
            break;
        case cudaMemcpyDeviceToDevice:
            dst = pThis->GetDevicePointer(in_buffer);
            src = pThis->GetDevicePointer(in_buffer
                    + CudaUtil::MarshaledDevicePointerSize);
            result = cudaMemcpy(dst, src, count, kind);
            if(result == cudaSuccess) {
                *out_buffer_size = 0;
                *out_buffer = NULL;
            }
            break;
    }
    return result;
}

static cudaError_t ThreadSynchronize(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaThreadSynchronize(void) */
    cudaError_t result = cudaThreadSynchronize();

    if(result == cudaSuccess) {
        *out_buffer_size = 0;
        *out_buffer = NULL;
    }

    return result;
}

static cudaError_t GetLastError(CudaRtHandler *pThis, char *in_buffer,
        size_t in_buffer_size, char **out_buffer, size_t *out_buffer_size) {
    /* cudaError_t cudaThreadSynchronize(void) */
    cudaError_t result = cudaGetLastError();

    if(result == cudaSuccess) {
        *out_buffer_size = 0;
        *out_buffer = NULL;
    }

    return result;
}

void CudaRtHandler::RegisterDevicePointer(std::string& handler, void* devPtr) {
    map<string, void *>::iterator it = mpDeviceMemory->find(handler);
    if (it != mpDeviceMemory->end()) {
        /* FIXME: think about freeing memory */
        mpDeviceMemory->erase(it);
    }
    mpDeviceMemory->insert(make_pair(handler, devPtr));
    cout << "Registered DevicePointer " << devPtr << " with handler " << handler << endl;
}

void CudaRtHandler::RegisterDevicePointer(const char* handler, void* devPtr) {
    string tmp(handler);
    RegisterDevicePointer(tmp, devPtr);
}

void * CudaRtHandler::GetDevicePointer(string & handler) {
    map<string, void *>::iterator it = mpDeviceMemory->find(handler);
    if (it == mpDeviceMemory->end())
        throw "Device Pointer '" + handler + "' not found";
    return it->second;
}

void * CudaRtHandler::GetDevicePointer(const char * handler) {
    string tmp(handler);
    return GetDevicePointer(tmp);
}

void CudaRtHandler::UnregisterDevicePointer(std::string& handler) {
    map<string, void *>::iterator it = mpDeviceMemory->find(handler);
    if (it == mpDeviceMemory->end()) {
        /* FIXME: think about throwing an exception */
        return;
    }
    /* FIXME: think about freeing memory */
    cout << "Registered DevicePointer " << it->second << " with handler " << handler << endl;
    mpDeviceMemory->erase(it);
}

void CudaRtHandler::UnregisterDevicePointer(const char* handler) {
    string tmp(handler);
    UnregisterDevicePointer(tmp);
}

cudaError_t CudaRtHandler::Execute(std::string routine, char* in_buffer,
    size_t in_buffer_size, char** out_buffer, size_t* out_buffer_size) {
    map<string, CudaRtHandler::CudaRoutineHandler>::iterator it;
    it = mspHandlers->find(routine);
    if(it == mspHandlers->end())
        throw "No handler for '" + routine + "' found!";
    return it->second(this, in_buffer, in_buffer_size, out_buffer,
        out_buffer_size);
}

void CudaRtHandler::Initialize() {
    if(mspHandlers != NULL)
        return;
    mspHandlers = new map<string, CudaRtHandler::CudaRoutineHandler>();

    /* Thread Management */
    mspHandlers->insert(make_pair("cudaThreadSynchronize", ThreadSynchronize));

    /* Error Handling */
    mspHandlers->insert(make_pair("cudaGetLastError", GetLastError));

    /* Memory Management */
    mspHandlers->insert(make_pair("cudaFree", Free));
    mspHandlers->insert(make_pair("cudaMalloc", Malloc));
    mspHandlers->insert(make_pair("cudaMemcpy", Memcpy));

    mspHandlers->insert(make_pair("cudaGetDeviceCount", GetDeviceCount));
    mspHandlers->insert(make_pair("cudaGetDeviceProperties", GetDeviceProperties));

}<|endoftext|>


<commit_before>// RUN: cat %s | %cling -Xclang -verify -I%p | FileCheck %s

// Test the removal of decls which are stored in vector of redeclarables
#include "cling/Interpreter/Interpreter.h"

.rawInput 1
extern int __my_i;
template<typename T> T TemplatedF(T t);
int OverloadedF(int i);
float OverloadedF(float f){ return f + 100.111f;}
double OverloadedF(double d){ return d + 10.11f; };
namespace test { int y = 0; }
.rawInput 0

#include "SubsequentDecls.h"

.rawInput 1
template<> int TemplatedF(int i) { return i + 100; }
int OverloadedF(int i) { return i + 100;}
.rawInput 0

int __my_i = 10
// CHECK: (int) 10
OverloadedF(__my_i)
// CHECK: (int const) 110
TemplatedF(__my_i)
// CHECK: (int const) 110

// .rawInput 1
//   struct Outer { struct Inner { static int i; }; }; struct Outer {};
// namespace Outer { struct Inner { static int i; }; };
// .rawInput 0
// Outer::Inner::i = 12;
.q
<commit_msg>Remove redundant include<commit_after>// RUN: cat %s | %cling -Xclang -verify -I%p | FileCheck %s

// Test the removal of decls which are stored in vector of redeclarables

.rawInput 1
extern int __my_i;
template<typename T> T TemplatedF(T t);
int OverloadedF(int i);
float OverloadedF(float f){ return f + 100.111f;}
double OverloadedF(double d){ return d + 10.11f; };
namespace test { int y = 0; }
.rawInput 0

#include "SubsequentDecls.h"

.rawInput 1
template<> int TemplatedF(int i) { return i + 100; }
int OverloadedF(int i) { return i + 100;}
.rawInput 0

int __my_i = 10
// CHECK: (int) 10
OverloadedF(__my_i)
// CHECK: (int const) 110
TemplatedF(__my_i)
// CHECK: (int const) 110

// .rawInput 1
//   struct Outer { struct Inner { static int i; }; }; struct Outer {};
// namespace Outer { struct Inner { static int i; }; };
// .rawInput 0
// Outer::Inner::i = 12;
.q
<|endoftext|>


<commit_before>/*
 * DeviceManager.cpp
 *
 The device manager keeps a list of all devices which are installed into the system.
 Anything that needs either a tick handler, a canbus handler, or to communicate to other
 devices on the system must be registered with the manager. The manager then handles
 making sure the tick handler is set up (if needed), the canbus handler is set up (if need),
 and that a device can send information to other devices by either type (BMS, motor ctrl, etc)
 or by device ID.

 The device class itself has the handlers defined so the tick and canbus handling code
 need only call these existing functions but the manager interface needs to
 expose a way to register them with the system.

 Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 */

#include "DeviceManager.h"

DeviceManager *DeviceManager::deviceManager = NULL;

DeviceManager::DeviceManager() {
	throttle = NULL;
	brake = NULL;
	motorController = NULL;
	for (int i = 0; i < CFG_DEV_MGR_MAX_DEVICES; i++)
		devices[i] = NULL;
}

/*
 * Get the instance of the DeviceManager (singleton pattern)
 *
 * Note: It's a simple singleton implementation - no worries about
 * thread-safety and memory-leaks, this object lives as long as the
 * Arduino has power.
 */
DeviceManager *DeviceManager::getInstance() {
	if (deviceManager == NULL)
		deviceManager = new DeviceManager();
	return deviceManager;
}

/*
 * Add the specified device to the list of registered devices
 */
void DeviceManager::addDevice(Device *device) {
	if (findDevice(device) == -1) {
		int8_t i = findDevice(NULL);
		if (i != -1) {
			devices[i] = device;
		} else {
			Logger::error("unable to register device, max number of devices reached.");
		}
	}
	switch (device->getType()) {
	case Device::DEVICE_THROTTLE:
		throttle = (Throttle *) device;
		break;
	case Device::DEVICE_BRAKE:
		brake = (Throttle *) device;
		break;
	case Device::DEVICE_MOTORCTRL:
		motorController = (MotorController *) device;
		break;
	}
}

/*
 * Remove the specified device from the list of registered devices
 */
void DeviceManager::removeDevice(Device *device) {
	int8_t i = findDevice(NULL);
	if (i != -1)
		devices[i] = NULL;
	switch (device->getType()) {
	case Device::DEVICE_THROTTLE:
		throttle = NULL;
		break;
	case Device::DEVICE_BRAKE:
		brake = NULL;
		break;
	case Device::DEVICE_MOTORCTRL:
		motorController = NULL;
		break;
	}
}

/*Add a new tick handler to the specified device. It should
 //technically be possible to register for multiple intervals
 //and be called for all of them but support for that is not
 //immediately necessary
 */
//void DeviceManager::addTickObserver(TickObserver *observer, uint32_t frequency) {
//}

/*Add a new filter that sends frames through to the device. There definitely has
 to be support for multiple filters per device right from the beginning.
 Mask, id, ext form the filter. canbus sets whether to attach to
 CAN0 or CAN1.
 */
//void addCanObserver(CanObserver *observer, uint32_t id, uint32_t mask, bool extended, CanHandler::CanBusNode canBus) {
//}

/*
 Send an inter-device message. Devtype has to be filled out but could be DEVICE_ANY.
 If devId is anything other than INVALID (0xFFFF) then the message will be targetted to only
 one device. Otherwise it will broadcast to any device that matches the device type (or all
 devices in the case of DEVICE_ANY).
 DeviceManager.h has a list of standard message types but you're allowed to send
 whatever you want. The standard message types are to enforce standard messages for easy
 intercommunication.
 */
void DeviceManager::sendMessage(Device::DeviceType devType, Device::DeviceId devId, uint32_t msgType, void* message)
		{
}

uint8_t DeviceManager::getNumThrottles() {
	return countDeviceType(Device::DEVICE_THROTTLE);
}

uint8_t DeviceManager::getNumControllers() {
	return countDeviceType(Device::DEVICE_MOTORCTRL);
}

uint8_t DeviceManager::getNumBMS() {
	return countDeviceType(Device::DEVICE_BMS);
}

uint8_t DeviceManager::getNumChargers() {
	return countDeviceType(Device::DEVICE_CHARGER);
}

uint8_t DeviceManager::getNumDisplays() {
	return countDeviceType(Device::DEVICE_DISPLAY);
}

Throttle *DeviceManager::getAccelerator() {
	return throttle;
}

Throttle *DeviceManager::getBrake() {
	return brake;
}

MotorController *DeviceManager::getMotorController() {
	return motorController;
}

/*
 * Find the position of a device in the devices array
 * /retval the position of the device or -1 if not found.
 */
int8_t DeviceManager::findDevice(Device *device) {
	for (int i = 0; i < CFG_DEV_MGR_MAX_DEVICES; i++) {
		if (device == devices[i])
			return i;
	}
	return -1;
}

/*
 * Count the number of registered devices of a certain type.
 */
uint8_t DeviceManager::countDeviceType(Device::DeviceType deviceType) {
	uint8_t count = 0;
	for (int i = 0; i < CFG_DEV_MGR_MAX_DEVICES; i++) {
		if (devices[i]->getType() == deviceType)
			count++;
	}
	return count;
}
<commit_msg>Made the DeviceManager functions that return a pointer to the current brake, throttle, and motor controller also instantiate a dummy object if nothing existed so that there is always an object to call even if it does nothing.<commit_after>/*
 * DeviceManager.cpp
 *
 The device manager keeps a list of all devices which are installed into the system.
 Anything that needs either a tick handler, a canbus handler, or to communicate to other
 devices on the system must be registered with the manager. The manager then handles
 making sure the tick handler is set up (if needed), the canbus handler is set up (if need),
 and that a device can send information to other devices by either type (BMS, motor ctrl, etc)
 or by device ID.

 The device class itself has the handlers defined so the tick and canbus handling code
 need only call these existing functions but the manager interface needs to
 expose a way to register them with the system.

 Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 */

#include "DeviceManager.h"

DeviceManager *DeviceManager::deviceManager = NULL;

DeviceManager::DeviceManager() {
	throttle = NULL;
	brake = NULL;
	motorController = NULL;
	for (int i = 0; i < CFG_DEV_MGR_MAX_DEVICES; i++)
		devices[i] = NULL;
}

/*
 * Get the instance of the DeviceManager (singleton pattern)
 *
 * Note: It's a simple singleton implementation - no worries about
 * thread-safety and memory-leaks, this object lives as long as the
 * Arduino has power.
 */
DeviceManager *DeviceManager::getInstance() {
	if (deviceManager == NULL)
		deviceManager = new DeviceManager();
	return deviceManager;
}

/*
 * Add the specified device to the list of registered devices
 */
void DeviceManager::addDevice(Device *device) {
	if (findDevice(device) == -1) {
		int8_t i = findDevice(NULL);
		if (i != -1) {
			devices[i] = device;
		} else {
			Logger::error("unable to register device, max number of devices reached.");
		}
	}
	switch (device->getType()) {
	case Device::DEVICE_THROTTLE:
		throttle = (Throttle *) device;
		break;
	case Device::DEVICE_BRAKE:
		brake = (Throttle *) device;
		break;
	case Device::DEVICE_MOTORCTRL:
		motorController = (MotorController *) device;
		break;
	}
}

/*
 * Remove the specified device from the list of registered devices
 */
void DeviceManager::removeDevice(Device *device) {
	int8_t i = findDevice(NULL);
	if (i != -1)
		devices[i] = NULL;
	switch (device->getType()) {
	case Device::DEVICE_THROTTLE:
		throttle = NULL;
		break;
	case Device::DEVICE_BRAKE:
		brake = NULL;
		break;
	case Device::DEVICE_MOTORCTRL:
		motorController = NULL;
		break;
	}
}

/*Add a new tick handler to the specified device. It should
 //technically be possible to register for multiple intervals
 //and be called for all of them but support for that is not
 //immediately necessary
 */
//void DeviceManager::addTickObserver(TickObserver *observer, uint32_t frequency) {
//}

/*Add a new filter that sends frames through to the device. There definitely has
 to be support for multiple filters per device right from the beginning.
 Mask, id, ext form the filter. canbus sets whether to attach to
 CAN0 or CAN1.
 */
//void addCanObserver(CanObserver *observer, uint32_t id, uint32_t mask, bool extended, CanHandler::CanBusNode canBus) {
//}

/*
 Send an inter-device message. Devtype has to be filled out but could be DEVICE_ANY.
 If devId is anything other than INVALID (0xFFFF) then the message will be targetted to only
 one device. Otherwise it will broadcast to any device that matches the device type (or all
 devices in the case of DEVICE_ANY).
 DeviceManager.h has a list of standard message types but you're allowed to send
 whatever you want. The standard message types are to enforce standard messages for easy
 intercommunication.
 */
void DeviceManager::sendMessage(Device::DeviceType devType, Device::DeviceId devId, uint32_t msgType, void* message)
		{
}

uint8_t DeviceManager::getNumThrottles() {
	return countDeviceType(Device::DEVICE_THROTTLE);
}

uint8_t DeviceManager::getNumControllers() {
	return countDeviceType(Device::DEVICE_MOTORCTRL);
}

uint8_t DeviceManager::getNumBMS() {
	return countDeviceType(Device::DEVICE_BMS);
}

uint8_t DeviceManager::getNumChargers() {
	return countDeviceType(Device::DEVICE_CHARGER);
}

uint8_t DeviceManager::getNumDisplays() {
	return countDeviceType(Device::DEVICE_DISPLAY);
}

Throttle *DeviceManager::getAccelerator() {
	//if there is no throttle then instantiate a dummy throttle
	//so down range code doesn't puke
	if (!throttle)
	{
		throttle = new Throttle();
	}
	return throttle;
}

Throttle *DeviceManager::getBrake() {
	if (!brake)
	{
		brake = new Throttle();
	}
	return brake;
}

MotorController *DeviceManager::getMotorController() {
	if (!motorController)
	{
		motorController = new MotorController();
	}
	return motorController;
}

/*
 * Find the position of a device in the devices array
 * /retval the position of the device or -1 if not found.
 */
int8_t DeviceManager::findDevice(Device *device) {
	for (int i = 0; i < CFG_DEV_MGR_MAX_DEVICES; i++) {
		if (device == devices[i])
			return i;
	}
	return -1;
}

/*
 * Count the number of registered devices of a certain type.
 */
uint8_t DeviceManager::countDeviceType(Device::DeviceType deviceType) {
	uint8_t count = 0;
	for (int i = 0; i < CFG_DEV_MGR_MAX_DEVICES; i++) {
		if (devices[i]->getType() == deviceType)
			count++;
	}
	return count;
}
<|endoftext|>