Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / api / plugins / plugins_handler.cc
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.
4
5 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
6
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 "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"
19
20 #if defined(OS_WIN)
21 #include "base/win/metro.h"
22 #endif
23
24 namespace extensions {
25
26 namespace keys = manifest_keys;
27
28 namespace {
29
30 struct PluginManifestData : Extension::ManifestData {
31   // Optional list of NPAPI plugins and associated properties for an extension.
32   PluginInfo::PluginVector plugins;
33 };
34
35 }  // namespace
36
37 PluginInfo::PluginInfo(const base::FilePath& plugin_path, bool plugin_is_public)
38     : path(plugin_path), is_public(plugin_is_public) {
39 }
40
41 PluginInfo::~PluginInfo() {
42 }
43
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;
50 }
51
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;
57 }
58
59 PluginsHandler::PluginsHandler() {
60 }
61
62 PluginsHandler::~PluginsHandler() {
63 }
64
65 const std::vector<std::string> PluginsHandler::Keys() const {
66   return SingleKey(keys::kPlugins);
67 }
68
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;
74   }
75
76   scoped_ptr<PluginManifestData> plugins_data(new PluginManifestData);
77
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;
83     }
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::IntToString(i));
89       return false;
90     }
91
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));
99         return false;
100       }
101     }
102
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)
108     continue;
109 #elif defined(OS_WIN)
110     if (base::win::IsMetroProcess()) {
111       continue;
112     }
113 #endif  // defined(OS_WIN).
114     plugins_data->plugins.push_back(PluginInfo(
115         extension->path().Append(base::FilePath::FromUTF8Unsafe(path_str)),
116         is_public));
117   }
118
119   if (!plugins_data->plugins.empty()) {
120     extension->SetManifestData(keys::kPlugins, plugins_data.release());
121     PermissionsParser::AddAPIPermission(extension, APIPermission::kPlugin);
122   }
123
124   return true;
125 }
126
127 bool PluginsHandler::Validate(const Extension* extension,
128                               std::string* error,
129                               std::vector<InstallWarning>* warnings) const {
130   // Validate claimed plugin paths.
131   if (extensions::PluginInfo::HasPlugins(extension)) {
132     const extensions::PluginInfo::PluginVector* plugins =
133         extensions::PluginInfo::GetPlugins(extension);
134     CHECK(plugins);
135     for (std::vector<extensions::PluginInfo>::const_iterator plugin =
136              plugins->begin();
137          plugin != plugins->end(); ++plugin) {
138       if (!base::PathExists(plugin->path)) {
139         *error = l10n_util::GetStringFUTF8(
140             IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED,
141             plugin->path.LossyDisplayName());
142       return false;
143       }
144     }
145   }
146   return true;
147 }
148
149 }  // namespace extensions