Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: chrome/common/extensions/feature.cc

Issue 9950046: Implement FeatureProvider for ExtensionAPI. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/extensions/feature.h" 5 #include "chrome/common/extensions/feature.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 44
45 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? 45 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff?
46 46
47 void ParseSet(const DictionaryValue* value, 47 void ParseSet(const DictionaryValue* value,
48 const std::string& property, 48 const std::string& property,
49 std::set<std::string>* set) { 49 std::set<std::string>* set) {
50 ListValue* list_value = NULL; 50 ListValue* list_value = NULL;
51 if (!value->GetList(property, &list_value)) 51 if (!value->GetList(property, &list_value))
52 return; 52 return;
53 53
54 set->clear();
54 for (size_t i = 0; i < list_value->GetSize(); ++i) { 55 for (size_t i = 0; i < list_value->GetSize(); ++i) {
55 std::string str_val; 56 std::string str_val;
56 CHECK(list_value->GetString(i, &str_val)) << property << " " << i; 57 CHECK(list_value->GetString(i, &str_val)) << property << " " << i;
57 set->insert(str_val); 58 set->insert(str_val);
58 } 59 }
59 } 60 }
60 61
61 template<typename T> 62 template<typename T>
62 void ParseEnum(const std::string& string_value, 63 void ParseEnum(const std::string& string_value,
63 T* enum_value, 64 T* enum_value,
64 const std::map<std::string, T>& mapping) { 65 const std::map<std::string, T>& mapping) {
65 typename std::map<std::string, T>::const_iterator iter = 66 typename std::map<std::string, T>::const_iterator iter =
66 mapping.find(string_value); 67 mapping.find(string_value);
67 CHECK(iter != mapping.end()) << string_value; 68 CHECK(iter != mapping.end()) << string_value;
68 *enum_value = iter->second; 69 *enum_value = iter->second;
69 } 70 }
70 71
71 template<typename T> 72 template<typename T>
72 void ParseEnum(const DictionaryValue* value, 73 void ParseEnum(const DictionaryValue* value,
73 const std::string& property, 74 const std::string& property,
74 T* enum_value, 75 T* enum_value,
75 const std::map<std::string, T>& mapping) { 76 const std::map<std::string, T>& mapping) {
76 std::string string_value; 77 std::string string_value;
77 if (!value->GetString(property, &string_value)) 78 if (!value->GetString(property, &string_value))
78 return; 79 return;
80
79 ParseEnum(string_value, enum_value, mapping); 81 ParseEnum(string_value, enum_value, mapping);
80 } 82 }
81 83
82 template<typename T> 84 template<typename T>
83 void ParseEnumSet(const DictionaryValue* value, 85 void ParseEnumSet(const DictionaryValue* value,
84 const std::string& property, 86 const std::string& property,
85 std::set<T>* enum_set, 87 std::set<T>* enum_set,
86 const std::map<std::string, T>& mapping) { 88 const std::map<std::string, T>& mapping) {
89 if (!value->HasKey(property))
90 return;
91
92 enum_set->clear();
93
87 std::string property_string; 94 std::string property_string;
88 if (value->GetString(property, &property_string)) { 95 if (value->GetString(property, &property_string)) {
89 if (property_string == "all") { 96 if (property_string == "all") {
90 for (typename std::map<std::string, T>::const_iterator j = 97 for (typename std::map<std::string, T>::const_iterator j =
91 mapping.begin(); j != mapping.end(); ++j) { 98 mapping.begin(); j != mapping.end(); ++j) {
92 enum_set->insert(j->second); 99 enum_set->insert(j->second);
93 } 100 }
94 } 101 }
95 return; 102 return;
96 } 103 }
(...skipping 12 matching lines...) Expand all
109 116
110 namespace extensions { 117 namespace extensions {
111 118
112 Feature::Feature() 119 Feature::Feature()
113 : location_(UNSPECIFIED_LOCATION), 120 : location_(UNSPECIFIED_LOCATION),
114 platform_(UNSPECIFIED_PLATFORM), 121 platform_(UNSPECIFIED_PLATFORM),
115 min_manifest_version_(0), 122 min_manifest_version_(0),
116 max_manifest_version_(0) { 123 max_manifest_version_(0) {
117 } 124 }
118 125
126 Feature::Feature(const Feature& other)
127 : whitelist_(other.whitelist_),
128 extension_types_(other.extension_types_),
129 contexts_(other.contexts_),
130 location_(other.location_),
131 platform_(other.platform_),
132 min_manifest_version_(other.min_manifest_version_),
133 max_manifest_version_(other.max_manifest_version_) {
134 }
135
119 Feature::~Feature() { 136 Feature::~Feature() {
120 } 137 }
121 138
122 // static 139 bool Feature::Equals(const Feature& other) const {
123 scoped_ptr<Feature> Feature::Parse(const DictionaryValue* value) { 140 return whitelist_ == other.whitelist_ &&
124 scoped_ptr<Feature> feature(new Feature()); 141 extension_types_ == other.extension_types_ &&
125 142 contexts_ == other.contexts_ &&
126 ParseSet(value, "whitelist", feature->whitelist()); 143 location_ == other.location_ &&
127 ParseEnumSet<Extension::Type>(value, "extension_types", 144 platform_ == other.platform_ &&
128 feature->extension_types(), 145 min_manifest_version_ == other.min_manifest_version_ &&
129 g_mappings.Get().extension_types); 146 max_manifest_version_ == other.max_manifest_version_;
130 ParseEnumSet<Context>(value, "contexts", feature->contexts(),
131 g_mappings.Get().contexts);
132 ParseEnum<Location>(value, "location", &feature->location_,
133 g_mappings.Get().locations);
134 ParseEnum<Platform>(value, "platform", &feature->platform_,
135 g_mappings.Get().platforms);
136
137 value->GetInteger("min_manifest_version", &feature->min_manifest_version_);
138 value->GetInteger("max_manifest_version", &feature->max_manifest_version_);
139
140 return feature.Pass();
141 } 147 }
142 148
143 // static 149 // static
144 Feature::Platform Feature::GetCurrentPlatform() { 150 Feature::Platform Feature::GetCurrentPlatform() {
145 #if defined(OS_CHROMEOS) 151 #if defined(OS_CHROMEOS)
146 return CHROMEOS_PLATFORM; 152 return CHROMEOS_PLATFORM;
147 #else 153 #else
148 return UNSPECIFIED_PLATFORM; 154 return UNSPECIFIED_PLATFORM;
149 #endif 155 #endif
150 } 156 }
151 157
152 // static 158 // static
153 Feature::Location Feature::ConvertLocation(Extension::Location location) { 159 Feature::Location Feature::ConvertLocation(Extension::Location location) {
154 if (location == Extension::COMPONENT) 160 if (location == Extension::COMPONENT)
155 return COMPONENT_LOCATION; 161 return COMPONENT_LOCATION;
156 else 162 else
157 return UNSPECIFIED_LOCATION; 163 return UNSPECIFIED_LOCATION;
158 } 164 }
159 165
166 void Feature::Parse(const DictionaryValue* value) {
167 ParseSet(value, "whitelist", &whitelist_);
168 ParseEnumSet<Extension::Type>(value, "extension_types", &extension_types_,
169 g_mappings.Get().extension_types);
170 ParseEnumSet<Context>(value, "contexts", &contexts_,
171 g_mappings.Get().contexts);
172 ParseEnum<Location>(value, "location", &location_,
173 g_mappings.Get().locations);
174 ParseEnum<Platform>(value, "platform", &platform_,
175 g_mappings.Get().platforms);
176 value->GetInteger("min_manifest_version", &min_manifest_version_);
177 value->GetInteger("max_manifest_version", &max_manifest_version_);
178 }
179
160 std::string Feature::GetErrorMessage(Feature::Availability result) { 180 std::string Feature::GetErrorMessage(Feature::Availability result) {
161 switch (result) { 181 switch (result) {
162 case IS_AVAILABLE: 182 case IS_AVAILABLE:
163 return ""; 183 return "";
164 case NOT_FOUND_IN_WHITELIST: 184 case NOT_FOUND_IN_WHITELIST:
165 return "Not allowed for specified extension ID."; 185 return "Not allowed for specified extension ID.";
166 case INVALID_TYPE: 186 case INVALID_TYPE:
167 return "Not allowed for specified package type (theme, app, etc.)."; 187 return "Not allowed for specified package type (theme, app, etc.).";
168 case INVALID_CONTEXT: 188 case INVALID_CONTEXT:
169 return "Not allowed for specified context type content script, extension " 189 return "Not allowed for specified context type content script, extension "
170 "page, web page, etc.)."; 190 "page, web page, etc.).";
171 case INVALID_LOCATION: 191 case INVALID_LOCATION:
172 return "Not allowed for specified install location."; 192 return "Not allowed for specified install location.";
173 case INVALID_PLATFORM: 193 case INVALID_PLATFORM:
174 return "Not allowed for specified platform."; 194 return "Not allowed for specified platform.";
175 case INVALID_MIN_MANIFEST_VERSION: 195 case INVALID_MIN_MANIFEST_VERSION:
176 return base::StringPrintf("Requires manifest version of at least %d.", 196 return base::StringPrintf("Requires manifest version of at least %d.",
177 min_manifest_version_); 197 min_manifest_version_);
178 case INVALID_MAX_MANIFEST_VERSION: 198 case INVALID_MAX_MANIFEST_VERSION:
179 return base::StringPrintf("Requires manifest version of %d or lower.", 199 return base::StringPrintf("Requires manifest version of %d or lower.",
180 max_manifest_version_); 200 max_manifest_version_);
181 default: 201 default:
182 CHECK(false); 202 CHECK(false);
183 return ""; 203 return "";
184 } 204 }
185 } 205 }
186 206
187 Feature::Availability Feature::IsAvailable(const std::string& extension_id, 207 Feature::Availability Feature::IsAvailableToManifest(
188 Extension::Type type, 208 const std::string& extension_id,
189 Location location, 209 Extension::Type type,
190 Context context, 210 Location location,
191 Platform platform, 211 int manifest_version,
192 int manifest_version) { 212 Platform platform) const {
193 // Component extensions can access any feature. 213 // Component extensions can access any feature.
194 if (location == COMPONENT_LOCATION) 214 if (location == COMPONENT_LOCATION)
195 return IS_AVAILABLE; 215 return IS_AVAILABLE;
196 216
197 if (!whitelist_.empty()) { 217 if (!whitelist_.empty()) {
198 if (whitelist_.find(extension_id) == whitelist_.end()) { 218 if (whitelist_.find(extension_id) == whitelist_.end()) {
199 // TODO(aa): This is gross. There should be a better way to test the 219 // TODO(aa): This is gross. There should be a better way to test the
200 // whitelist. 220 // whitelist.
201 CommandLine* command_line = CommandLine::ForCurrentProcess(); 221 CommandLine* command_line = CommandLine::ForCurrentProcess();
202 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) 222 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID))
203 return NOT_FOUND_IN_WHITELIST; 223 return NOT_FOUND_IN_WHITELIST;
204 224
205 std::string whitelist_switch_value = 225 std::string whitelist_switch_value =
206 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 226 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
207 switches::kWhitelistedExtensionID); 227 switches::kWhitelistedExtensionID);
208 if (extension_id != whitelist_switch_value) 228 if (extension_id != whitelist_switch_value)
209 return NOT_FOUND_IN_WHITELIST; 229 return NOT_FOUND_IN_WHITELIST;
210 } 230 }
211 } 231 }
212 232
213 if (!extension_types_.empty() && 233 if (!extension_types_.empty() &&
214 extension_types_.find(type) == extension_types_.end()) { 234 extension_types_.find(type) == extension_types_.end()) {
215 return INVALID_TYPE; 235 return INVALID_TYPE;
216 } 236 }
217 237
218 if (!contexts_.empty() &&
219 contexts_.find(context) == contexts_.end()) {
220 return INVALID_CONTEXT;
221 }
222
223 if (location_ != UNSPECIFIED_LOCATION && location_ != location) 238 if (location_ != UNSPECIFIED_LOCATION && location_ != location)
224 return INVALID_LOCATION; 239 return INVALID_LOCATION;
225 240
226 if (platform_ != UNSPECIFIED_PLATFORM && platform_ != platform) 241 if (platform_ != UNSPECIFIED_PLATFORM && platform_ != platform)
227 return INVALID_PLATFORM; 242 return INVALID_PLATFORM;
228 243
229 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) 244 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_)
230 return INVALID_MIN_MANIFEST_VERSION; 245 return INVALID_MIN_MANIFEST_VERSION;
231 246
232 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) 247 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_)
233 return INVALID_MAX_MANIFEST_VERSION; 248 return INVALID_MAX_MANIFEST_VERSION;
234 249
235 return IS_AVAILABLE; 250 return IS_AVAILABLE;
236 } 251 }
237 252
253 Feature::Availability Feature::IsAvailableToContext(
254 const Extension* extension,
255 Feature::Context context,
256 Feature::Platform platform) const {
257 Availability result = IsAvailableToManifest(
258 extension->id(),
259 extension->GetType(),
260 ConvertLocation(extension->location()),
261 extension->manifest_version(),
262 platform);
263 if (result != IS_AVAILABLE)
264 return result;
265
266 if (!contexts_.empty() &&
267 contexts_.find(context) == contexts_.end()) {
268 return INVALID_CONTEXT;
269 }
270
271 return IS_AVAILABLE;
272 }
273
238 } // namespace 274 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698