Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / common / extensions / api / plugins / plugins_handler.cc
blob6cb2caceeb7ed789a3e0a5fa95abce1529c34ada
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
7 #include "base/files/file_util.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "chrome/grit/generated_resources.h"
12 #include "extensions/common/error_utils.h"
13 #include "extensions/common/manifest.h"
14 #include "extensions/common/manifest_constants.h"
15 #include "extensions/common/manifest_handlers/permissions_parser.h"
16 #include "extensions/common/permissions/api_permission.h"
17 #include "extensions/common/permissions/api_permission_set.h"
18 #include "ui/base/l10n/l10n_util.h"
20 #if defined(OS_WIN)
21 #include "base/win/metro.h"
22 #endif
24 namespace extensions {
26 namespace keys = manifest_keys;
28 namespace {
30 struct PluginManifestData : Extension::ManifestData {
31 // Optional list of NPAPI plugins and associated properties for an extension.
32 PluginInfo::PluginVector plugins;
35 } // namespace
37 PluginInfo::PluginInfo(const base::FilePath& plugin_path, bool plugin_is_public)
38 : path(plugin_path), is_public(plugin_is_public) {
41 PluginInfo::~PluginInfo() {
44 // static
45 const PluginInfo::PluginVector* PluginInfo::GetPlugins(
46 const Extension* extension) {
47 PluginManifestData* data = static_cast<PluginManifestData*>(
48 extension->GetManifestData(keys::kPlugins));
49 return data ? &data->plugins : NULL;
52 // static
53 bool PluginInfo::HasPlugins(const Extension* extension) {
54 PluginManifestData* data = static_cast<PluginManifestData*>(
55 extension->GetManifestData(keys::kPlugins));
56 return data && !data->plugins.empty() ? true : false;
59 PluginsHandler::PluginsHandler() {
62 PluginsHandler::~PluginsHandler() {
65 const std::vector<std::string> PluginsHandler::Keys() const {
66 return SingleKey(keys::kPlugins);
69 bool PluginsHandler::Parse(Extension* extension, base::string16* error) {
70 const base::ListValue* list_value = NULL;
71 if (!extension->manifest()->GetList(keys::kPlugins, &list_value)) {
72 *error = base::ASCIIToUTF16(manifest_errors::kInvalidPlugins);
73 return false;
76 scoped_ptr<PluginManifestData> plugins_data(new PluginManifestData);
78 for (size_t i = 0; i < list_value->GetSize(); ++i) {
79 const base::DictionaryValue* plugin_value = NULL;
80 if (!list_value->GetDictionary(i, &plugin_value)) {
81 *error = base::ASCIIToUTF16(manifest_errors::kInvalidPlugins);
82 return false;
84 // Get plugins[i].path.
85 std::string path_str;
86 if (!plugin_value->GetString(keys::kPluginsPath, &path_str)) {
87 *error = ErrorUtils::FormatErrorMessageUTF16(
88 manifest_errors::kInvalidPluginsPath, base::SizeTToString(i));
89 return false;
92 // Get plugins[i].content (optional).
93 bool is_public = false;
94 if (plugin_value->HasKey(keys::kPluginsPublic)) {
95 if (!plugin_value->GetBoolean(keys::kPluginsPublic, &is_public)) {
96 *error = ErrorUtils::FormatErrorMessageUTF16(
97 manifest_errors::kInvalidPluginsPublic, base::SizeTToString(i));
98 return false;
102 // We don't allow extensions to load NPAPI plugins on Chrome OS, or under
103 // Windows 8 Metro mode, but still parse the entries to display consistent
104 // error messages. If the extension actually requires the plugins then
105 // LoadRequirements will prevent it loading.
106 #if defined(OS_CHROMEOS)
107 continue;
108 #elif defined(OS_WIN)
109 if (base::win::IsMetroProcess()) {
110 continue;
112 #endif // defined(OS_WIN).
113 plugins_data->plugins.push_back(PluginInfo(
114 extension->path().Append(base::FilePath::FromUTF8Unsafe(path_str)),
115 is_public));
118 if (!plugins_data->plugins.empty()) {
119 extension->SetManifestData(keys::kPlugins, plugins_data.release());
120 PermissionsParser::AddAPIPermission(extension, APIPermission::kPlugin);
123 return true;
126 bool PluginsHandler::Validate(const Extension* extension,
127 std::string* error,
128 std::vector<InstallWarning>* warnings) const {
129 // Validate claimed plugin paths.
130 if (extensions::PluginInfo::HasPlugins(extension)) {
131 const extensions::PluginInfo::PluginVector* plugins =
132 extensions::PluginInfo::GetPlugins(extension);
133 CHECK(plugins);
134 for (std::vector<extensions::PluginInfo>::const_iterator plugin =
135 plugins->begin();
136 plugin != plugins->end(); ++plugin) {
137 if (!base::PathExists(plugin->path)) {
138 *error = l10n_util::GetStringFUTF8(
139 IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED,
140 plugin->path.LossyDisplayName());
141 return false;
145 return true;
148 } // namespace extensions