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/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 "extensions/common/error_utils.h"
12 #include "extensions/common/manifest.h"
13 #include "extensions/common/manifest_constants.h"
14 #include "extensions/common/permissions/api_permission.h"
15 #include "extensions/common/permissions/api_permission_set.h"
16 #include "extensions/common/permissions/permissions_data.h"
17 #include "grit/generated_resources.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::IntToString(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
,
98 base::IntToString(i
));
103 // We don't allow extensions to load NPAPI plugins on Chrome OS, or under
104 // Windows 8 Metro mode, but still parse the entries to display consistent
105 // error messages. If the extension actually requires the plugins then
106 // LoadRequirements will prevent it loading.
107 #if defined(OS_CHROMEOS)
109 #elif defined(OS_WIN)
110 if (base::win::IsMetroProcess()) {
113 #endif // defined(OS_WIN).
114 plugins_data
->plugins
.push_back(PluginInfo(
115 extension
->path().Append(base::FilePath::FromUTF8Unsafe(path_str
)),
119 if (!plugins_data
->plugins
.empty()) {
120 extension
->SetManifestData(keys::kPlugins
, plugins_data
.release());
121 PermissionsData::GetInitialAPIPermissions(extension
)->insert(
122 APIPermission::kPlugin
);
128 bool PluginsHandler::Validate(const Extension
* extension
,
130 std::vector
<InstallWarning
>* warnings
) const {
131 // Validate claimed plugin paths.
132 if (extensions::PluginInfo::HasPlugins(extension
)) {
133 const extensions::PluginInfo::PluginVector
* plugins
=
134 extensions::PluginInfo::GetPlugins(extension
);
136 for (std::vector
<extensions::PluginInfo
>::const_iterator plugin
=
138 plugin
!= plugins
->end(); ++plugin
) {
139 if (!base::PathExists(plugin
->path
)) {
140 *error
= l10n_util::GetStringFUTF8(
141 IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED
,
142 plugin
->path
.LossyDisplayName());
150 } // namespace extensions