OLD | NEW |
| (Empty) |
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/manifest_handlers/requirements_handler.h" | |
6 | |
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" | |
13 | |
14 namespace extensions { | |
15 | |
16 namespace keys = manifest_keys; | |
17 namespace errors = manifest_errors; | |
18 | |
19 RequirementsInfo::RequirementsInfo(const Manifest* manifest) | |
20 : webgl(false), | |
21 css3d(false), | |
22 npapi(false) { | |
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) && | |
27 !list_value->empty(); | |
28 } | |
29 | |
30 RequirementsInfo::~RequirementsInfo() { | |
31 } | |
32 | |
33 // static | |
34 const RequirementsInfo& RequirementsInfo::GetRequirements( | |
35 const Extension* extension) { | |
36 RequirementsInfo* info = static_cast<RequirementsInfo*>( | |
37 extension->GetManifestData(keys::kRequirements)); | |
38 | |
39 // We should be guaranteed to have requirements, since they are parsed for all | |
40 // extension types. | |
41 CHECK(info); | |
42 return *info; | |
43 } | |
44 | |
45 RequirementsHandler::RequirementsHandler() { | |
46 } | |
47 | |
48 RequirementsHandler::~RequirementsHandler() { | |
49 } | |
50 | |
51 const std::vector<std::string> RequirementsHandler::PrerequisiteKeys() const { | |
52 return SingleKey(keys::kPlugins); | |
53 } | |
54 | |
55 const std::vector<std::string> RequirementsHandler::Keys() const { | |
56 return SingleKey(keys::kRequirements); | |
57 } | |
58 | |
59 bool RequirementsHandler::AlwaysParseForType(Manifest::Type type) const { | |
60 return true; | |
61 } | |
62 | |
63 bool RequirementsHandler::Parse(Extension* extension, string16* error) { | |
64 scoped_ptr<RequirementsInfo> requirements( | |
65 new RequirementsInfo(extension->manifest())); | |
66 | |
67 if (!extension->manifest()->HasKey(keys::kRequirements)) { | |
68 extension->SetManifestData(keys::kRequirements, requirements.release()); | |
69 return true; | |
70 } | |
71 | |
72 const base::DictionaryValue* requirements_value = NULL; | |
73 if (!extension->manifest()->GetDictionary(keys::kRequirements, | |
74 &requirements_value)) { | |
75 *error = ASCIIToUTF16(errors::kInvalidRequirements); | |
76 return false; | |
77 } | |
78 | |
79 for (base::DictionaryValue::Iterator iter(*requirements_value); | |
80 !iter.IsAtEnd(); | |
81 iter.Advance()) { | |
82 const base::DictionaryValue* requirement_value; | |
83 if (!iter.value().GetAsDictionary(&requirement_value)) { | |
84 *error = ErrorUtils::FormatErrorMessageUTF16( | |
85 errors::kInvalidRequirement, iter.key()); | |
86 return false; | |
87 } | |
88 | |
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()); | |
96 return false; | |
97 } | |
98 if (plugin_iter.key() == "npapi") { | |
99 requirements->npapi = plugin_required; | |
100 } else { | |
101 *error = ErrorUtils::FormatErrorMessageUTF16( | |
102 errors::kInvalidRequirement, iter.key()); | |
103 return false; | |
104 } | |
105 } | |
106 } else if (iter.key() == "3D") { | |
107 const base::ListValue* features = NULL; | |
108 if (!requirement_value->GetListWithoutPathExpansion("features", | |
109 &features) || | |
110 !features) { | |
111 *error = ErrorUtils::FormatErrorMessageUTF16( | |
112 errors::kInvalidRequirement, iter.key()); | |
113 return false; | |
114 } | |
115 | |
116 for (base::ListValue::const_iterator feature_iter = features->begin(); | |
117 feature_iter != features->end(); ++feature_iter) { | |
118 std::string feature; | |
119 if ((*feature_iter)->GetAsString(&feature)) { | |
120 if (feature == "webgl") { | |
121 requirements->webgl = true; | |
122 } else if (feature == "css3d") { | |
123 requirements->css3d = true; | |
124 } else { | |
125 *error = ErrorUtils::FormatErrorMessageUTF16( | |
126 errors::kInvalidRequirement, iter.key()); | |
127 return false; | |
128 } | |
129 } | |
130 } | |
131 } else { | |
132 *error = ASCIIToUTF16(errors::kInvalidRequirements); | |
133 return false; | |
134 } | |
135 } | |
136 | |
137 extension->SetManifestData(keys::kRequirements, requirements.release()); | |
138 return true; | |
139 } | |
140 | |
141 } // namespace extensions | |
OLD | NEW |