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