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"
21 #include "base/win/metro.h"
24 namespace extensions
{
26 namespace keys
= manifest_keys
;
30 struct PluginManifestData
: Extension::ManifestData
{
31 // Optional list of NPAPI plugins and associated properties for an extension.
32 PluginInfo::PluginVector plugins
;
37 PluginInfo::PluginInfo(const base::FilePath
& plugin_path
, bool plugin_is_public
)
38 : path(plugin_path
), is_public(plugin_is_public
) {
41 PluginInfo::~PluginInfo() {
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
;
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
);
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
);
84 // Get plugins[i].path.
86 if (!plugin_value
->GetString(keys::kPluginsPath
, &path_str
)) {
87 *error
= ErrorUtils::FormatErrorMessageUTF16(
88 manifest_errors::kInvalidPluginsPath
, base::SizeTToString(i
));
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
));
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)
108 #elif defined(OS_WIN)
109 if (base::win::IsMetroProcess()) {
112 #endif // defined(OS_WIN).
113 plugins_data
->plugins
.push_back(PluginInfo(
114 extension
->path().Append(base::FilePath::FromUTF8Unsafe(path_str
)),
118 if (!plugins_data
->plugins
.empty()) {
119 extension
->SetManifestData(keys::kPlugins
, plugins_data
.release());
120 PermissionsParser::AddAPIPermission(extension
, APIPermission::kPlugin
);
126 bool PluginsHandler::Validate(const Extension
* extension
,
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
);
134 for (std::vector
<extensions::PluginInfo
>::const_iterator plugin
=
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());
148 } // namespace extensions