summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-15 21:50:28 +0000
committergspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-15 21:50:28 +0000
commitd4a7cc0322939beab17c17f7b6d5155115047a42 (patch)
treef5f2d9a17c9d5b805d3de7bf746906e708ccca3f
parentd3055ce66417c6117c31e81d8d841c4fe4ba1fa9 (diff)
downloadchromium_src-d4a7cc0322939beab17c17f7b6d5155115047a42.zip
chromium_src-d4a7cc0322939beab17c17f7b6d5155115047a42.tar.gz
chromium_src-d4a7cc0322939beab17c17f7b6d5155115047a42.tar.bz2
Merge 62679 [2nd try] - This adds a plugin selection policy for
selecting which plugin is allowed for a particular domain. It is only used on ChromeOS. It reads from a file that is installed in a known location on ChromeOS, and uses that as it's policy. When there are multiple plugins supporting the same mime-type, the appropriate plugin file to load is now selected based on policy. BUG=http://crosbug.com/7403 TEST=ran new unit test, tested on device. Review URL: http://codereview.chromium.org/3717005 TBR=gspencer@chromium.org Review URL: http://codereview.chromium.org/3814008 git-svn-id: svn://svn.chromium.org/chrome/branches/552/src@62800 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/plugin_selection_policy.cc166
-rw-r--r--chrome/browser/chromeos/plugin_selection_policy.h79
-rw-r--r--chrome/browser/chromeos/plugin_selection_policy_unittest.cc270
-rw-r--r--chrome/browser/plugin_service.cc80
-rw-r--r--chrome/browser/plugin_service.h38
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc28
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h1
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi3
-rw-r--r--chrome/common/render_messages_internal.h35
-rw-r--r--chrome/renderer/render_view.cc46
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc3
12 files changed, 687 insertions, 64 deletions
diff --git a/chrome/browser/chromeos/plugin_selection_policy.cc b/chrome/browser/chromeos/plugin_selection_policy.cc
new file mode 100644
index 0000000..b27bc42
--- /dev/null
+++ b/chrome/browser/chromeos/plugin_selection_policy.cc
@@ -0,0 +1,166 @@
+// Copyright (c) 2010 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/chromeos/plugin_selection_policy.h"
+
+#include <algorithm>
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "base/auto_reset.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "chrome/browser/browser_thread.h"
+#include "googleurl/src/gurl.h"
+
+#if !defined(OS_CHROMEOS)
+#error This file is meant to be compiled on ChromeOS only.
+#endif
+
+using std::vector;
+using std::string;
+using std::pair;
+using std::map;
+
+namespace chromeos {
+
+static const char kPluginSelectionPolicyFile[] =
+ "/usr/share/chromeos-assets/flash/plugin_policy";
+
+PluginSelectionPolicy::PluginSelectionPolicy() : initialized_(false) {
+}
+
+void PluginSelectionPolicy::StartInit() {
+ // Initialize the policy on the FILE thread, since it reads from a
+ // policy file.
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &chromeos::PluginSelectionPolicy::Init));
+}
+
+bool PluginSelectionPolicy::Init() {
+ return InitFromFile(FilePath(kPluginSelectionPolicyFile));
+}
+
+bool PluginSelectionPolicy::InitFromFile(const FilePath& policy_file) {
+ // This must always be called from the FILE thread.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ // Note: We're "initialized" even if loading the file fails.
+ initialized_ = true;
+
+ string data;
+ // This should be a really small file, so we're OK with just
+ // slurping it.
+ if (!file_util::ReadFileToString(policy_file, &data)) {
+ LOG(ERROR) << "Unable to read plugin policy file \""
+ << policy_file.value() << "\".";
+ return false;
+ }
+
+ std::istringstream input_stream(data);
+ string line;
+ map<string, Policy> policies;
+ Policy policy;
+ string last_plugin;
+
+ while (std::getline(input_stream, line)) {
+ // Strip comments.
+ string::size_type pos = line.find("#");
+ if (pos != string::npos) {
+ line = line.substr(0, pos);
+ }
+ TrimWhitespaceASCII(line, TRIM_ALL, &line);
+ if (line.find("allow") == 0) {
+ // Has to be preceeded by a "plugin" statement.
+ if (last_plugin.empty()) {
+ LOG(ERROR) << "Plugin policy file error: 'allow' out of context.";
+ return false;
+ }
+ line = line.substr(6);
+ TrimWhitespaceASCII(line, TRIM_ALL, &line);
+ line = StringToLowerASCII(line);
+ policy.push_back(make_pair(true, line));
+ }
+ if (line.find("deny") == 0) {
+ // Has to be preceeded by a "plugin" statement.
+ if (last_plugin.empty()) {
+ LOG(ERROR) << "Plugin policy file error: 'deny' out of context.";
+ return false;
+ }
+ line = line.substr(5);
+ TrimWhitespaceASCII(line, TRIM_ALL, &line);
+ line = StringToLowerASCII(line);
+ policy.push_back(make_pair(false, line));
+ }
+ if (line.find("plugin") == 0) {
+ line = line.substr(7);
+ TrimWhitespaceASCII(line, TRIM_ALL, &line);
+ if (!policy.empty() && !last_plugin.empty())
+ policies.insert(make_pair(last_plugin, policy));
+ last_plugin = line;
+ policy.clear();
+ }
+ }
+
+ if (!last_plugin.empty())
+ policies.insert(make_pair(last_plugin, policy));
+
+ policies_.swap(policies);
+ return true;
+}
+
+int PluginSelectionPolicy::FindFirstAllowed(
+ const GURL& url,
+ const std::vector<WebPluginInfo>& info) {
+ for (std::vector<WebPluginInfo>::size_type i = 0; i < info.size(); ++i) {
+ if (IsAllowed(url, info[i].path))
+ return i;
+ }
+ return -1;
+}
+
+bool PluginSelectionPolicy::IsAllowed(const GURL& url,
+ const FilePath& path) {
+ // This must always be called from the FILE thread, to be sure
+ // initialization doesn't happen at the same time.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ // Make sure that we notice if this starts being called before
+ // initialization is complete. Right now it is guaranteed only by
+ // the startup order and the fact that InitFromFile runs on the FILE
+ // thread too.
+ DCHECK(initialized_) << "Tried to check policy before policy is initialized.";
+
+ string name = path.BaseName().value();
+
+ PolicyMap::iterator policy_iter = policies_.find(name);
+ if (policy_iter != policies_.end()) {
+ Policy& policy(policy_iter->second);
+
+ // We deny by default. (equivalent to "deny" at the top of the section)
+ bool allow = false;
+
+ for (Policy::iterator iter = policy.begin(); iter != policy.end(); ++iter) {
+ bool policy_allow = iter->first;
+ string& policy_domain = iter->second;
+ if (policy_domain.empty() || url.DomainIs(policy_domain.c_str(),
+ policy_domain.size())) {
+ allow = policy_allow;
+ }
+ }
+ return allow;
+ }
+
+ // If it's not in the policy file, then we assume it's OK to allow
+ // it.
+ return true;
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/plugin_selection_policy.h b/chrome/browser/chromeos/plugin_selection_policy.h
new file mode 100644
index 0000000..4786e3c
--- /dev/null
+++ b/chrome/browser/chromeos/plugin_selection_policy.h
@@ -0,0 +1,79 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_PLUGIN_SELECTION_POLICY_H_
+#define CHROME_BROWSER_CHROMEOS_PLUGIN_SELECTION_POLICY_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/gtest_prod_util.h"
+#include "base/ref_counted.h"
+#include "webkit/glue/plugins/webplugininfo.h"
+
+class GURL;
+class FilePath;
+
+namespace chromeos {
+
+#if !defined(OS_CHROMEOS)
+#error This file is meant to be compiled on ChromeOS only.
+#endif
+
+// This class is used to provide logic for selection of a plugin
+// executable path in the browser. It loads a policy file for
+// selection of particular plugins based on the domain they are be
+// instantiated for. It is used by the PluginService. It is (and
+// should be) only used for ChromeOS.
+
+// The functions in this class must only be called on the FILE thread
+// (and will DCHECK if they aren't).
+
+class PluginSelectionPolicy
+ : public base::RefCountedThreadSafe<PluginSelectionPolicy> {
+ public:
+ PluginSelectionPolicy();
+
+ // This should be called before any other method. This starts the
+ // process of initialization on the FILE thread.
+ void StartInit();
+
+ // Returns the first allowed plugin in the given vector of plugin
+ // information. Returns -1 if no plugins in the info vector are
+ // allowed (or if the info vector is empty). InitFromFile must
+ // complete before any calls to FindFirstAllowed happen or it will
+ // assert.
+ int FindFirstAllowed(const GURL& url, const std::vector<WebPluginInfo>& info);
+
+ // Applies the current policy to the given path using the url to
+ // look up what the policy for that domain is. Returns true if the
+ // given plugin is allowed for that domain. InitFromFile must
+ // complete before any calls to IsAllowed happen or it will assert.
+ bool IsAllowed(const GURL& url, const FilePath& path);
+
+ private:
+ // To allow access to InitFromFile
+ FRIEND_TEST_ALL_PREFIXES(PluginSelectionPolicyTest, Basic);
+ FRIEND_TEST_ALL_PREFIXES(PluginSelectionPolicyTest, InitFromFile);
+ FRIEND_TEST_ALL_PREFIXES(PluginSelectionPolicyTest, IsAllowed);
+ FRIEND_TEST_ALL_PREFIXES(PluginSelectionPolicyTest, FindFirstAllowed);
+
+ // Initializes from the default policy file.
+ bool Init();
+
+ // Initializes from the given file.
+ bool InitFromFile(const FilePath& policy_file);
+
+ typedef std::vector<std::pair<bool, std::string> > Policy;
+ typedef std::map<std::string, Policy> PolicyMap;
+
+ PolicyMap policies_;
+ bool initialized_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginSelectionPolicy);
+};
+
+} // namespace chromeos
+#endif // CHROME_BROWSER_CHROMEOS_PLUGIN_SELECTION_POLICY_H_
diff --git a/chrome/browser/chromeos/plugin_selection_policy_unittest.cc b/chrome/browser/chromeos/plugin_selection_policy_unittest.cc
new file mode 100644
index 0000000..455ed37
--- /dev/null
+++ b/chrome/browser/chromeos/plugin_selection_policy_unittest.cc
@@ -0,0 +1,270 @@
+// Copyright (c) 2010 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/chromeos/plugin_selection_policy.h"
+
+#include <string>
+#include <vector>
+
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/ref_counted.h"
+#include "base/scoped_temp_dir.h"
+#include "chrome/browser/browser_thread.h"
+#include "googleurl/src/gurl.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+using std::string;
+using std::vector;
+
+#if !defined(OS_CHROMEOS)
+#error This file is meant to be compiled on ChromeOS only.
+#endif
+
+namespace chromeos {
+
+const char kBasicPolicy[] = "# This is a basic policy\n"
+ "plugin test.so\n"
+ "allow foo.com\n"
+ "deny bar.com\n";
+
+const char kNoPluginPolicy[] = "# This is a policy with missing plugin.\n"
+ "# Missing plugin test.so\n"
+ "allow foo.com\n"
+ "deny bar.com\n";
+const char kNoRulesPolicy[] = "# This is a policy with no rules\n"
+ "plugin test.so\n";
+
+const char kEmptyPolicy[] = "# This is an empty policy\n";
+
+const char kCommentTestPolicy[] = "# This is a policy with inline comments.\n"
+ "plugin test.so# like this\n"
+ "allow foo.com # and this\n"
+ "deny bar.com # and this\n";
+
+const char kMultiPluginTestPolicy[] =
+ "# This is a policy with multiple plugins.\n"
+ "plugin allow_foo.so\n"
+ "allow foo.com\n"
+ "deny bar.com\n"
+ "plugin allow_baz_bim1.so\n"
+ "deny google.com\n"
+ "allow baz.com\n"
+ "allow bim.com\n"
+ "plugin allow_baz_bim2.so\n"
+ "deny google.com\n"
+ "allow baz.com\n"
+ "allow bim.com\n";
+
+const char kWhitespaceTestPolicy[] = "# This is a policy with odd whitespace.\n"
+ " plugin\ttest.so# like this\n"
+ "\n\n \n allow\t\tfoo.com # and this\n"
+ "\tdeny bar.com\t\t\t# and this \n";
+
+class PluginSelectionPolicyTest : public PlatformTest {
+ public:
+ PluginSelectionPolicyTest()
+ : loop_(MessageLoop::TYPE_DEFAULT),
+ file_thread_(BrowserThread::FILE, &loop_) {}
+
+ virtual void SetUp() {
+ PlatformTest::SetUp();
+ // Create a policy file to test with.
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ }
+
+ protected:
+ bool CreatePolicy(const std::string& name,
+ const std::string& contents,
+ FilePath* path) {
+ FilePath policy_file(temp_dir_.path());
+ policy_file = policy_file.Append(FilePath(name));
+ int bytes_written = file_util::WriteFile(policy_file,
+ contents.c_str(),
+ contents.size());
+ if (path)
+ *path = policy_file;
+ return bytes_written >= 0;
+ }
+
+ private:
+ ScopedTempDir temp_dir_;
+ MessageLoop loop_;
+ BrowserThread file_thread_;
+};
+
+TEST_F(PluginSelectionPolicyTest, Basic) {
+ FilePath path;
+ ASSERT_TRUE(CreatePolicy("basic", kBasicPolicy, &path));
+ scoped_refptr<PluginSelectionPolicy> policy = new PluginSelectionPolicy;
+ EXPECT_TRUE(policy->InitFromFile(path));
+}
+
+TEST_F(PluginSelectionPolicyTest, InitFromFile) {
+ {
+ FilePath path;
+ ASSERT_TRUE(CreatePolicy("basic", kBasicPolicy, &path));
+ scoped_refptr<PluginSelectionPolicy> policy = new PluginSelectionPolicy;
+ EXPECT_TRUE(policy->InitFromFile(path));
+ }
+
+ {
+ FilePath path;
+ ASSERT_TRUE(CreatePolicy("no_plugin", kNoPluginPolicy, &path));
+ scoped_refptr<PluginSelectionPolicy> policy = new PluginSelectionPolicy;
+ EXPECT_FALSE(policy->InitFromFile(path));
+ }
+
+ {
+ FilePath path;
+ ASSERT_TRUE(CreatePolicy("no_rules", kNoRulesPolicy, &path));
+ scoped_refptr<PluginSelectionPolicy> policy = new PluginSelectionPolicy;
+ EXPECT_TRUE(policy->InitFromFile(path));
+ }
+
+ {
+ FilePath path;
+ ASSERT_TRUE(CreatePolicy("empty", kEmptyPolicy, &path));
+ scoped_refptr<PluginSelectionPolicy> policy = new PluginSelectionPolicy;
+ EXPECT_TRUE(policy->InitFromFile(path));
+ }
+
+ {
+ FilePath path;
+ ASSERT_TRUE(CreatePolicy("comment", kCommentTestPolicy, &path));
+ scoped_refptr<PluginSelectionPolicy> policy = new PluginSelectionPolicy;
+ EXPECT_TRUE(policy->InitFromFile(path));
+ }
+
+ {
+ FilePath path;
+ ASSERT_TRUE(CreatePolicy("comment", kMultiPluginTestPolicy, &path));
+ scoped_refptr<PluginSelectionPolicy> policy = new PluginSelectionPolicy;
+ EXPECT_TRUE(policy->InitFromFile(path));
+ }
+
+ {
+ FilePath path;
+ ASSERT_TRUE(CreatePolicy("whitespace", kWhitespaceTestPolicy, &path));
+ scoped_refptr<PluginSelectionPolicy> policy = new PluginSelectionPolicy;
+ EXPECT_TRUE(policy->InitFromFile(path));
+ }
+}
+
+TEST_F(PluginSelectionPolicyTest, IsAllowed) {
+ FilePath path;
+ ASSERT_TRUE(CreatePolicy("basic", kBasicPolicy, &path));
+
+ scoped_refptr<PluginSelectionPolicy> policy1 = new PluginSelectionPolicy;
+ ASSERT_TRUE(policy1->InitFromFile(path));
+ EXPECT_TRUE(policy1->IsAllowed(GURL("http://www.foo.com/blah.html"),
+ FilePath("/usr/local/bin/test.so")));
+ EXPECT_FALSE(policy1->IsAllowed(GURL("http://www.bar.com/blah.html"),
+ FilePath("/usr/local/bin/test.so")));
+ EXPECT_FALSE(policy1->IsAllowed(GURL("http://www.baz.com/blah.html"),
+ FilePath("/usr/local/bin/test.so")));
+ EXPECT_TRUE(policy1->IsAllowed(GURL("http://www.baz.com/blah.html"),
+ FilePath("/usr/local/bin/real.so")));
+
+ scoped_refptr<PluginSelectionPolicy> policy2 = new PluginSelectionPolicy;
+ ASSERT_TRUE(CreatePolicy("no_rules", kNoRulesPolicy, &path));
+ ASSERT_TRUE(policy2->InitFromFile(path));
+ EXPECT_FALSE(policy2->IsAllowed(GURL("http://www.foo.com/blah.html"),
+ FilePath("/usr/local/bin/test.so")));
+ EXPECT_FALSE(policy2->IsAllowed(GURL("http://www.bar.com/blah.html"),
+ FilePath("/usr/local/bin/test.so")));
+ EXPECT_FALSE(policy2->IsAllowed(GURL("http://www.baz.com/blah.html"),
+ FilePath("/usr/local/bin/test.so")));
+ EXPECT_TRUE(policy2->IsAllowed(GURL("http://www.baz.com/blah.html"),
+ FilePath("/usr/local/bin/real.so")));
+
+ scoped_refptr<PluginSelectionPolicy> policy3 = new PluginSelectionPolicy;
+ ASSERT_TRUE(CreatePolicy("empty", kEmptyPolicy, &path));
+ ASSERT_TRUE(policy3->InitFromFile(path));
+ EXPECT_TRUE(policy3->IsAllowed(GURL("http://www.foo.com/blah.html"),
+ FilePath("/usr/local/bin/test.so")));
+ EXPECT_TRUE(policy3->IsAllowed(GURL("http://www.bar.com/blah.html"),
+ FilePath("/usr/local/bin/test.so")));
+ EXPECT_TRUE(policy3->IsAllowed(GURL("http://www.baz.com/blah.html"),
+ FilePath("/usr/local/bin/test.so")));
+ EXPECT_TRUE(policy3->IsAllowed(GURL("http://www.baz.com/blah.html"),
+ FilePath("/usr/local/bin/real.so")));
+}
+
+TEST_F(PluginSelectionPolicyTest, FindFirstAllowed) {
+ FilePath path;
+ ASSERT_TRUE(CreatePolicy("multi", kMultiPluginTestPolicy, &path));
+ scoped_refptr<PluginSelectionPolicy> policy = new PluginSelectionPolicy;
+ ASSERT_TRUE(policy->InitFromFile(path));
+ EXPECT_TRUE(policy->IsAllowed(GURL("http://www.foo.com/blah.html"),
+ FilePath("/usr/local/bin/allow_foo.so")));
+ EXPECT_FALSE(policy->IsAllowed(GURL("http://www.bar.com/blah.html"),
+ FilePath("/usr/local/bin/allow_foo.so")));
+ EXPECT_FALSE(policy->IsAllowed(GURL("http://www.baz.com/blah.html"),
+ FilePath("/usr/local/bin/allow_foo.so")));
+ EXPECT_FALSE(policy->IsAllowed(GURL("http://www.bim.com/blah.html"),
+ FilePath("/usr/local/bin/allow_foo.so")));
+ EXPECT_FALSE(policy->IsAllowed(GURL("http://www.foo.com/blah.html"),
+ FilePath("/usr/local/bin/allow_baz_bim1.so")));
+ EXPECT_FALSE(policy->IsAllowed(GURL("http://www.bar.com/blah.html"),
+ FilePath("/usr/local/bin/allow_baz_bim1.so")));
+ EXPECT_TRUE(policy->IsAllowed(GURL("http://www.baz.com/blah.html"),
+ FilePath("/usr/local/bin/allow_baz_bim1.so")));
+ EXPECT_TRUE(policy->IsAllowed(GURL("http://www.bim.com/blah.html"),
+ FilePath("/usr/local/bin/allow_baz_bim1.so")));
+ EXPECT_FALSE(policy->IsAllowed(GURL("http://www.google.com/blah.html"),
+ FilePath("/usr/local/bin/allow_baz_bim1.so")));
+ EXPECT_FALSE(policy->IsAllowed(GURL("http://www.foo.com/blah.html"),
+ FilePath("/usr/local/bin/allow_baz_bim2.so")));
+ EXPECT_FALSE(policy->IsAllowed(GURL("http://www.bar.com/blah.html"),
+ FilePath("/usr/local/bin/allow_baz_bim2.so")));
+ EXPECT_TRUE(policy->IsAllowed(GURL("http://www.baz.com/blah.html"),
+ FilePath("/usr/local/bin/allow_baz_bim2.so")));
+ EXPECT_TRUE(policy->IsAllowed(GURL("http://www.bim.com/blah.html"),
+ FilePath("/usr/local/bin/allow_baz_bim2.so")));
+ EXPECT_FALSE(policy->IsAllowed(GURL("http://www.google.com/blah.html"),
+ FilePath("/usr/local/bin/allow_baz_bim2.so")));
+ std::vector<WebPluginInfo> info_vector;
+ WebPluginInfo info;
+ // First we test that the one without any policy gets
+ // selected for all if it's first.
+ info.path = FilePath("/usr/local/bin/no_policy.so");
+ info_vector.push_back(info);
+ info.path = FilePath("/usr/local/bin/allow_foo.so");
+ info_vector.push_back(info);
+ info.path = FilePath("/usr/local/bin/allow_baz_bim1.so");
+ info_vector.push_back(info);
+ info.path = FilePath("/usr/local/bin/allow_baz_bim2.so");
+ info_vector.push_back(info);
+ EXPECT_EQ(0, policy->FindFirstAllowed(GURL("http://www.baz.com/blah.html"),
+ info_vector));
+ EXPECT_EQ(0, policy->FindFirstAllowed(GURL("http://www.foo.com/blah.html"),
+ info_vector));
+ EXPECT_EQ(0, policy->FindFirstAllowed(GURL("http://www.bling.com/blah.html"),
+ info_vector));
+ EXPECT_EQ(0, policy->FindFirstAllowed(GURL("http://www.google.com/blah.html"),
+ info_vector));
+
+ // Now move the plugin without any policy to the end.
+ info_vector.clear();
+ info.path = FilePath("/usr/local/bin/allow_foo.so");
+ info_vector.push_back(info);
+ info.path = FilePath("/usr/local/bin/allow_baz_bim1.so");
+ info_vector.push_back(info);
+ info.path = FilePath("/usr/local/bin/allow_baz_bim2.so");
+ info_vector.push_back(info);
+ info.path = FilePath("/usr/local/bin/no_policy.so");
+ info_vector.push_back(info);
+ EXPECT_EQ(1, policy->FindFirstAllowed(GURL("http://www.baz.com/blah.html"),
+ info_vector));
+ EXPECT_EQ(0, policy->FindFirstAllowed(GURL("http://www.foo.com/blah.html"),
+ info_vector));
+ EXPECT_EQ(3, policy->FindFirstAllowed(GURL("http://www.bling.com/blah.html"),
+ info_vector));
+ EXPECT_EQ(3, policy->FindFirstAllowed(GURL("http://www.google.com/blah.html"),
+ info_vector));
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc
index e42c2ae..7b0dd47 100644
--- a/chrome/browser/plugin_service.cc
+++ b/chrome/browser/plugin_service.cc
@@ -40,6 +40,11 @@
#endif
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_list.h"
+#include "webkit/glue/plugins/webplugininfo.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/plugin_selection_policy.h"
+#endif
#if defined(OS_MACOSX)
static void NotifyPluginsOfActivation() {
@@ -123,6 +128,11 @@ PluginService::PluginService()
}
#endif
+#if defined(OS_CHROMEOS)
+ plugin_selection_policy_ = new chromeos::PluginSelectionPolicy;
+ plugin_selection_policy_->StartInit();
+#endif
+
chrome::RegisterInternalGPUPlugin();
#if defined(OS_WIN)
@@ -243,16 +253,41 @@ void PluginService::OpenChannelToPlugin(
ResourceMessageFilter* renderer_msg_filter,
const GURL& url,
const std::string& mime_type,
- const std::string& locale,
IPC::Message* reply_msg) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- bool allow_wildcard = true;
+ // The PluginList::GetFirstAllowedPluginInfo may need to load the
+ // plugins. Don't do it on the IO thread.
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(
+ this, &PluginService::GetAllowedPluginForOpenChannelToPlugin,
+ renderer_msg_filter, url, mime_type, reply_msg));
+}
+void PluginService::GetAllowedPluginForOpenChannelToPlugin(
+ ResourceMessageFilter* renderer_msg_filter,
+ const GURL& url,
+ const std::string& mime_type,
+ IPC::Message* reply_msg) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
WebPluginInfo info;
+ bool found = GetFirstAllowedPluginInfo(url, mime_type, &info, NULL);
FilePath plugin_path;
- if (NPAPI::PluginList::Singleton()->GetPluginInfo(
- url, mime_type, allow_wildcard, &info, NULL) && info.enabled) {
- plugin_path = info.path;
- }
+ if (found && info.enabled)
+ plugin_path = FilePath(info.path);
+ // Now we jump back to the IO thread to finish opening the channel.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ this, &PluginService::FinishOpenChannelToPlugin,
+ renderer_msg_filter, mime_type, plugin_path, reply_msg));
+}
+
+void PluginService::FinishOpenChannelToPlugin(
+ ResourceMessageFilter* renderer_msg_filter,
+ const std::string& mime_type,
+ const FilePath& plugin_path,
+ IPC::Message* reply_msg) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
PluginProcessHost* plugin_host = FindOrStartPluginProcess(plugin_path);
if (plugin_host) {
plugin_host->OpenChannelToPlugin(renderer_msg_filter, mime_type, reply_msg);
@@ -262,6 +297,37 @@ void PluginService::OpenChannelToPlugin(
}
}
+bool PluginService::GetFirstAllowedPluginInfo(
+ const GURL& url,
+ const std::string& mime_type,
+ WebPluginInfo* info,
+ std::string* actual_mime_type) {
+ // GetPluginInfoArray may need to load the plugins, so we need to be
+ // on the FILE thread.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ bool allow_wildcard = true;
+#if defined(OS_CHROMEOS)
+ std::vector<WebPluginInfo> info_array;
+ std::vector<std::string> actual_mime_types;
+ NPAPI::PluginList::Singleton()->GetPluginInfoArray(
+ url, mime_type, allow_wildcard, &info_array, &actual_mime_types);
+
+ // Now we filter by the plugin selection policy.
+ int allowed_index = plugin_selection_policy_->FindFirstAllowed(url,
+ info_array);
+ if (!info_array.empty() && allowed_index >= 0) {
+ *info = info_array[allowed_index];
+ if (actual_mime_type)
+ *actual_mime_type = actual_mime_types[allowed_index];
+ return true;
+ }
+ return false;
+#else
+ return NPAPI::PluginList::Singleton()->GetPluginInfo(
+ url, mime_type, allow_wildcard, info, actual_mime_type);
+#endif
+}
+
static void PurgePluginListCache(bool reload_pages) {
for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
!it.IsAtEnd(); it.Advance()) {
diff --git a/chrome/browser/plugin_service.h b/chrome/browser/plugin_service.h
index 3f25c25..9ff7988 100644
--- a/chrome/browser/plugin_service.h
+++ b/chrome/browser/plugin_service.h
@@ -25,6 +25,12 @@
#include "base/scoped_ptr.h"
#endif
+#if defined(OS_CHROMEOS)
+namespace chromeos {
+class PluginSelectionPolicy;
+}
+#endif
+
namespace IPC {
class Message;
}
@@ -32,9 +38,10 @@ class Message;
class MessageLoop;
class PluginProcessHost;
class Profile;
-class URLRequestContext;
class ResourceDispatcherHost;
class ResourceMessageFilter;
+class URLRequestContext;
+struct WebPluginInfo;
// This must be created on the main thread but it's only called on the IO/file
// thread.
@@ -78,9 +85,15 @@ class PluginService
void OpenChannelToPlugin(ResourceMessageFilter* renderer_msg_filter,
const GURL& url,
const std::string& mime_type,
- const std::string& locale,
IPC::Message* reply_msg);
+ // Gets the first allowed plugin in the list of plugins that matches
+ // the given url and mime type. Must be called on the FILE thread.
+ bool GetFirstAllowedPluginInfo(const GURL& url,
+ const std::string& mime_type,
+ WebPluginInfo* info,
+ std::string* actual_mime_type);
+
// Returns true if the given plugin is allowed to be used by a page with
// the given URL.
bool PrivatePluginAllowedForURL(const FilePath& plugin_path, const GURL& url);
@@ -111,6 +124,21 @@ class PluginService
void RegisterPepperPlugins();
+ // Helper so we can do the plugin lookup on the FILE thread.
+ void GetAllowedPluginForOpenChannelToPlugin(
+ ResourceMessageFilter* renderer_msg_filter,
+ const GURL& url,
+ const std::string& mime_type,
+ IPC::Message* reply_msg);
+
+ // Helper so we can finish opening the channel after looking up the
+ // plugin.
+ void FinishOpenChannelToPlugin(
+ ResourceMessageFilter* renderer_msg_filter,
+ const std::string& mime_type,
+ const FilePath& plugin_path,
+ IPC::Message* reply_msg);
+
// mapping between plugin path and PluginProcessHost
typedef base::hash_map<FilePath, PluginProcessHost*> PluginMap;
PluginMap plugin_hosts_;
@@ -134,6 +162,10 @@ class PluginService
NotificationRegistrar registrar_;
+#if defined(OS_CHROMEOS)
+ scoped_refptr<chromeos::PluginSelectionPolicy> plugin_selection_policy_;
+#endif
+
#if defined(OS_WIN)
// Registry keys for getting notifications when new plugins are installed.
RegKey hkcu_key_;
@@ -150,4 +182,6 @@ class PluginService
DISALLOW_COPY_AND_ASSIGN(PluginService);
};
+DISABLE_RUNNABLE_METHOD_REFCOUNT(PluginService);
+
#endif // CHROME_BROWSER_PLUGIN_SERVICE_H_
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 1c5e569..d1398d6 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -10,13 +10,13 @@
#if defined(OS_POSIX)
#include "base/file_descriptor_posix.h"
#endif
-#include "base/file_util.h"
#include "base/file_path.h"
+#include "base/file_util.h"
#include "base/histogram.h"
#include "base/process_util.h"
#include "base/shared_memory.h"
-#include "base/thread.h"
#include "base/sys_string_conversions.h"
+#include "base/thread.h"
#include "base/utf_string_conversions.h"
#include "base/worker_pool.h"
#include "chrome/browser/appcache/appcache_dispatcher_host.h"
@@ -32,8 +32,8 @@
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/file_system/file_system_dispatcher_host.h"
#include "chrome/browser/file_system/file_system_host_context.h"
-#include "chrome/browser/geolocation/geolocation_permission_context.h"
#include "chrome/browser/geolocation/geolocation_dispatcher_host.h"
+#include "chrome/browser/geolocation/geolocation_permission_context.h"
#include "chrome/browser/gpu_process_host.h"
#include "chrome/browser/host_zoom_map.h"
#include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h"
@@ -44,8 +44,11 @@
#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/notifications/notifications_prefs_cache.h"
-#include "chrome/browser/plugin_updater.h"
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/plugin_selection_policy.h"
+#endif
#include "chrome/browser/plugin_service.h"
+#include "chrome/browser/plugin_updater.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/printer_query.h"
@@ -763,8 +766,8 @@ void ResourceMessageFilter::OnGetPluginInfo(const GURL& url,
const GURL& policy_url,
const std::string& mime_type,
IPC::Message* reply_msg) {
- // The PluginList::GetPluginInfo may need to load the plugins. Don't do it
- // on the IO thread.
+ // The PluginService::GetFirstAllowedPluginInfo may need to load the
+ // plugins. Don't do it on the IO thread.
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
@@ -777,11 +780,12 @@ void ResourceMessageFilter::OnGetPluginInfoOnFileThread(
const GURL& policy_url,
const std::string& mime_type,
IPC::Message* reply_msg) {
- WebPluginInfo info;
std::string actual_mime_type;
- bool allow_wildcard = true;
- bool found = NPAPI::PluginList::Singleton()->GetPluginInfo(
- url, mime_type, allow_wildcard, &info, &actual_mime_type);
+ WebPluginInfo info;
+ bool found = plugin_service_->GetFirstAllowedPluginInfo(url,
+ mime_type,
+ &info,
+ &actual_mime_type);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
NewRunnableMethod(
@@ -813,10 +817,8 @@ void ResourceMessageFilter::OnGotPluginInfo(bool found,
void ResourceMessageFilter::OnOpenChannelToPlugin(const GURL& url,
const std::string& mime_type,
- const std::string& locale,
IPC::Message* reply_msg) {
- plugin_service_->OpenChannelToPlugin(
- this, url, mime_type, locale, reply_msg);
+ plugin_service_->OpenChannelToPlugin(this, url, mime_type, reply_msg);
}
void ResourceMessageFilter::OnLaunchNaCl(
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 0123ce6..6a8bdd7 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -195,7 +195,6 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
IPC::Message* reply_msg);
void OnOpenChannelToPlugin(const GURL& url,
const std::string& mime_type,
- const std::string& locale,
IPC::Message* reply_msg);
void OnLaunchNaCl(const std::wstring& url,
int channel_descriptor,
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 3b19fd4..434b08c 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -691,6 +691,8 @@
'browser/chromeos/panels/panel_scroller_header.h',
'browser/chromeos/pipe_reader.cc',
'browser/chromeos/pipe_reader.h',
+ 'browser/chromeos/plugin_selection_policy.cc',
+ 'browser/chromeos/plugin_selection_policy.h',
'browser/chromeos/preferences.cc',
'browser/chromeos/preferences.h',
'browser/chromeos/proxy_config_service.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 326655a..2b8ffab 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -672,7 +672,7 @@
'test/webdriver/commands/session_with_id.h',
'test/webdriver/commands/session_with_id.cc',
'test/webdriver/commands/source_command.h',
- 'test/webdriver/commands/source_command.cc',
+ 'test/webdriver/commands/source_command.cc',
'test/webdriver/commands/title_command.h',
'test/webdriver/commands/title_command.cc',
'test/webdriver/commands/url_command.h',
@@ -1065,6 +1065,7 @@
'browser/chromeos/offline/offline_load_page_unittest.cc',
'browser/chromeos/options/language_config_model_unittest.cc',
'browser/chromeos/pipe_reader_unittest.cc',
+ 'browser/chromeos/plugin_selection_policy_unittest.cc',
'browser/chromeos/proxy_config_service_impl_unittest.cc',
'browser/chromeos/status/input_method_menu_unittest.cc',
'browser/chromeos/version_loader_unittest.cc',
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 2aa3e73..1307799 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -1366,19 +1366,27 @@ IPC_BEGIN_MESSAGES(ViewHost)
bool /* refresh*/,
std::vector<WebPluginInfo> /* plugins */)
- // Return information about a plugin for the given URL and MIME type. If there
- // is no matching plugin, |found| is set to false.
- // If |enabled| in the WebPluginInfo struct is false, the plug-in is basically
+ // Return information about a plugin for the given URL and MIME
+ // type. If there is no matching plugin, |found| is false. If
+ // |enabled| in the WebPluginInfo struct is false, the plug-in is
// treated as if it was not installed at all.
- // If |setting| is set to CONTENT_SETTING_BLOCK, the plug-in is blocked by the
- // content settings for |policy_url|. It still appears in navigator.plugins in
- // Javascript though, and can be loaded via click-to-play.
- // If |setting| is set to CONTENT_SETTING_ALLOW, the domain is explicitly
- // white-listed for the plug-in, or the user has chosen not to block
- // nonsandboxed plugins.
- // If |setting| is set to CONTENT_SETTING_DEFAULT, the plug-in is neither
- // blocked nor white-listed, which means that it's allowed by default and
- // can still be blocked if it's non-sandboxed.
+ //
+ // If |setting| is set to CONTENT_SETTING_BLOCK, the plug-in is
+ // blocked by the content settings for |policy_url|. It still
+ // appears in navigator.plugins in Javascript though, and can be
+ // loaded via click-to-play.
+ //
+ // If |setting| is set to CONTENT_SETTING_ALLOW, the domain is
+ // explicitly white-listed for the plug-in, or the user has chosen
+ // not to block nonsandboxed plugins.
+ //
+ // If |setting| is set to CONTENT_SETTING_DEFAULT, the plug-in is
+ // neither blocked nor white-listed, which means that it's allowed
+ // by default and can still be blocked if it's non-sandboxed.
+ //
+ // |actual_mime_type| is the actual mime type supported by the
+ // plugin found that match the URL given (one for each item in
+ // |info|).
IPC_SYNC_MESSAGE_CONTROL3_4(ViewHostMsg_GetPluginInfo,
GURL /* url */,
GURL /* policy_url */,
@@ -1524,10 +1532,9 @@ IPC_BEGIN_MESSAGES(ViewHost)
// create a plugin. The browser will create the plugin process if
// necessary, and will return a handle to the channel on success.
// On error an empty string is returned.
- IPC_SYNC_MESSAGE_CONTROL3_2(ViewHostMsg_OpenChannelToPlugin,
+ IPC_SYNC_MESSAGE_CONTROL2_2(ViewHostMsg_OpenChannelToPlugin,
GURL /* url */,
std::string /* mime_type */,
- std::string /* locale */,
IPC::ChannelHandle /* handle to channel */,
WebPluginInfo /* info */)
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index d1c19252..9118de4 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -9,8 +9,8 @@
#include <string>
#include <vector>
-#include "app/message_box_flags.h"
#include "app/l10n_util.h"
+#include "app/message_box_flags.h"
#include "app/resource_bundle.h"
#include "base/callback.h"
#include "base/command_line.h"
@@ -22,8 +22,8 @@
#include "base/singleton.h"
#include "base/string_piece.h"
#include "base/string_util.h"
-#include "base/time.h"
#include "base/sys_string_conversions.h"
+#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/common/appcache/appcache_dispatcher.h"
@@ -56,9 +56,9 @@
#include "chrome/renderer/dom_ui_bindings.h"
#include "chrome/renderer/extension_groups.h"
#include "chrome/renderer/extensions/bindings_utils.h"
-#include "chrome/renderer/extensions/extension_renderer_info.h"
#include "chrome/renderer/extensions/event_bindings.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
+#include "chrome/renderer/extensions/extension_renderer_info.h"
#include "chrome/renderer/extensions/renderer_extension_bindings.h"
#include "chrome/renderer/external_host_bindings.h"
#include "chrome/renderer/geolocation_dispatcher.h"
@@ -101,8 +101,6 @@
#include "net/base/net_errors.h"
#include "skia/ext/bitmap_platform_device.h"
#include "skia/ext/image_operations.h"
-#include "third_party/cld/encodings/compact_lang_det/win/cld_unicodetext.h"
-#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityCache.h"
#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCString.h"
@@ -111,9 +109,9 @@
#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDragData.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileChooserParams.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebFindOptions.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileSystemCallbacks.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFindOptions.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFormControlElement.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFormElement.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
@@ -126,8 +124,8 @@
#include "third_party/WebKit/WebKit/chromium/public/WebPageSerializer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPluginDocument.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPoint.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRange.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
@@ -145,6 +143,8 @@
#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
#include "third_party/WebKit/WebKit/chromium/public/WebWindowFeatures.h"
+#include "third_party/cld/encodings/compact_lang_det/win/cld_unicodetext.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "v8/include/v8.h"
#include "webkit/appcache/web_application_cache_host_impl.h"
#include "webkit/glue/context_menu.h"
@@ -182,28 +182,17 @@
#include "skia/ext/skia_utils_mac.h"
#endif
-using appcache::WebApplicationCacheHostImpl;
-using base::Time;
-using base::TimeDelta;
-using webkit_glue::AltErrorPageResourceFetcher;
-using webkit_glue::FormData;
-using webkit_glue::FormField;
-using webkit_glue::ImageResourceFetcher;
-using webkit_glue::PasswordForm;
-using webkit_glue::PasswordFormDomManager;
-using webkit_glue::SiteIsolationMetrics;
-using webkit_glue::WebAccessibility;
using WebKit::WebAccessibilityCache;
using WebKit::WebAccessibilityNotification;
using WebKit::WebAccessibilityObject;
using WebKit::WebApplicationCacheHost;
using WebKit::WebApplicationCacheHostClient;
+using WebKit::WebCString;
using WebKit::WebColor;
using WebKit::WebColorName;
using WebKit::WebConsoleMessage;
using WebKit::WebContextMenuData;
using WebKit::WebCookieJar;
-using WebKit::WebCString;
using WebKit::WebData;
using WebKit::WebDataSource;
using WebKit::WebDevToolsAgent;
@@ -255,9 +244,20 @@ using WebKit::WebURLResponse;
using WebKit::WebVector;
using WebKit::WebView;
using WebKit::WebWidget;
+using WebKit::WebWindowFeatures;
using WebKit::WebWorker;
using WebKit::WebWorkerClient;
-using WebKit::WebWindowFeatures;
+using appcache::WebApplicationCacheHostImpl;
+using base::Time;
+using base::TimeDelta;
+using webkit_glue::AltErrorPageResourceFetcher;
+using webkit_glue::FormData;
+using webkit_glue::FormField;
+using webkit_glue::ImageResourceFetcher;
+using webkit_glue::PasswordForm;
+using webkit_glue::PasswordFormDomManager;
+using webkit_glue::SiteIsolationMetrics;
+using webkit_glue::WebAccessibility;
//-----------------------------------------------------------------------------
@@ -299,10 +299,8 @@ static const int kDelaySecondsForContentStateSync = 1;
// The maximum number of popups that can be spawned from one page.
static const int kMaximumNumberOfUnacknowledgedPopups = 25;
-static const char* const kUnreachableWebDataURL =
- "chrome://chromewebdata/";
-
-static const char* const kBackForwardNavigationScheme = "history";
+static const char kUnreachableWebDataURL[] = "chrome://chromewebdata/";
+static const char kBackForwardNavigationScheme[] = "history";
static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
WebVector<WebURL> urls;
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index de4381d..5585eb7 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -274,8 +274,7 @@ bool WebPluginDelegateProxy::Initialize(const GURL& url,
bool load_manually) {
IPC::ChannelHandle channel_handle;
if (!RenderThread::current()->Send(new ViewHostMsg_OpenChannelToPlugin(
- url, mime_type_, webkit_glue::GetWebKitLocale(),
- &channel_handle, &info_))) {
+ url, mime_type_, &channel_handle, &info_))) {
return false;
}