summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-24 00:21:34 +0000
committerviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-24 00:21:34 +0000
commitcec1b8d4524bd0ce53a7b08b4263c788a5b6d72b (patch)
treec229241e080953f2ff84966f1e969747b6129268
parent50d8766af20bd48bce1094039153291e31c0e0bf (diff)
downloadchromium_src-cec1b8d4524bd0ce53a7b08b4263c788a5b6d72b.zip
chromium_src-cec1b8d4524bd0ce53a7b08b4263c788a5b6d72b.tar.gz
chromium_src-cec1b8d4524bd0ce53a7b08b4263c788a5b6d72b.tar.bz2
Implement chrome://plugins page that can disable plugins.
BUG=736 TEST=Go to chrome://plugins/. Should be able to enable/disable plugins. Enabled/disabled plugins should persist between sessions. Review URL: http://codereview.chromium.org/1085003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42412 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd41
-rw-r--r--chrome/browser/browser_main.cc6
-rw-r--r--chrome/browser/browser_prefs.cc2
-rw-r--r--chrome/browser/browser_resources.grd1
-rw-r--r--chrome/browser/dom_ui/dom_ui_factory.cc8
-rw-r--r--chrome/browser/dom_ui/plugins_ui.cc276
-rw-r--r--chrome/browser/dom_ui/plugins_ui.h24
-rw-r--r--chrome/browser/plugin_service.cc34
-rw-r--r--chrome/browser/plugin_service.h7
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc2
-rw-r--r--chrome/browser/resources/plugins.html558
-rwxr-xr-xchrome/chrome_browser.gypi2
-rw-r--r--chrome/common/pref_names.cc29
-rw-r--r--chrome/common/pref_names.h1
-rw-r--r--chrome/common/url_constants.cc4
-rw-r--r--chrome/common/url_constants.h4
-rw-r--r--webkit/glue/plugins/plugin_lib_mac.mm2
-rw-r--r--webkit/glue/plugins/plugin_lib_posix.cc1
-rw-r--r--webkit/glue/plugins/plugin_list.cc78
-rw-r--r--webkit/glue/plugins/plugin_list.h22
-rw-r--r--webkit/glue/webplugininfo.h3
21 files changed, 1080 insertions, 25 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 59a7674..201dc9e 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3460,6 +3460,47 @@ Keep your key file in a safe place. You will need it to create new versions of y
Allow
</message>
+ <!-- chrome://plugins page -->
+ <message name="IDS_PLUGINS_TITLE" desc="Title for the chrome://plugins page.">
+ Plug-ins
+ </message>
+ <message name="IDS_PLUGINS_DETAILS_MODE_LINK" desc="Text of the link for details mode.">
+ Details
+ </message>
+ <message name="IDS_PLUGINS_NONE_INSTALLED" desc="Text that lets the user know that no plug-ins are installed.">
+ No plug-ins installed.
+ </message>
+ <message name="IDS_PLUGINS_DISABLED_PLUGIN" desc="Text that signifies that the plug-in is currently disabled.">
+ (Disabled)
+ </message>
+ <message name="IDS_PLUGINS_VERSION" desc="The label in front of a plug-in version number.">
+ Version:
+ </message>
+ <message name="IDS_PLUGINS_DESCRIPTION" desc="The label in front of a plug-in description.">
+ Description:
+ </message>
+ <message name="IDS_PLUGINS_PATH" desc="The label in front of a plug-in path (file/location on disk).">
+ Location:
+ </message>
+ <message name="IDS_PLUGINS_MIME_TYPES" desc="The label in front of a plug-in's MIME types table.">
+ MIME types:
+ </message>
+ <message name="IDS_PLUGINS_MIME_TYPES_MIME_TYPE" desc="The label over the MIME type column in a plug-in's MIME types table.">
+ MIME type
+ </message>
+ <message name="IDS_PLUGINS_MIME_TYPES_DESCRIPTION" desc="The label over the description column in a plug-in's MIME types table.">
+ Description
+ </message>
+ <message name="IDS_PLUGINS_MIME_TYPES_FILE_EXTENSIONS" desc="The label over the file extensions column in a plug-in's MIME types table.">
+ File extensions
+ </message>
+ <message name="IDS_PLUGINS_DISABLE" desc="The link for disabling a plug-in.">
+ Disable
+ </message>
+ <message name="IDS_PLUGINS_ENABLE" desc="The link for enabling a plug-in.">
+ Enable
+ </message>
+
<!-- Session Crashed Info Bar-->
<message name="IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON" desc="Title of the restore button in the session crashed view.">
Restore
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index 48ecfbb..4cc4d91 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -45,6 +45,7 @@
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/process_singleton.h"
+#include "chrome/browser/profile.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/shell_integration.h"
@@ -107,7 +108,6 @@
#include "chrome/browser/browser_trial.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/net/url_fixer_upper.h"
-#include "chrome/browser/profile.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/views/user_data_dir_dialog.h"
#include "chrome/common/env_vars.h"
@@ -976,8 +976,8 @@ int BrowserMain(const MainFunctionParams& parameters) {
browser_process->google_url_tracker();
browser_process->intranet_redirect_detector();
- // Have Chrome plugins write their data to the profile directory.
- PluginService::GetInstance()->SetChromePluginDataDir(profile->GetPath());
+ // Do initialize the plug-in service (and related preferences).
+ PluginService::InitGlobalInstance(profile);
// Prepare for memory caching of SDCH dictionaries.
// Perform A/B test to measure global impact of SDCH support.
diff --git a/chrome/browser/browser_prefs.cc b/chrome/browser/browser_prefs.cc
index 187201a..12d626d 100644
--- a/chrome/browser/browser_prefs.cc
+++ b/chrome/browser/browser_prefs.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/cookie_modal_dialog.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/dom_ui/new_tab_ui.h"
+#include "chrome/browser/dom_ui/plugins_ui.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/extensions/extension_dom_ui.h"
#include "chrome/browser/extensions/extension_prefs.h"
@@ -97,6 +98,7 @@ void RegisterUserPrefs(PrefService* user_prefs) {
ExtensionDOMUI::RegisterUserPrefs(user_prefs);
ExtensionsUI::RegisterUserPrefs(user_prefs);
NewTabUI::RegisterUserPrefs(user_prefs);
+ PluginsUI::RegisterUserPrefs(user_prefs);
HostContentSettingsMap::RegisterUserPrefs(user_prefs);
HostZoomMap::RegisterUserPrefs(user_prefs);
DevToolsManager::RegisterUserPrefs(user_prefs);
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 2562a2c..64127cb 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -52,6 +52,7 @@ without changes to the corresponding grd file. fbt1 -->
<include name="IDR_EXTENSION_DEFAULT_ICON" file="resources\extension_default_icon.png" type="BINDATA" />
<include name="IDR_EXTENSIONS_INFOBAR_CSS" file="resources\extensions_infobar.css" flattenhtml="true" type="BINDATA" />
<include name="IDR_EXTENSIONS_TOOLSTRIP_THEME_CSS" file="resources\extensions_toolstrip.css" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_PLUGINS_HTML" file="resources\plugins.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_PRINT_TAB_HTML" file="resources\print_tab.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_PRINT_TAB_CSS" file="resources\print_tab.css" type="BINDATA" />
<include name="IDR_PRINT_TAB_JS" file="resources\print_tab.js" type="BINDATA" />
diff --git a/chrome/browser/dom_ui/dom_ui_factory.cc b/chrome/browser/dom_ui/dom_ui_factory.cc
index c6fb306..01148d0 100644
--- a/chrome/browser/dom_ui/dom_ui_factory.cc
+++ b/chrome/browser/dom_ui/dom_ui_factory.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -14,6 +14,7 @@
#include "chrome/browser/dom_ui/mediaplayer_ui.h"
#include "chrome/browser/dom_ui/net_internals_ui.h"
#include "chrome/browser/dom_ui/new_tab_ui.h"
+#include "chrome/browser/dom_ui/plugins_ui.h"
#include "chrome/browser/dom_ui/print_ui.h"
#include "chrome/browser/extensions/extension_dom_ui.h"
#include "chrome/browser/extensions/extensions_service.h"
@@ -99,6 +100,8 @@ static DOMUIFactoryFunction GetDOMUIFactoryFunction(const GURL& url) {
return &NewDOMUI<HistoryUI>;
if (url.host() == chrome::kChromeUINetInternalsHost)
return &NewDOMUI<NetInternalsUI>;
+ if (url.host() == chrome::kChromeUIPluginsHost)
+ return &NewDOMUI<PluginsUI>;
#if defined(OS_CHROMEOS)
if (url.host() == chrome::kChromeUIFileBrowseHost)
@@ -160,5 +163,8 @@ RefCountedMemory* DOMUIFactory::GetFaviconResourceBytes(Profile* profile,
if (page_url.host() == chrome::kChromeUIHistoryHost)
return HistoryUI::GetFaviconResourceBytes();
+ if (page_url.host() == chrome::kChromeUIPluginsHost)
+ return PluginsUI::GetFaviconResourceBytes();
+
return NULL;
}
diff --git a/chrome/browser/dom_ui/plugins_ui.cc b/chrome/browser/dom_ui/plugins_ui.cc
new file mode 100644
index 0000000..948907d
--- /dev/null
+++ b/chrome/browser/dom_ui/plugins_ui.cc
@@ -0,0 +1,276 @@
+// 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/dom_ui/plugins_ui.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/singleton.h"
+#include "base/values.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
+#include "chrome/browser/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/jstemplate_builder.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "grit/browser_resources.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "webkit/glue/plugins/plugin_list.h"
+
+namespace {
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// PluginsHTMLSource
+//
+///////////////////////////////////////////////////////////////////////////////
+
+class PluginsUIHTMLSource : public ChromeURLDataManager::DataSource {
+ public:
+ PluginsUIHTMLSource()
+ : DataSource(chrome::kChromeUIPluginsHost, MessageLoop::current()) {}
+
+ // Called when the network layer has requested a resource underneath
+ // the path we registered.
+ virtual void StartDataRequest(const std::string& path,
+ bool is_off_the_record,
+ int request_id);
+ virtual std::string GetMimeType(const std::string&) const {
+ return "text/html";
+ }
+
+ private:
+ ~PluginsUIHTMLSource() {}
+
+ DISALLOW_COPY_AND_ASSIGN(PluginsUIHTMLSource);
+};
+
+void PluginsUIHTMLSource::StartDataRequest(const std::string& path,
+ bool is_off_the_record, int request_id) {
+ // Strings used in the JsTemplate file.
+ DictionaryValue localized_strings;
+ localized_strings.SetString(L"pluginsTitle",
+ l10n_util::GetString(IDS_PLUGINS_TITLE));
+ localized_strings.SetString(L"pluginsDetailsModeLink",
+ l10n_util::GetString(IDS_PLUGINS_DETAILS_MODE_LINK));
+ localized_strings.SetString(L"pluginsNoneInstalled",
+ l10n_util::GetString(IDS_PLUGINS_NONE_INSTALLED));
+ localized_strings.SetString(L"pluginDisabled",
+ l10n_util::GetString(IDS_PLUGINS_DISABLED_PLUGIN));
+ localized_strings.SetString(L"pluginVersion",
+ l10n_util::GetString(IDS_PLUGINS_VERSION));
+ localized_strings.SetString(L"pluginDescription",
+ l10n_util::GetString(IDS_PLUGINS_DESCRIPTION));
+ localized_strings.SetString(L"pluginPath",
+ l10n_util::GetString(IDS_PLUGINS_PATH));
+ localized_strings.SetString(L"pluginMimeTypes",
+ l10n_util::GetString(IDS_PLUGINS_MIME_TYPES));
+ localized_strings.SetString(L"pluginMimeTypesMimeType",
+ l10n_util::GetString(IDS_PLUGINS_MIME_TYPES_MIME_TYPE));
+ localized_strings.SetString(L"pluginMimeTypesDescription",
+ l10n_util::GetString(IDS_PLUGINS_MIME_TYPES_DESCRIPTION));
+ localized_strings.SetString(L"pluginMimeTypesFileExtensions",
+ l10n_util::GetString(IDS_PLUGINS_MIME_TYPES_FILE_EXTENSIONS));
+ localized_strings.SetString(L"disable",
+ l10n_util::GetString(IDS_PLUGINS_DISABLE));
+ localized_strings.SetString(L"enable",
+ l10n_util::GetString(IDS_PLUGINS_ENABLE));
+
+ ChromeURLDataManager::DataSource::SetFontAndTextDirection(&localized_strings);
+
+ static const base::StringPiece plugins_html(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_PLUGINS_HTML));
+ std::string full_html(plugins_html.data(), plugins_html.size());
+ jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html);
+ jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html);
+ jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html);
+ jstemplate_builder::AppendJsTemplateSourceHtml(&full_html);
+
+ scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
+ html_bytes->data.resize(full_html.size());
+ std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
+
+ SendResponse(request_id, html_bytes);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// PluginsDOMHandler
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// The handler for Javascript messages related to the "history" view.
+// TODO(viettrungluu): Make plugin list updates notify, and then observe
+// changes; maybe replumb plugin list through plugin service?
+// <http://crbug.com/39101>
+class PluginsDOMHandler : public DOMMessageHandler {
+ public:
+ PluginsDOMHandler() {}
+ virtual ~PluginsDOMHandler() {}
+
+ // DOMMessageHandler implementation.
+ virtual void RegisterMessages();
+
+ // Callback for the "requestPluginsData" message.
+ void HandleRequestPluginsData(const Value* value);
+
+ // Callback for the "enablePlugin" message.
+ void HandleEnablePluginMessage(const Value* value);
+
+ private:
+ // Creates a dictionary containing all the information about the given plugin;
+ // this is put into the list to "return" for the "requestPluginsData" message.
+ DictionaryValue* CreatePluginDetailValue(const WebPluginInfo& plugin);
+
+ // Creates a dictionary containing the important parts of the information
+ // about the given plugin; this is put into a list and saved in prefs.
+ DictionaryValue* CreatePluginSummaryValue(const WebPluginInfo& plugin);
+
+ // Update the user preferences to reflect the current (user-selected) state of
+ // plugins.
+ void UpdatePreferences();
+
+ DISALLOW_COPY_AND_ASSIGN(PluginsDOMHandler);
+};
+
+void PluginsDOMHandler::RegisterMessages() {
+ dom_ui_->RegisterMessageCallback("requestPluginsData",
+ NewCallback(this, &PluginsDOMHandler::HandleRequestPluginsData));
+ dom_ui_->RegisterMessageCallback("enablePlugin",
+ NewCallback(this, &PluginsDOMHandler::HandleEnablePluginMessage));
+}
+
+void PluginsDOMHandler::HandleRequestPluginsData(const Value* value) {
+ DictionaryValue* results = new DictionaryValue();
+
+ // Add plugins to the results structure.
+ ListValue* plugins_list = new ListValue();
+
+ std::vector<WebPluginInfo> plugins;
+ NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
+
+ for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
+ it != plugins.end();
+ ++it) {
+ plugins_list->Append(CreatePluginDetailValue(*it));
+ }
+ results->Set(L"plugins", plugins_list);
+
+ dom_ui_->CallJavascriptFunction(L"returnPluginsData", *results);
+}
+
+void PluginsDOMHandler::HandleEnablePluginMessage(const Value* value) {
+ CHECK(value->IsType(Value::TYPE_LIST));
+ const ListValue* list = static_cast<const ListValue*>(value);
+ CHECK(list->GetSize() == 2);
+ FilePath::StringType plugin_path;
+ std::string enable_str;
+ CHECK(list->GetString(0, &plugin_path));
+ CHECK(list->GetString(1, &enable_str));
+ if (enable_str == "true")
+ NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(plugin_path));
+ else
+ NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(plugin_path));
+
+ // TODO(viettrungluu): It's morally wrong to do this here (it should be done
+ // by the plugins service), and we might also want to ensure that the plugins
+ // list is always written to prefs even when the user hasn't disabled a
+ // plugin. This will require refactoring the plugin list and service.
+ // <http://crbug.com/39101>
+ UpdatePreferences();
+}
+
+DictionaryValue* PluginsDOMHandler::CreatePluginDetailValue(
+ const WebPluginInfo& plugin) {
+ DictionaryValue* plugin_data = new DictionaryValue();
+ plugin_data->SetString(L"path", plugin.path.value());
+ plugin_data->SetString(L"name", plugin.name);
+ plugin_data->SetString(L"version", plugin.version);
+ plugin_data->SetString(L"description", plugin.desc);
+ plugin_data->SetBoolean(L"enabled", plugin.enabled);
+
+ ListValue* mime_types = new ListValue();
+ for (std::vector<WebPluginMimeType>::const_iterator type_it =
+ plugin.mime_types.begin();
+ type_it != plugin.mime_types.end();
+ ++type_it) {
+ DictionaryValue* mime_type = new DictionaryValue();
+ mime_type->SetString(L"mimeType", type_it->mime_type);
+ mime_type->SetString(L"description", type_it->description);
+
+ ListValue* file_extensions = new ListValue();
+ for (std::vector<std::string>::const_iterator ext_it =
+ type_it->file_extensions.begin();
+ ext_it != type_it->file_extensions.end();
+ ++ext_it) {
+ file_extensions->Append(new StringValue(*ext_it));
+ }
+ mime_type->Set(L"fileExtensions", file_extensions);
+
+ mime_types->Append(mime_type);
+ }
+ plugin_data->Set(L"mimeTypes", mime_types);
+
+ return plugin_data;
+}
+
+DictionaryValue* PluginsDOMHandler::CreatePluginSummaryValue(
+ const WebPluginInfo& plugin) {
+ DictionaryValue* plugin_data = new DictionaryValue();
+ plugin_data->SetString(L"path", plugin.path.value());
+ plugin_data->SetString(L"name", plugin.name);
+ plugin_data->SetString(L"version", plugin.version);
+ plugin_data->SetBoolean(L"enabled", plugin.enabled);
+ return plugin_data;
+}
+
+void PluginsDOMHandler::UpdatePreferences() {
+ ListValue* plugins_list = dom_ui_->GetProfile()->GetPrefs()->GetMutableList(
+ prefs::kPluginsPluginsList);
+ plugins_list->Clear();
+
+ std::vector<WebPluginInfo> plugins;
+ NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
+
+ for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
+ it != plugins.end();
+ ++it) {
+ plugins_list->Append(CreatePluginSummaryValue(*it));
+ }
+}
+
+} // namespace
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// PluginsUI
+//
+///////////////////////////////////////////////////////////////////////////////
+
+PluginsUI::PluginsUI(TabContents* contents) : DOMUI(contents) {
+ AddMessageHandler((new PluginsDOMHandler())->Attach(this));
+
+ PluginsUIHTMLSource* html_source = new PluginsUIHTMLSource();
+
+ // Set up the chrome://plugins/ source.
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(Singleton<ChromeURLDataManager>::get(),
+ &ChromeURLDataManager::AddDataSource,
+ make_scoped_refptr(html_source)));
+}
+
+
+// static
+RefCountedMemory* PluginsUI::GetFaviconResourceBytes() {
+ return ResourceBundle::GetSharedInstance().
+ LoadDataResourceBytes(IDR_PLUGIN);
+}
+
+// static
+void PluginsUI::RegisterUserPrefs(PrefService* prefs) {
+ prefs->RegisterListPref(prefs::kPluginsPluginsList);
+}
diff --git a/chrome/browser/dom_ui/plugins_ui.h b/chrome/browser/dom_ui/plugins_ui.h
new file mode 100644
index 0000000..00dbce9
--- /dev/null
+++ b/chrome/browser/dom_ui/plugins_ui.h
@@ -0,0 +1,24 @@
+// 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_DOM_UI_PLUGINS_UI_H_
+#define CHROME_BROWSER_DOM_UI_PLUGINS_UI_H_
+
+#include "chrome/browser/dom_ui/dom_ui.h"
+
+class PrefService;
+class RefCountedMemory;
+
+class PluginsUI : public DOMUI {
+ public:
+ explicit PluginsUI(TabContents* contents);
+
+ static RefCountedMemory* GetFaviconResourceBytes();
+ static void RegisterUserPrefs(PrefService* prefs);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PluginsUI);
+};
+
+#endif // CHROME_BROWSER_DOM_UI_PLUGINS_UI_H_
diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc
index 987d68e..12a15e1 100644
--- a/chrome/browser/plugin_service.cc
+++ b/chrome/browser/plugin_service.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -10,12 +10,15 @@
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/thread.h"
+#include "base/values.h"
#include "base/waitable_event.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_plugin_host.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/plugin_process_host.h"
+#include "chrome/browser/pref_service.h"
+#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/common/chrome_plugin_lib.h"
#include "chrome/common/chrome_paths.h"
@@ -25,6 +28,7 @@
#include "chrome/common/logging_chrome.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/notification_service.h"
+#include "chrome/common/pref_names.h"
#include "chrome/common/render_messages.h"
#ifndef DISABLE_NACL
#include "native_client/src/trusted/plugin/nacl_entry_points.h"
@@ -48,6 +52,34 @@ static void NotifyPluginsOfActivation() {
bool PluginService::enable_chrome_plugins_ = true;
// static
+void PluginService::InitGlobalInstance(Profile* profile) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+
+ // Disable plugins listed as disabled in prefs.
+ if (const ListValue* saved_plugins_list =
+ profile->GetPrefs()->GetList(prefs::kPluginsPluginsList)) {
+ for (ListValue::const_iterator it = saved_plugins_list->begin();
+ it != saved_plugins_list->end();
+ ++it) {
+ if (!(*it)->IsType(Value::TYPE_DICTIONARY)) {
+ LOG(WARNING) << "Invalid entry in " << prefs::kPluginsPluginsList;
+ continue; // Oops, don't know what to do with this item.
+ }
+
+ DictionaryValue* plugin = static_cast<DictionaryValue*>(*it);
+ FilePath::StringType path;
+ bool enabled = true;
+ plugin->GetBoolean(L"enabled", &enabled);
+ if (!enabled && plugin->GetString(L"path", &path))
+ NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path));
+ }
+ }
+
+ // Have Chrome plugins write their data to the profile directory.
+ GetInstance()->SetChromePluginDataDir(profile->GetPath());
+}
+
+// static
PluginService* PluginService::GetInstance() {
return Singleton<PluginService>::get();
}
diff --git a/chrome/browser/plugin_service.h b/chrome/browser/plugin_service.h
index 7ab39e2..f3214e0 100644
--- a/chrome/browser/plugin_service.h
+++ b/chrome/browser/plugin_service.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -31,6 +31,7 @@ class Message;
class MessageLoop;
class PluginProcessHost;
+class Profile;
class URLRequestContext;
class ResourceDispatcherHost;
class ResourceMessageFilter;
@@ -41,6 +42,10 @@ class PluginService
: public base::WaitableEventWatcher::Delegate,
public NotificationObserver {
public:
+ // Initializes the global instance; should be called on startup from the main
+ // thread.
+ static void InitGlobalInstance(Profile* profile);
+
// Returns the PluginService singleton.
static PluginService* GetInstance();
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 74ae523..48c1cb6 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -746,7 +746,7 @@ void ResourceMessageFilter::OnGetPluginsOnFileThread(
bool refresh, IPC::Message* reply_msg) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
std::vector<WebPluginInfo> plugins;
- NPAPI::PluginList::Singleton()->GetPlugins(refresh, &plugins);
+ NPAPI::PluginList::Singleton()->GetEnabledPlugins(refresh, &plugins);
ViewHostMsg_GetPlugins::WriteReplyParams(reply_msg, plugins);
ChromeThread::PostTask(
ChromeThread::IO, FROM_HERE,
diff --git a/chrome/browser/resources/plugins.html b/chrome/browser/resources/plugins.html
new file mode 100644
index 0000000..19cbedb
--- /dev/null
+++ b/chrome/browser/resources/plugins.html
@@ -0,0 +1,558 @@
+<!DOCTYPE HTML>
+<html i18n-values="dir:textdirection;">
+<head>
+<meta charset="utf-8">
+<title i18n-content="pluginsTitle"></title>
+<style>
+
+body {
+ margin: 10px;
+ min-width: 47em;
+}
+
+a {
+ color: blue;
+ font-size: 103%;
+}
+
+div#header {
+ margin-bottom: 1.05em;
+ overflow: hidden;
+ padding-bottom: 1.5em;
+ padding-left: 0;
+ padding-top: 1.5em;
+ position: relative;
+}
+
+html[dir='rtl'] div#header {
+ padding-right: 0;
+}
+
+div#header h1 {
+ background: url('../../app/theme/extensions_section.png') 0px 20px no-repeat;
+ display: inline;
+ margin: 0;
+ padding-bottom: 43px;
+ padding-left: 75px;
+ padding-top: 40px;
+}
+
+html[dir='rtl'] div#header h1 {
+ background: url('../../app/theme/extensions_section.png') right no-repeat;
+ padding-right: 95px;
+ padding-left: 0;
+}
+
+h1 {
+ font-size: 156%;
+ font-weight: bold;
+ padding: 0;
+ margin: 0;
+}
+
+div.content {
+ font-size: 88%;
+ margin-top: 5px;
+}
+
+.section-header {
+ background: #ebeff9;
+ border-top: 1px solid #b5c7de;
+ font-size: 99%;
+ padding-bottom: 2px;
+ padding-left: 5px;
+ padding-top: 3px;
+ width: 100%;
+}
+
+html[dir='rtl'] .section-header {
+ padding-right: 5px;
+ padding-left: 0;
+}
+
+.section-header > table tr td:first-child {
+ width: 100%;
+}
+
+.section-header > table {
+ width: 100%;
+}
+
+.section-header-title {
+ font-weight: bold;
+}
+
+.vbox-container {
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+}
+
+.wbox {
+ display: -webkit-box;
+ -webkit-box-align: stretch;
+ -webkit-box-flex: 1;
+}
+
+.wbox#top {
+ padding-right: 5px;
+}
+
+html[dir='rtl'] .wbox#top {
+ padding-left: 5px;
+ padding-right: 0;
+}
+
+.showInTmiMode {
+ overflow: hidden;
+}
+
+body.hideTmiModeInitial .showInTmiMode {
+ height: 0 !important;
+ opacity: 0;
+}
+
+body.hideTmiMode .showInTmiMode {
+ height: 0 !important;
+ opacity: 0;
+ -webkit-transition: all .1s ease-out;
+}
+
+body.showTmiModeInitial .showInTmiMode {
+ opacity: 1;
+}
+
+body.showTmiMode .showInTmiMode {
+ opacity: 1;
+ -webkit-transition: all .1s ease-in;
+}
+
+.wbox-tmi-mode {
+ -webkit-box-align: stretch;
+ -webkit-box-flex: 1;
+}
+
+.tmi-mode-image {
+ margin-top: 2px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+.tmi-mode-link {
+ margin-right: 3px;
+ white-space: nowrap;
+}
+
+.tmi-mode-link a {
+ font-size: 97%;
+}
+
+.tmi-mode {
+ background: #f4f6fc;
+ border-bottom: 1px solid #edeff5;
+ font-size: 89%;
+ padding-bottom: 0.8em;
+ padding-left: 10px;
+ padding-top: 0.8em;
+ width: 100%;
+}
+
+html[dir='rtl'] .tmi-mode {
+ padding-right: 10px;
+ padding-left: 0;
+}
+
+.plugin_disabled > td {
+ background: url('gray.png') 0px 0px;
+ color: #a0a0a0;
+ padding-bottom: 4px;
+ padding-top: 5px;
+}
+
+.plugin_enabled > td {
+ padding-bottom: 4px;
+ padding-top: 5px;
+}
+
+.plugin {
+ border-bottom: 1px solid #cdcdcd;
+}
+
+/* Indent the text related to each plug-in. */
+.plugin-text {
+ padding-left: 5px;
+}
+
+html[dir='rtl'] .plugin-text {
+ padding-right: 5px;
+ padding-left: 0;
+}
+
+.plugin-name {
+ font-weight: bold;
+}
+
+.no-plugins {
+ margin: 6em 0 0;
+ text-align: center;
+ font-size: 1.2em;
+}
+
+/* Use tables for layout, so eliminate extra spacing. */
+.plugin-details table {
+ -webkit-border-horizontal-spacing: 0;
+ -webkit-border-vertical-spacing: 0;
+}
+
+/* Separate the inital line, Description, Location, and MIME Types lines. */
+.plugin-details > div {
+ padding-top: 0.1em
+}
+
+/* Align rows of tables along the top. */
+.plugin-details tr {
+ vertical-align: top;
+}
+
+/* Separate columns by 1em for the most part. */
+.plugin-details td+td {
+ padding-left: 1em;
+}
+
+html[dir='rtl'] .plugin-details td+td {
+ padding-right: 1em;
+ padding-left: 0;
+}
+
+/* Make the MIME Types tables smaller. */
+.plugin-details .mime_types {
+ font-size: 95%;
+}
+
+/* Separate the header from the contents in each MIME Types table. */
+.plugin-details .mime_types .header td {
+ padding-bottom: 0.1em;
+ border-bottom: 1px solid;
+}
+
+/* Separate the columns for tables used for horizontal listings only a bit. */
+.hlisting td+td {
+ padding-left: 0.4em;
+}
+
+html[dir='rtl'] .hlisting td+td {
+ padding-right: 0.4em;
+ padding-left: 0;
+}
+
+/* Match the indentation of .plugin-text. */
+.plugin-actions {
+ padding-left: 5px;
+ margin-top: 0.2em;
+ margin-bottom: 0.2em;
+}
+
+html[dir='rtl'] .plugin-actions {
+ padding-right: 5px;
+ padding-left: 0;
+}
+
+button {
+ font-size: 104%;
+}
+
+</style>
+<script>
+
+/**
+ * This variable structure is here to document the structure that the template
+ * expects to correctly populate the page.
+ */
+var pluginDataFormat = {
+ 'plugins': [
+ {
+ 'path': '/blahblah/blahblah/MyCrappyPlugin.plugin',
+ 'name': 'MyCrappyPlugin',
+ 'version': '1.2.3',
+ 'description': 'My crappy plugin',
+ 'mimeTypes': [
+ { 'description': 'Foo Media',
+ 'fileExtensions': [ 'foo' ],
+ 'mimeType': 'application/x-my-foo' },
+ { 'description': 'Bar Stuff',
+ 'fileExtensions': [ 'bar','baz' ],
+ 'mimeType': 'application/my-bar' }
+ ],
+ 'enabled': true
+ },
+ {
+ 'path': '/foobar/baz/YourGreatPlugin.plugin',
+ 'name': 'YourGreatPlugin',
+ 'version': '4.5',
+ 'description': 'Your great plugin',
+ 'mimeTypes': [
+ { 'description': 'Baz Stuff',
+ 'fileExtensions': [ 'baz' ],
+ 'mimeType': 'application/x-your-baz' }
+ ],
+ 'enabled': false
+ }
+ ]
+};
+
+/**
+ * Takes the |pluginsData| input argument which represents data about the
+ * currently installed/running plugins and populates the html jstemplate with
+ * that data. It expects an object structure like the above.
+ * @param {Object} pluginsData Detailed info about installed plugins
+ */
+function renderTemplate(pluginsData) {
+ // This is the javascript code that processes the template:
+ var input = new JsEvalContext(pluginsData);
+ var output = document.getElementById('pluginTemplate');
+ jstProcess(input, output);
+}
+
+/**
+ * Asks the C++ PluginsDOMHandler to get details about the installed plugins and
+ * return detailed data about the configuration. The PluginsDOMHandler should
+ * reply to returnPluginsData() (below).
+ */
+function requestPluginsData() {
+ chrome.send('requestPluginsData', []);
+}
+
+/**
+ * Called by the dom_ui_ to re-populate the page with data representing the
+ * current state of installed plugins.
+ */
+function returnPluginsData(pluginsData){
+ var bodyContainer = document.getElementById('body-container');
+ var body = document.body;
+
+ // Set all page content to be visible so we can measure heights.
+ bodyContainer.style.visibility = 'hidden';
+ body.className = '';
+ var slidables = document.getElementsByClassName('showInTmiMode');
+ for (var i = 0; i < slidables.length; i++)
+ slidables[i].style.height = 'auto';
+
+ renderTemplate(pluginsData);
+
+ // Make sure the left column (with "Description:", "Location:", etc.) is the
+ // same size for all plugins.
+ var labels = document.getElementsByClassName('plugin-details-label');
+ var maxLabelWidth = 0;
+ for (var i = 0; i < labels.length; i++)
+ labels[i].style.width = 'auto';
+ for (var i = 0; i < labels.length; i++)
+ maxLabelWidth = Math.max(maxLabelWidth, labels[i].offsetWidth);
+ for (var i = 0; i < labels.length; i++)
+ labels[i].style.width = maxLabelWidth + 'px';
+
+ // Explicitly set the height for each element that wants to be "slid" in and
+ // out when the tmiModeExpanded is toggled.
+ var slidables = document.getElementsByClassName('showInTmiMode');
+ for (var i = 0; i < slidables.length; i++)
+ slidables[i].style.height = slidables[i].offsetHeight + 'px';
+
+ // Reset visibility of page based on the current tmi mode.
+ document.getElementById('collapse').style.display =
+ tmiModeExpanded ? 'inline' : 'none';
+ document.getElementById('expand').style.display =
+ tmiModeExpanded ? 'none' : 'inline';
+ bodyContainer.style.visibility = 'visible';
+ body.className = tmiModeExpanded ?
+ 'showTmiModeInitial' : 'hideTmiModeInitial';
+}
+
+/**
+ * Handles a 'enable' or 'disable' button getting clicked.
+ */
+function handleEnablePlugin(node, enable) {
+ // Tell the C++ PluginsDOMHandler to enable/disable the plugin.
+ chrome.send('enablePlugin', [node.pluginPath, String(enable)]);
+ requestPluginsData();
+}
+
+// Keeps track of whether details have been made visible (expanded) or not.
+var tmiModeExpanded = false;
+
+/*
+ * Toggles visibility of details.
+ */
+function toggleTmiMode() {
+ tmiModeExpanded = !tmiModeExpanded;
+
+ document.getElementById('collapse').style.display =
+ tmiModeExpanded ? 'inline' : 'none';
+ document.getElementById('expand').style.display =
+ tmiModeExpanded ? 'none' : 'inline';
+
+ document.body.className =
+ tmiModeExpanded ? 'showTmiMode' : 'hideTmiMode';
+}
+
+/**
+ * Determines whether a plugin's version should be displayed.
+ */
+function shouldDisplayPluginVersion(plugin) {
+ return !!plugin.version;
+}
+
+/**
+ * Determines whether a plugin's description should be displayed.
+ */
+function shouldDisplayPluginDescription(plugin) {
+ // Only display the description if it's not blank and if it's not just the
+ // name, version, or combination thereof.
+ return plugin.description &&
+ plugin.description != plugin.name &&
+ plugin.description != plugin.version &&
+ plugin.description != 'Version ' + plugin.version &&
+ plugin.description != plugin.name + ' ' + plugin.version;
+}
+
+/**
+ * Formats a file extension for display.
+ */
+function formatFileExtension(ext) {
+ return '.' + ext;
+}
+
+// Unfortunately, we don't have notifications for plugin (list) status changes
+// (yet), so in the meanwhile just update regularly.
+setInterval('requestPluginsData()', 30000);
+
+// Get data and have it displayed upon loading.
+window.onload = requestPluginsData;
+
+</script>
+</head>
+<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
+<div id="body-container" style="visibility:hidden">
+
+ <div id="header"><h1 i18n-content="pluginsTitle">TITLE</h1></div>
+
+ <div id="pluginTemplate">
+
+ <div id="container" class="vbox-container">
+ <div id="top" class="wbox">
+
+ <div class="section-header">
+ <table cellpadding="0" cellspacing="0"><tr valign="center">
+ <td>
+ <span class="section-header-title" i18n-content="pluginsTitle"
+ >TITLE</span>
+ <span class="section-header-title"
+ jsdisplay="plugins.length > 0">(<span
+ jscontent="plugins.length"></span>)</span>
+ </td>
+ <td width="18">
+ <img id="collapse" class="tmi-mode-image"
+ style="display:none" onclick="toggleTmiMode();"
+ src="minus.png"></img>
+ <img id="expand" class="tmi-mode-image"
+ onclick="toggleTmiMode();" src="plus.png"></img>
+ </td>
+ <td>
+ <div class="tmi-mode-link">
+ <a onclick="toggleTmiMode();" style="cursor: default"
+ i18n-content="pluginsDetailsModeLink">DETAILS</a>
+ </div>
+ </td>
+ </tr></table>
+ </div>
+
+ </div>
+ </div>
+
+ <div class="content">
+ <div class="plugin-name no-plugins" jsdisplay="plugins.length === 0">
+ <div i18n-content="noPlugins">NO_PLUGINS_ARE_INSTALLED</div>
+ </div>
+
+ <div jsdisplay="plugins.length > 0">
+ <div class="plugin" jsselect="plugins">
+ <table width="100%" cellpadding="2" cellspacing="0">
+ <tr jsvalues=
+ ".className:enabled ? 'plugin_enabled' : 'plugin_disabled'">
+ <td valign="top">
+ <div class="plugin-text">
+ <div>
+ <span class="plugin-name"
+ jscontent="name">PLUGIN NAME</span>
+ <span jsdisplay="shouldDisplayPluginVersion($this)">
+ - <span i18n-content="pluginVersion">VERSION</span>
+ <span jscontent="version">x.x.x.x</span>
+ </span>
+ <span jsdisplay="!enabled"
+ i18n-content="pluginDisabled">(DISABLED)</span>
+ </div>
+ <div class="plugin-details">
+ <div><table><tr jsdisplay="shouldDisplayPluginDescription($this)">
+ <td class="plugin-details-label"
+ i18n-content="pluginDescription">DESCRIPTION:</td>
+ <td jsvalues=".innerHTML:description"></td>
+ </tr></table></div>
+ <div><table><tr>
+ <td class="plugin-details-label"
+ i18n-content="pluginPath">PATH:</td>
+ <td jscontent="path"></td>
+ </tr></table></div>
+ <div class="showInTmiMode">
+ <table><tr jsdisplay="mimeTypes.length > 0">
+ <td class="plugin-details-label"
+ i18n-content="pluginMimeTypes">MIME_TYPES:</td>
+ <td><table width="100%" class="mime_types">
+ <tr class="header">
+ <td i18n-content="pluginMimeTypesMimeType"
+ >MIME type</td>
+ <td i18n-content="pluginMimeTypesDescription"
+ >DESCRIPTION</td>
+ <td i18n-content="pluginMimeTypesFileExtensions"
+ >FILE_EXTENSIONS</td>
+ </tr>
+ <tr jsselect="mimeTypes">
+ <td jscontent="mimeType"></td>
+ <td jscontent="description"></td>
+ <td><table jsdisplay="fileExtensions.length > 0"
+ class="hlisting">
+ <tr><td jsselect="fileExtensions">
+ <span jscontent="formatFileExtension($this)"></span>
+ </td></tr>
+ </table></td>
+ </tr>
+ </table></td>
+ </tr></table>
+ </div>
+ </div>
+ </div>
+
+ <div class="plugin-actions">
+ <span>
+ <a
+ jsvalues=".pluginPath:path"
+ jsdisplay="enabled"
+ onclick="handleEnablePlugin(this, false)"
+ href="javascript:void();"
+ i18n-content="disable"
+ >DISABLE</a>
+ <a
+ jsvalues=".pluginPath:path"
+ jsdisplay="!enabled"
+ onclick="handleEnablePlugin(this, true)"
+ href="javascript:void();"
+ i18n-content="enable"
+ >ENABLE</a>
+ </span>
+ </div>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+</body>
+</html>
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 935162d..b408402 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -866,6 +866,8 @@
'browser/dom_ui/new_tab_ui.h',
'browser/dom_ui/ntp_resource_cache.cc',
'browser/dom_ui/ntp_resource_cache.h',
+ 'browser/dom_ui/plugins_ui.cc',
+ 'browser/dom_ui/plugins_ui.h',
'browser/dom_ui/print_ui.cc',
'browser/dom_ui/print_ui.h',
'browser/dom_ui/shown_sections_handler.cc',
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 62486e3..5e4f84d 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -163,38 +163,36 @@ const wchar_t kDnsStartupPrefetchList[] = L"StartupDNSPrefetchList";
// sub-resource hostnames (and expected latency benefits from pre-resolving such
// sub-resource hostnames).
// This list is adaptively grown and pruned.
-extern const wchar_t kDnsHostReferralList[] = L"HostReferralList";
+const wchar_t kDnsHostReferralList[] = L"HostReferralList";
// Is the cookie prompt expanded?
-extern const wchar_t kCookiePromptExpanded[] = L"cookieprompt.expanded";
+const wchar_t kCookiePromptExpanded[] = L"cookieprompt.expanded";
#if defined(USE_NSS)
// Prefs for SSLConfigServicePref. Currently, these are only present on
// and used by NSS-using OSes.
-extern const wchar_t kCertRevocationCheckingEnabled[] =
- L"ssl.rev_checking.enabled";
-extern const wchar_t kSSL2Enabled[] = L"ssl.ssl2.enabled";
-extern const wchar_t kSSL3Enabled[] = L"ssl.ssl3.enabled";
-extern const wchar_t kTLS1Enabled[] = L"ssl.tls1.enabled";
+const wchar_t kCertRevocationCheckingEnabled[] = L"ssl.rev_checking.enabled";
+const wchar_t kSSL2Enabled[] = L"ssl.ssl2.enabled";
+const wchar_t kSSL3Enabled[] = L"ssl.ssl3.enabled";
+const wchar_t kTLS1Enabled[] = L"ssl.tls1.enabled";
#endif
#if defined(OS_CHROMEOS)
// A string pref set to the timezone.
-extern const wchar_t kTimeZone[] = L"settings.datetime.timezone";
+const wchar_t kTimeZone[] = L"settings.datetime.timezone";
// A boolean pref set to true if TapToClick is being done in browser.
-extern const wchar_t kTapToClickEnabled[] =
- L"settings.touchpad.enable_tap_to_click";
+const wchar_t kTapToClickEnabled[] = L"settings.touchpad.enable_tap_to_click";
// A boolean pref set to true if VertEdgeScroll is being done in browser.
-extern const wchar_t kVertEdgeScrollEnabled[] =
+const wchar_t kVertEdgeScrollEnabled[] =
L"settings.touchpad.enable_vert_edge_scroll";
// A integer pref for the touchpad speed factor.
-extern const wchar_t kTouchpadSpeedFactor[] = L"settings.touchpad.speed_factor";
+const wchar_t kTouchpadSpeedFactor[] = L"settings.touchpad.speed_factor";
// A integer pref for the touchpad sensitivity.
-extern const wchar_t kTouchpadSensitivity[] = L"settings.touchpad.sensitivity";
+const wchar_t kTouchpadSensitivity[] = L"settings.touchpad.sensitivity";
#endif
// The disabled messages in IPC logging.
@@ -273,6 +271,9 @@ const wchar_t kExtensionsUIDeveloperMode[] = L"extensions.ui.developer_mode";
// actions toolbar.
const wchar_t kExtensionToolbarSize[] = L"extensions.toolbarsize";
+// List pref containing information (dictionaries) on plugins.
+const wchar_t kPluginsPluginsList[] = L"plugins.plugins_list";
+
// Boolean that indicates whether we should check if we are the default browser
// on start-up.
const wchar_t kCheckDefaultBrowser[] = L"browser.check_default_browser";
@@ -407,7 +408,7 @@ const wchar_t kStabilityStatsVersion[] =
// Build time, in seconds since an epoch, which is used to assure that stability
// metrics reported reflect stability of the same build.
-extern const wchar_t kStabilityStatsBuildTime[] =
+const wchar_t kStabilityStatsBuildTime[] =
L"user_experience_metrics.stability.stats_buildtime";
// False if we received a session end and either we crashed during processing
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index a8b2de9..eecb1c1 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -110,6 +110,7 @@ extern const wchar_t kCurrentThemeTints[];
extern const wchar_t kCurrentThemeDisplayProperties[];
extern const wchar_t kExtensionsUIDeveloperMode[];
extern const wchar_t kExtensionToolbarSize[];
+extern const wchar_t kPluginsPluginsList[];
extern const wchar_t kCheckDefaultBrowser[];
#if defined(OS_MACOSX)
extern const wchar_t kShowUpdatePromotionInfoBar[];
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 9d24745..d770685 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -38,11 +38,11 @@ const char* kSavableSchemes[] = {
const char kAboutBlankURL[] = "about:blank";
const char kAboutCacheURL[] = "about:cache";
-const char kAboutNetInternalsURL[] = "about:net-internals";
const char kAboutCrashURL[] = "about:crash";
const char kAboutCreditsURL[] = "about:credits";
const char kAboutHangURL[] = "about:hang";
const char kAboutMemoryURL[] = "about:memory";
+const char kAboutNetInternalsURL[] = "about:net-internals";
const char kAboutShorthangURL[] = "about:shorthang";
const char kAboutTermsURL[] = "about:terms";
@@ -55,6 +55,7 @@ const char kChromeUIDevToolsURL[] = "chrome://devtools/";
const char kChromeUIDownloadsURL[] = "chrome://downloads/";
const char kChromeUIExtensionsURL[] = "chrome://extensions/";
const char kChromeUIHistoryURL[] = "chrome://history/";
+const char kChromeUIPluginsURL[] = "chrome://plugins/";
const char kChromeUIFileBrowseURL[] = "chrome://filebrowse/";
const char kChromeUIMediaplayerURL[] = "chrome://mediaplayer/";
const char kChromeUIIPCURL[] = "chrome://about/ipc";
@@ -68,6 +69,7 @@ const char kChromeUIDownloadsHost[] = "downloads";
const char kChromeUIExtensionsHost[] = "extensions";
const char kChromeUIFavIconPath[] = "favicon";
const char kChromeUIHistoryHost[] = "history";
+const char kChromeUIPluginsHost[] = "plugins";
const char kChromeUIFileBrowseHost[] = "filebrowse";
const char kChromeUIMediaplayerHost[] = "mediaplayer";
const char kChromeUIInspectorHost[] = "inspector";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 665bd66..d4f2ee5 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -32,7 +32,7 @@ extern const char kStandardSchemeSeparator[];
// Null terminated list of schemes that are savable.
extern const char* kSavableSchemes[];
-// About URLs (including schmes).
+// About URLs (including schemes).
extern const char kAboutBlankURL[];
extern const char kAboutBrowserCrash[];
extern const char kAboutCacheURL[];
@@ -51,6 +51,7 @@ extern const char kChromeUIDevToolsURL[];
extern const char kChromeUIDownloadsURL[];
extern const char kChromeUIExtensionsURL[];
extern const char kChromeUIHistoryURL[];
+extern const char kChromeUIPluginsURL[];
extern const char kChromeUIFileBrowseURL[];
extern const char kChromeUIMediaplayerURL[];
extern const char kChromeUIIPCURL[];
@@ -66,6 +67,7 @@ extern const char kChromeUIDownloadsHost[];
extern const char kChromeUIExtensionsHost[];
extern const char kChromeUIFavIconPath[];
extern const char kChromeUIHistoryHost[];
+extern const char kChromeUIPluginsHost[];
extern const char kChromeUIFileBrowseHost[];
extern const char kChromeUIMediaplayerHost[];
extern const char kChromeUIInspectorHost[];
diff --git a/webkit/glue/plugins/plugin_lib_mac.mm b/webkit/glue/plugins/plugin_lib_mac.mm
index 64d34c3..b6ced70 100644
--- a/webkit/glue/plugins/plugin_lib_mac.mm
+++ b/webkit/glue/plugins/plugin_lib_mac.mm
@@ -123,6 +123,7 @@ bool ReadPlistPluginInfo(const FilePath& filename, CFBundleRef bundle,
info->desc = base::SysNSStringToWide(plugin_desc);
else
info->desc = UTF8ToWide(filename.BaseName().value());
+ info->enabled = true;
return true;
}
@@ -220,6 +221,7 @@ bool ReadSTRPluginInfo(const FilePath& filename, CFBundleRef bundle,
info->desc = UTF8ToWide(plugin_descs[0]);
else
info->desc = UTF8ToWide(filename.BaseName().value());
+ info->enabled = true;
return true;
}
diff --git a/webkit/glue/plugins/plugin_lib_posix.cc b/webkit/glue/plugins/plugin_lib_posix.cc
index e738b67..6541a66 100644
--- a/webkit/glue/plugins/plugin_lib_posix.cc
+++ b/webkit/glue/plugins/plugin_lib_posix.cc
@@ -131,6 +131,7 @@ bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
return false;
info->path = filename;
+ info->enabled = true;
// Attempt to swap in the wrapped plugin if this is nspluginwrapper.
UnwrapNSPluginWrapper(&dl, &info->path);
diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc
index e8565d8..d0199d4 100644
--- a/webkit/glue/plugins/plugin_list.cc
+++ b/webkit/glue/plugins/plugin_list.cc
@@ -1,9 +1,11 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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 "webkit/glue/plugins/plugin_list.h"
+#include <algorithm>
+
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/string_util.h"
@@ -106,6 +108,7 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi,
info->desc = pvi.file_description;
info->version = pvi.file_version;
info->path = pvi.path;
+ info->enabled = true;
for (size_t i = 0; i < mime_types.size(); ++i) {
WebPluginMimeType mime_type;
@@ -214,7 +217,17 @@ void PluginList::LoadPlugins(bool refresh) {
base::TimeDelta elapsed = end_time - start_time;
DLOG(INFO) << "Loaded plugin list in " << elapsed.InMilliseconds() << " ms.";
+ // Only update the data now since loading plugins can take a while.
AutoLock lock(lock_);
+
+ // Go through and mark new plugins in the disabled list as, well, disabled.
+ for (std::vector<WebPluginInfo>::iterator it = new_plugins.begin();
+ it != new_plugins.end();
+ ++it) {
+ if (disabled_plugins_.find(it->path) != disabled_plugins_.end())
+ it->enabled = false;
+ }
+
plugins_ = new_plugins;
plugins_loaded_ = true;
}
@@ -331,6 +344,20 @@ void PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
*plugins = plugins_;
}
+void PluginList::GetEnabledPlugins(bool refresh,
+ std::vector<WebPluginInfo>* plugins) {
+ LoadPlugins(refresh);
+
+ plugins->clear();
+ AutoLock lock(lock_);
+ for (std::vector<WebPluginInfo>::const_iterator it = plugins_.begin();
+ it != plugins_.end();
+ ++it) {
+ if (it->enabled)
+ plugins->push_back(*it);
+ }
+}
+
bool PluginList::GetPluginInfo(const GURL& url,
const std::string& mime_type,
bool allow_wildcard,
@@ -362,6 +389,55 @@ bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path,
return false;
}
+bool PluginList::EnablePlugin(const FilePath& filename) {
+ AutoLock lock(lock_);
+
+ bool did_enable = false;
+
+ std::set<FilePath>::iterator entry = disabled_plugins_.find(filename);
+ if (entry == disabled_plugins_.end())
+ return did_enable; // Early exit if plugin not in disabled list.
+
+ disabled_plugins_.erase(entry); // Remove from disabled list.
+
+ // Set enabled flags if necessary.
+ for (std::vector<WebPluginInfo>::iterator it = plugins_.begin();
+ it != plugins_.end();
+ ++it) {
+ if (it->path == filename) {
+ DCHECK(!it->enabled); // Should have been disabled.
+ it->enabled = true;
+ did_enable = true;
+ }
+ }
+
+ return did_enable;
+}
+
+bool PluginList::DisablePlugin(const FilePath& filename) {
+ AutoLock lock(lock_);
+
+ bool did_disable = false;
+
+ if (disabled_plugins_.find(filename) != disabled_plugins_.end())
+ return did_disable; // Early exit if plugin already in disabled list.
+
+ disabled_plugins_.insert(filename); // Add to disabled list.
+
+ // Unset enabled flags if necessary.
+ for (std::vector<WebPluginInfo>::iterator it = plugins_.begin();
+ it != plugins_.end();
+ ++it) {
+ if (it->path == filename) {
+ DCHECK(it->enabled); // Should have been enabled.
+ it->enabled = false;
+ did_disable = true;
+ }
+ }
+
+ return did_disable;
+}
+
void PluginList::Shutdown() {
// TODO
}
diff --git a/webkit/glue/plugins/plugin_list.h b/webkit/glue/plugins/plugin_list.h
index 0017399..91bf23f 100644
--- a/webkit/glue/plugins/plugin_list.h
+++ b/webkit/glue/plugins/plugin_list.h
@@ -5,6 +5,7 @@
#ifndef WEBKIT_GLUE_PLUGINS_PLUGIN_LIST_H_
#define WEBKIT_GLUE_PLUGINS_PLUGIN_LIST_H_
+#include <set>
#include <string>
#include <vector>
#include <set>
@@ -114,9 +115,12 @@ class PluginList {
// Shutdown all plugins. Should be called at process teardown.
void Shutdown();
- // Get all the plugins
+ // Get all the plugins.
void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins);
+ // Get all the enabled plugins.
+ void GetEnabledPlugins(bool refresh, std::vector<WebPluginInfo>* plugins);
+
// Returns true if a plugin is found for the given url and mime type.
// The mime type which corresponds to the URL is optionally returned
// back.
@@ -137,6 +141,19 @@ class PluginList {
void LoadPlugin(const FilePath& filename,
std::vector<WebPluginInfo>* plugins);
+ // Enable a specific plugin, specified by path. Returns |true| iff a plugin
+ // currently in the plugin list was actually enabled as a result; regardless
+ // of return value, if a plugin is found in the future with the given name, it
+ // will be enabled. Note that plugins are enabled by default as far as
+ // |PluginList| is concerned.
+ bool EnablePlugin(const FilePath& filename);
+
+ // Disable a specific plugin, specified by path. Returns |true| iff a plugin
+ // currently in the plugin list was actually disabled as a result; regardless
+ // of return value, if a plugin is found in the future with the given name, it
+ // will be disabled.
+ bool DisablePlugin(const FilePath& filename);
+
private:
// Constructors are private for singletons
PluginList();
@@ -222,6 +239,9 @@ class PluginList {
// Holds information about internal plugins.
std::vector<PluginVersionInfo> internal_plugins_;
+ // Path names of plugins to disable (the default is to enable them all).
+ std::set<FilePath> disabled_plugins_;
+
// Need synchronization for the above members since this object can be
// accessed on multiple threads.
Lock lock_;
diff --git a/webkit/glue/webplugininfo.h b/webkit/glue/webplugininfo.h
index 77c59ea..21f34df 100644
--- a/webkit/glue/webplugininfo.h
+++ b/webkit/glue/webplugininfo.h
@@ -39,6 +39,9 @@ struct WebPluginInfo {
// A list of all the mime types that this plugin supports.
std::vector<WebPluginMimeType> mime_types;
+
+ // Whether the plugin is enabled.
+ bool enabled;
};
#endif // WEBKIT_GLUE_WEBPLUGININFO_H_