| 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 |