OLD | NEW |
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/features/feature.h" | 5 #include "chrome/common/extensions/features/simple_feature.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
| 8 #include <vector> |
8 | 9 |
9 #include "base/command_line.h" | 10 #include "base/command_line.h" |
10 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 12 #include "base/string_util.h" |
11 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
12 #include "base/string_util.h" | |
13 #include "chrome/common/chrome_switches.h" | 14 #include "chrome/common/chrome_switches.h" |
14 | 15 |
15 using chrome::VersionInfo; | 16 using chrome::VersionInfo; |
16 using extensions::Extension; | 17 using extensions::Extension; |
17 | 18 |
18 namespace { | 19 namespace { |
19 | 20 |
20 struct Mappings { | 21 struct Mappings { |
21 Mappings() { | 22 Mappings() { |
22 extension_types["extension"] = Extension::TYPE_EXTENSION; | 23 extension_types["extension"] = Extension::TYPE_EXTENSION; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 typedef std::map<std::string, VersionInfo::Channel> ChannelsMap; | 58 typedef std::map<std::string, VersionInfo::Channel> ChannelsMap; |
58 ChannelsMap channels = g_mappings.Get().channels; | 59 ChannelsMap channels = g_mappings.Get().channels; |
59 for (ChannelsMap::iterator i = channels.begin(); i != channels.end(); ++i) { | 60 for (ChannelsMap::iterator i = channels.begin(); i != channels.end(); ++i) { |
60 if (i->second == channel) | 61 if (i->second == channel) |
61 return i->first; | 62 return i->first; |
62 } | 63 } |
63 NOTREACHED(); | 64 NOTREACHED(); |
64 return "unknown"; | 65 return "unknown"; |
65 } | 66 } |
66 | 67 |
67 const VersionInfo::Channel kDefaultChannel = VersionInfo::CHANNEL_STABLE; | |
68 VersionInfo::Channel g_current_channel = kDefaultChannel; | |
69 | |
70 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? | 68 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? |
71 | 69 |
72 void ParseSet(const DictionaryValue* value, | 70 void ParseSet(const DictionaryValue* value, |
73 const std::string& property, | 71 const std::string& property, |
74 std::set<std::string>* set) { | 72 std::set<std::string>* set) { |
75 const ListValue* list_value = NULL; | 73 const ListValue* list_value = NULL; |
76 if (!value->GetList(property, &list_value)) | 74 if (!value->GetList(property, &list_value)) |
77 return; | 75 return; |
78 | 76 |
79 set->clear(); | 77 set->clear(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 } | 155 } |
158 | 156 |
159 NOTREACHED(); | 157 NOTREACHED(); |
160 return ""; | 158 return ""; |
161 } | 159 } |
162 | 160 |
163 } // namespace | 161 } // namespace |
164 | 162 |
165 namespace extensions { | 163 namespace extensions { |
166 | 164 |
167 Feature::Feature() | 165 SimpleFeature::SimpleFeature() |
168 : location_(UNSPECIFIED_LOCATION), | 166 : location_(UNSPECIFIED_LOCATION), |
169 platform_(UNSPECIFIED_PLATFORM), | 167 platform_(UNSPECIFIED_PLATFORM), |
170 min_manifest_version_(0), | 168 min_manifest_version_(0), |
171 max_manifest_version_(0), | 169 max_manifest_version_(0), |
172 channel_(VersionInfo::CHANNEL_UNKNOWN) { | 170 channel_(VersionInfo::CHANNEL_UNKNOWN) { |
173 } | 171 } |
174 | 172 |
175 Feature::Feature(const Feature& other) | 173 SimpleFeature::SimpleFeature(const SimpleFeature& other) |
176 : whitelist_(other.whitelist_), | 174 : whitelist_(other.whitelist_), |
177 extension_types_(other.extension_types_), | 175 extension_types_(other.extension_types_), |
178 contexts_(other.contexts_), | 176 contexts_(other.contexts_), |
179 location_(other.location_), | 177 location_(other.location_), |
180 platform_(other.platform_), | 178 platform_(other.platform_), |
181 min_manifest_version_(other.min_manifest_version_), | 179 min_manifest_version_(other.min_manifest_version_), |
182 max_manifest_version_(other.max_manifest_version_), | 180 max_manifest_version_(other.max_manifest_version_), |
183 channel_(other.channel_) { | 181 channel_(other.channel_) { |
184 } | 182 } |
185 | 183 |
186 Feature::~Feature() { | 184 SimpleFeature::~SimpleFeature() { |
187 } | 185 } |
188 | 186 |
189 bool Feature::Equals(const Feature& other) const { | 187 bool SimpleFeature::Equals(const SimpleFeature& other) const { |
190 return whitelist_ == other.whitelist_ && | 188 return whitelist_ == other.whitelist_ && |
191 extension_types_ == other.extension_types_ && | 189 extension_types_ == other.extension_types_ && |
192 contexts_ == other.contexts_ && | 190 contexts_ == other.contexts_ && |
193 location_ == other.location_ && | 191 location_ == other.location_ && |
194 platform_ == other.platform_ && | 192 platform_ == other.platform_ && |
195 min_manifest_version_ == other.min_manifest_version_ && | 193 min_manifest_version_ == other.min_manifest_version_ && |
196 max_manifest_version_ == other.max_manifest_version_ && | 194 max_manifest_version_ == other.max_manifest_version_ && |
197 channel_ == other.channel_; | 195 channel_ == other.channel_; |
198 } | 196 } |
199 | 197 |
200 // static | 198 void SimpleFeature::Parse(const DictionaryValue* value) { |
201 Feature::Platform Feature::GetCurrentPlatform() { | |
202 #if defined(OS_CHROMEOS) | |
203 return CHROMEOS_PLATFORM; | |
204 #else | |
205 return UNSPECIFIED_PLATFORM; | |
206 #endif | |
207 } | |
208 | |
209 // static | |
210 Feature::Location Feature::ConvertLocation(Extension::Location location) { | |
211 if (location == Extension::COMPONENT) | |
212 return COMPONENT_LOCATION; | |
213 else | |
214 return UNSPECIFIED_LOCATION; | |
215 } | |
216 | |
217 void Feature::Parse(const DictionaryValue* value) { | |
218 ParseSet(value, "whitelist", &whitelist_); | 199 ParseSet(value, "whitelist", &whitelist_); |
219 ParseEnumSet<Extension::Type>(value, "extension_types", &extension_types_, | 200 ParseEnumSet<Extension::Type>(value, "extension_types", &extension_types_, |
220 g_mappings.Get().extension_types); | 201 g_mappings.Get().extension_types); |
221 ParseEnumSet<Context>(value, "contexts", &contexts_, | 202 ParseEnumSet<Context>(value, "contexts", &contexts_, |
222 g_mappings.Get().contexts); | 203 g_mappings.Get().contexts); |
223 ParseEnum<Location>(value, "location", &location_, | 204 ParseEnum<Location>(value, "location", &location_, |
224 g_mappings.Get().locations); | 205 g_mappings.Get().locations); |
225 ParseEnum<Platform>(value, "platform", &platform_, | 206 ParseEnum<Platform>(value, "platform", &platform_, |
226 g_mappings.Get().platforms); | 207 g_mappings.Get().platforms); |
227 value->GetInteger("min_manifest_version", &min_manifest_version_); | 208 value->GetInteger("min_manifest_version", &min_manifest_version_); |
228 value->GetInteger("max_manifest_version", &max_manifest_version_); | 209 value->GetInteger("max_manifest_version", &max_manifest_version_); |
229 ParseEnum<VersionInfo::Channel>( | 210 ParseEnum<VersionInfo::Channel>( |
230 value, "channel", &channel_, | 211 value, "channel", &channel_, |
231 g_mappings.Get().channels); | 212 g_mappings.Get().channels); |
232 } | 213 } |
233 | 214 |
234 Feature::Availability Feature::IsAvailableToManifest( | 215 Feature::Availability SimpleFeature::IsAvailableToManifest( |
235 const std::string& extension_id, | 216 const std::string& extension_id, |
236 Extension::Type type, | 217 Extension::Type type, |
237 Location location, | 218 Location location, |
238 int manifest_version, | 219 int manifest_version, |
239 Platform platform) const { | 220 Platform platform) const { |
240 // Component extensions can access any feature. | 221 // Component extensions can access any feature. |
241 if (location == COMPONENT_LOCATION) | 222 if (location == COMPONENT_LOCATION) |
242 return CreateAvailability(IS_AVAILABLE, type); | 223 return CreateAvailability(IS_AVAILABLE, type); |
243 | 224 |
244 if (!whitelist_.empty()) { | 225 if (!whitelist_.empty()) { |
(...skipping 22 matching lines...) Expand all Loading... |
267 | 248 |
268 if (platform_ != UNSPECIFIED_PLATFORM && platform_ != platform) | 249 if (platform_ != UNSPECIFIED_PLATFORM && platform_ != platform) |
269 return CreateAvailability(INVALID_PLATFORM, type); | 250 return CreateAvailability(INVALID_PLATFORM, type); |
270 | 251 |
271 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) | 252 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) |
272 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); | 253 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); |
273 | 254 |
274 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) | 255 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) |
275 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); | 256 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); |
276 | 257 |
277 if (channel_ < g_current_channel) | 258 if (channel_ < Feature::GetCurrentChannel()) |
278 return CreateAvailability(UNSUPPORTED_CHANNEL, type); | 259 return CreateAvailability(UNSUPPORTED_CHANNEL, type); |
279 | 260 |
280 return CreateAvailability(IS_AVAILABLE, type); | 261 return CreateAvailability(IS_AVAILABLE, type); |
281 } | 262 } |
282 | 263 |
283 Feature::Availability Feature::IsAvailableToContext( | 264 Feature::Availability SimpleFeature::IsAvailableToContext( |
284 const Extension* extension, | 265 const Extension* extension, |
285 Feature::Context context, | 266 SimpleFeature::Context context, |
286 Feature::Platform platform) const { | 267 SimpleFeature::Platform platform) const { |
287 Availability result = IsAvailableToManifest( | 268 Availability result = IsAvailableToManifest( |
288 extension->id(), | 269 extension->id(), |
289 extension->GetType(), | 270 extension->GetType(), |
290 ConvertLocation(extension->location()), | 271 ConvertLocation(extension->location()), |
291 extension->manifest_version(), | 272 extension->manifest_version(), |
292 platform); | 273 platform); |
293 if (!result.is_available()) | 274 if (!result.is_available()) |
294 return result; | 275 return result; |
295 | 276 |
296 if (!contexts_.empty() && | 277 if (!contexts_.empty() && |
297 contexts_.find(context) == contexts_.end()) { | 278 contexts_.find(context) == contexts_.end()) { |
298 return CreateAvailability(INVALID_CONTEXT, extension->GetType()); | 279 return CreateAvailability(INVALID_CONTEXT, extension->GetType()); |
299 } | 280 } |
300 | 281 |
301 return CreateAvailability(IS_AVAILABLE); | 282 return CreateAvailability(IS_AVAILABLE); |
302 } | 283 } |
303 | 284 |
304 // static | 285 std::string SimpleFeature::GetAvailabilityMessage( |
305 chrome::VersionInfo::Channel Feature::GetCurrentChannel() { | |
306 return g_current_channel; | |
307 } | |
308 | |
309 // static | |
310 void Feature::SetCurrentChannel(VersionInfo::Channel channel) { | |
311 g_current_channel = channel; | |
312 } | |
313 | |
314 // static | |
315 chrome::VersionInfo::Channel Feature::GetDefaultChannel() { | |
316 return kDefaultChannel; | |
317 } | |
318 | |
319 Feature::Availability Feature::CreateAvailability( | |
320 AvailabilityResult result) const { | |
321 return Availability( | |
322 result, GetAvailabilityMessage(result, Extension::TYPE_UNKNOWN)); | |
323 } | |
324 | |
325 Feature::Availability Feature::CreateAvailability( | |
326 AvailabilityResult result, Extension::Type type) const { | |
327 return Availability(result, GetAvailabilityMessage(result, type)); | |
328 } | |
329 | |
330 std::string Feature::GetAvailabilityMessage( | |
331 AvailabilityResult result, Extension::Type type) const { | 286 AvailabilityResult result, Extension::Type type) const { |
332 switch (result) { | 287 switch (result) { |
333 case IS_AVAILABLE: | 288 case IS_AVAILABLE: |
334 return ""; | 289 return ""; |
335 case NOT_FOUND_IN_WHITELIST: | 290 case NOT_FOUND_IN_WHITELIST: |
336 return base::StringPrintf( | 291 return base::StringPrintf( |
337 "'%s' is not allowed for specified extension ID.", | 292 "'%s' is not allowed for specified extension ID.", |
338 name().c_str()); | 293 name().c_str()); |
339 case INVALID_TYPE: { | 294 case INVALID_TYPE: { |
340 std::string allowed_type_names; | 295 std::string allowed_type_names; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 "%s channel.", | 346 "%s channel.", |
392 name().c_str(), | 347 name().c_str(), |
393 GetChannelName(channel_).c_str(), | 348 GetChannelName(channel_).c_str(), |
394 GetChannelName(GetCurrentChannel()).c_str()); | 349 GetChannelName(GetCurrentChannel()).c_str()); |
395 } | 350 } |
396 | 351 |
397 NOTREACHED(); | 352 NOTREACHED(); |
398 return ""; | 353 return ""; |
399 } | 354 } |
400 | 355 |
| 356 Feature::Availability SimpleFeature::CreateAvailability( |
| 357 AvailabilityResult result) const { |
| 358 return Availability( |
| 359 result, GetAvailabilityMessage(result, Extension::TYPE_UNKNOWN)); |
| 360 } |
| 361 |
| 362 Feature::Availability SimpleFeature::CreateAvailability( |
| 363 AvailabilityResult result, Extension::Type type) const { |
| 364 return Availability(result, GetAvailabilityMessage(result, type)); |
| 365 } |
| 366 |
| 367 std::set<Feature::Context>* SimpleFeature::GetContexts() { |
| 368 return &contexts_; |
| 369 } |
401 | 370 |
402 } // namespace extensions | 371 } // namespace extensions |
OLD | NEW |