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