1 // Copyright 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 "extensions/common/manifest_handlers/requirements_info.h"
7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.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_constants.h"
14 namespace extensions
{
16 namespace keys
= manifest_keys
;
17 namespace errors
= manifest_errors
;
19 RequirementsInfo::RequirementsInfo(const Manifest
* manifest
)
23 // Before parsing requirements from the manifest, automatically default the
24 // NPAPI plugin requirement based on whether it includes NPAPI plugins.
25 const base::ListValue
* list_value
= NULL
;
26 npapi
= manifest
->GetList(keys::kPlugins
, &list_value
) &&
30 RequirementsInfo::~RequirementsInfo() {
34 const RequirementsInfo
& RequirementsInfo::GetRequirements(
35 const Extension
* extension
) {
36 RequirementsInfo
* info
= static_cast<RequirementsInfo
*>(
37 extension
->GetManifestData(keys::kRequirements
));
39 // We should be guaranteed to have requirements, since they are parsed for all
45 RequirementsHandler::RequirementsHandler() {
48 RequirementsHandler::~RequirementsHandler() {
51 const std::vector
<std::string
> RequirementsHandler::PrerequisiteKeys() const {
52 return SingleKey(keys::kPlugins
);
55 const std::vector
<std::string
> RequirementsHandler::Keys() const {
56 return SingleKey(keys::kRequirements
);
59 bool RequirementsHandler::AlwaysParseForType(Manifest::Type type
) const {
63 bool RequirementsHandler::Parse(Extension
* extension
, string16
* error
) {
64 scoped_ptr
<RequirementsInfo
> requirements(
65 new RequirementsInfo(extension
->manifest()));
67 if (!extension
->manifest()->HasKey(keys::kRequirements
)) {
68 extension
->SetManifestData(keys::kRequirements
, requirements
.release());
72 const base::DictionaryValue
* requirements_value
= NULL
;
73 if (!extension
->manifest()->GetDictionary(keys::kRequirements
,
74 &requirements_value
)) {
75 *error
= ASCIIToUTF16(errors::kInvalidRequirements
);
79 for (base::DictionaryValue::Iterator
iter(*requirements_value
);
82 const base::DictionaryValue
* requirement_value
;
83 if (!iter
.value().GetAsDictionary(&requirement_value
)) {
84 *error
= ErrorUtils::FormatErrorMessageUTF16(
85 errors::kInvalidRequirement
, iter
.key());
89 if (iter
.key() == "plugins") {
90 for (base::DictionaryValue::Iterator
plugin_iter(*requirement_value
);
91 !plugin_iter
.IsAtEnd(); plugin_iter
.Advance()) {
92 bool plugin_required
= false;
93 if (!plugin_iter
.value().GetAsBoolean(&plugin_required
)) {
94 *error
= ErrorUtils::FormatErrorMessageUTF16(
95 errors::kInvalidRequirement
, iter
.key());
98 if (plugin_iter
.key() == "npapi") {
99 requirements
->npapi
= plugin_required
;
101 *error
= ErrorUtils::FormatErrorMessageUTF16(
102 errors::kInvalidRequirement
, iter
.key());
106 } else if (iter
.key() == "3D") {
107 const base::ListValue
* features
= NULL
;
108 if (!requirement_value
->GetListWithoutPathExpansion("features",
111 *error
= ErrorUtils::FormatErrorMessageUTF16(
112 errors::kInvalidRequirement
, iter
.key());
116 for (base::ListValue::const_iterator feature_iter
= features
->begin();
117 feature_iter
!= features
->end(); ++feature_iter
) {
119 if ((*feature_iter
)->GetAsString(&feature
)) {
120 if (feature
== "webgl") {
121 requirements
->webgl
= true;
122 } else if (feature
== "css3d") {
123 requirements
->css3d
= true;
125 *error
= ErrorUtils::FormatErrorMessageUTF16(
126 errors::kInvalidRequirement
, iter
.key());
132 *error
= ASCIIToUTF16(errors::kInvalidRequirements
);
137 extension
->SetManifestData(keys::kRequirements
, requirements
.release());
141 } // namespace extensions