Chromium Code Reviews| 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/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" |
| 11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
| 12 #include "chrome/common/chrome_switches.h" | 12 #include "chrome/common/chrome_switches.h" |
| 13 | 13 |
| 14 using chrome::VersionInfo; | |
| 15 | |
| 14 namespace { | 16 namespace { |
| 15 | 17 |
| 16 struct Mappings { | 18 struct Mappings { |
| 17 Mappings() { | 19 Mappings() { |
| 18 extension_types["extension"] = Extension::TYPE_EXTENSION; | 20 extension_types["extension"] = Extension::TYPE_EXTENSION; |
| 19 extension_types["theme"] = Extension::TYPE_THEME; | 21 extension_types["theme"] = Extension::TYPE_THEME; |
| 20 extension_types["packaged_app"] = Extension::TYPE_PACKAGED_APP; | 22 extension_types["packaged_app"] = Extension::TYPE_PACKAGED_APP; |
| 21 extension_types["hosted_app"] = Extension::TYPE_HOSTED_APP; | 23 extension_types["hosted_app"] = Extension::TYPE_HOSTED_APP; |
| 22 extension_types["platform_app"] = Extension::TYPE_PLATFORM_APP; | 24 extension_types["platform_app"] = Extension::TYPE_PLATFORM_APP; |
| 23 | 25 |
| 24 contexts["blessed_extension"] = | 26 contexts["blessed_extension"] = |
| 25 extensions::Feature::BLESSED_EXTENSION_CONTEXT; | 27 extensions::Feature::BLESSED_EXTENSION_CONTEXT; |
| 26 contexts["unblessed_extension"] = | 28 contexts["unblessed_extension"] = |
| 27 extensions::Feature::UNBLESSED_EXTENSION_CONTEXT; | 29 extensions::Feature::UNBLESSED_EXTENSION_CONTEXT; |
| 28 contexts["content_script"] = extensions::Feature::CONTENT_SCRIPT_CONTEXT; | 30 contexts["content_script"] = extensions::Feature::CONTENT_SCRIPT_CONTEXT; |
| 29 contexts["web_page"] = extensions::Feature::WEB_PAGE_CONTEXT; | 31 contexts["web_page"] = extensions::Feature::WEB_PAGE_CONTEXT; |
| 30 | 32 |
| 31 locations["component"] = extensions::Feature::COMPONENT_LOCATION; | 33 locations["component"] = extensions::Feature::COMPONENT_LOCATION; |
| 32 | 34 |
| 33 platforms["chromeos"] = extensions::Feature::CHROMEOS_PLATFORM; | 35 platforms["chromeos"] = extensions::Feature::CHROMEOS_PLATFORM; |
| 36 channels["trunk"] = VersionInfo::CHANNEL_UNKNOWN; | |
|
Aaron Boodman
2012/04/11 23:35:53
.insert("\n")
not at google - send to devlin
2012/04/12 00:05:21
Done.
| |
| 37 channels["canary"] = VersionInfo::CHANNEL_CANARY; | |
| 38 channels["dev"] = VersionInfo::CHANNEL_DEV; | |
| 39 channels["beta"] = VersionInfo::CHANNEL_BETA; | |
| 40 channels["stable"] = VersionInfo::CHANNEL_STABLE; | |
| 34 } | 41 } |
| 35 | 42 |
| 36 std::map<std::string, Extension::Type> extension_types; | 43 std::map<std::string, Extension::Type> extension_types; |
| 37 std::map<std::string, extensions::Feature::Context> contexts; | 44 std::map<std::string, extensions::Feature::Context> contexts; |
| 38 std::map<std::string, extensions::Feature::Location> locations; | 45 std::map<std::string, extensions::Feature::Location> locations; |
| 39 std::map<std::string, extensions::Feature::Platform> platforms; | 46 std::map<std::string, extensions::Feature::Platform> platforms; |
| 47 std::map<std::string, VersionInfo::Channel> channels; | |
| 40 }; | 48 }; |
| 41 | 49 |
| 42 static base::LazyInstance<Mappings> g_mappings = | 50 static base::LazyInstance<Mappings> g_mappings = |
| 43 LAZY_INSTANCE_INITIALIZER; | 51 LAZY_INSTANCE_INITIALIZER; |
| 44 | 52 |
| 45 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? | 53 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? |
| 46 | 54 |
| 47 void ParseSet(const DictionaryValue* value, | 55 void ParseSet(const DictionaryValue* value, |
| 48 const std::string& property, | 56 const std::string& property, |
| 49 std::set<std::string>* set) { | 57 std::set<std::string>* set) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 } | 121 } |
| 114 | 122 |
| 115 } // namespace | 123 } // namespace |
| 116 | 124 |
| 117 namespace extensions { | 125 namespace extensions { |
| 118 | 126 |
| 119 Feature::Feature() | 127 Feature::Feature() |
| 120 : location_(UNSPECIFIED_LOCATION), | 128 : location_(UNSPECIFIED_LOCATION), |
| 121 platform_(UNSPECIFIED_PLATFORM), | 129 platform_(UNSPECIFIED_PLATFORM), |
| 122 min_manifest_version_(0), | 130 min_manifest_version_(0), |
| 123 max_manifest_version_(0) { | 131 max_manifest_version_(0), |
| 132 channel_(VersionInfo::GetChannel()), | |
| 133 supported_channel_(VersionInfo::CHANNEL_STABLE) { | |
| 124 } | 134 } |
| 125 | 135 |
| 126 Feature::Feature(const Feature& other) | 136 Feature::Feature(const Feature& other) |
| 127 : whitelist_(other.whitelist_), | 137 : whitelist_(other.whitelist_), |
| 128 extension_types_(other.extension_types_), | 138 extension_types_(other.extension_types_), |
| 129 contexts_(other.contexts_), | 139 contexts_(other.contexts_), |
| 130 location_(other.location_), | 140 location_(other.location_), |
| 131 platform_(other.platform_), | 141 platform_(other.platform_), |
| 132 min_manifest_version_(other.min_manifest_version_), | 142 min_manifest_version_(other.min_manifest_version_), |
| 133 max_manifest_version_(other.max_manifest_version_) { | 143 max_manifest_version_(other.max_manifest_version_), |
| 144 channel_(other.channel_), | |
| 145 supported_channel_(other.supported_channel_) { | |
| 134 } | 146 } |
| 135 | 147 |
| 136 Feature::~Feature() { | 148 Feature::~Feature() { |
| 137 } | 149 } |
| 138 | 150 |
| 139 bool Feature::Equals(const Feature& other) const { | 151 bool Feature::Equals(const Feature& other) const { |
| 140 return whitelist_ == other.whitelist_ && | 152 return whitelist_ == other.whitelist_ && |
| 141 extension_types_ == other.extension_types_ && | 153 extension_types_ == other.extension_types_ && |
| 142 contexts_ == other.contexts_ && | 154 contexts_ == other.contexts_ && |
| 143 location_ == other.location_ && | 155 location_ == other.location_ && |
| 144 platform_ == other.platform_ && | 156 platform_ == other.platform_ && |
| 145 min_manifest_version_ == other.min_manifest_version_ && | 157 min_manifest_version_ == other.min_manifest_version_ && |
| 146 max_manifest_version_ == other.max_manifest_version_; | 158 max_manifest_version_ == other.max_manifest_version_ && |
| 159 channel_ == other.channel_ && | |
| 160 supported_channel_ == other.supported_channel_; | |
| 147 } | 161 } |
| 148 | 162 |
| 149 // static | 163 // static |
| 150 Feature::Platform Feature::GetCurrentPlatform() { | 164 Feature::Platform Feature::GetCurrentPlatform() { |
| 151 #if defined(OS_CHROMEOS) | 165 #if defined(OS_CHROMEOS) |
| 152 return CHROMEOS_PLATFORM; | 166 return CHROMEOS_PLATFORM; |
| 153 #else | 167 #else |
| 154 return UNSPECIFIED_PLATFORM; | 168 return UNSPECIFIED_PLATFORM; |
| 155 #endif | 169 #endif |
| 156 } | 170 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 168 ParseEnumSet<Extension::Type>(value, "extension_types", &extension_types_, | 182 ParseEnumSet<Extension::Type>(value, "extension_types", &extension_types_, |
| 169 g_mappings.Get().extension_types); | 183 g_mappings.Get().extension_types); |
| 170 ParseEnumSet<Context>(value, "contexts", &contexts_, | 184 ParseEnumSet<Context>(value, "contexts", &contexts_, |
| 171 g_mappings.Get().contexts); | 185 g_mappings.Get().contexts); |
| 172 ParseEnum<Location>(value, "location", &location_, | 186 ParseEnum<Location>(value, "location", &location_, |
| 173 g_mappings.Get().locations); | 187 g_mappings.Get().locations); |
| 174 ParseEnum<Platform>(value, "platform", &platform_, | 188 ParseEnum<Platform>(value, "platform", &platform_, |
| 175 g_mappings.Get().platforms); | 189 g_mappings.Get().platforms); |
| 176 value->GetInteger("min_manifest_version", &min_manifest_version_); | 190 value->GetInteger("min_manifest_version", &min_manifest_version_); |
| 177 value->GetInteger("max_manifest_version", &max_manifest_version_); | 191 value->GetInteger("max_manifest_version", &max_manifest_version_); |
| 192 ParseEnum<VersionInfo::Channel>( | |
| 193 value, "supported_channel", &supported_channel_, | |
| 194 g_mappings.Get().channels); | |
| 178 } | 195 } |
| 179 | 196 |
| 180 std::string Feature::GetErrorMessage(Feature::Availability result) { | 197 std::string Feature::GetErrorMessage(Feature::Availability result) { |
| 181 switch (result) { | 198 switch (result) { |
| 182 case IS_AVAILABLE: | 199 case IS_AVAILABLE: |
| 183 return ""; | 200 return ""; |
| 184 case NOT_FOUND_IN_WHITELIST: | 201 case NOT_FOUND_IN_WHITELIST: |
| 185 return "Not allowed for specified extension ID."; | 202 return "Not allowed for specified extension ID."; |
| 186 case INVALID_TYPE: | 203 case INVALID_TYPE: |
| 187 return "Not allowed for specified package type (theme, app, etc.)."; | 204 return "Not allowed for specified package type (theme, app, etc.)."; |
| 188 case INVALID_CONTEXT: | 205 case INVALID_CONTEXT: |
| 189 return "Not allowed for specified context type content script, extension " | 206 return "Not allowed for specified context type content script, extension " |
| 190 "page, web page, etc.)."; | 207 "page, web page, etc.)."; |
| 191 case INVALID_LOCATION: | 208 case INVALID_LOCATION: |
| 192 return "Not allowed for specified install location."; | 209 return "Not allowed for specified install location."; |
| 193 case INVALID_PLATFORM: | 210 case INVALID_PLATFORM: |
| 194 return "Not allowed for specified platform."; | 211 return "Not allowed for specified platform."; |
| 195 case INVALID_MIN_MANIFEST_VERSION: | 212 case INVALID_MIN_MANIFEST_VERSION: |
| 196 return base::StringPrintf("Requires manifest version of at least %d.", | 213 return base::StringPrintf("Requires manifest version of at least %d.", |
| 197 min_manifest_version_); | 214 min_manifest_version_); |
| 198 case INVALID_MAX_MANIFEST_VERSION: | 215 case INVALID_MAX_MANIFEST_VERSION: |
| 199 return base::StringPrintf("Requires manifest version of %d or lower.", | 216 return base::StringPrintf("Requires manifest version of %d or lower.", |
| 200 max_manifest_version_); | 217 max_manifest_version_); |
| 201 default: | 218 case UNSUPPORTED_CHANNEL: |
| 202 CHECK(false); | 219 return base::StringPrintf("Channel %d is unsupported.", |
| 203 return ""; | 220 supported_channel_); |
|
not at google - send to devlin
2012/04/11 23:05:54
Unrelated cleanup, but clang won't compile if ther
Aaron Boodman
2012/04/11 23:35:53
Neat. Thanks for the info.
| |
| 204 } | 221 } |
| 222 | |
| 223 return ""; | |
| 205 } | 224 } |
| 206 | 225 |
| 207 Feature::Availability Feature::IsAvailableToManifest( | 226 Feature::Availability Feature::IsAvailableToManifest( |
| 208 const std::string& extension_id, | 227 const std::string& extension_id, |
| 209 Extension::Type type, | 228 Extension::Type type, |
| 210 Location location, | 229 Location location, |
| 211 int manifest_version, | 230 int manifest_version, |
| 212 Platform platform) const { | 231 Platform platform) const { |
| 213 // Component extensions can access any feature. | 232 // Component extensions can access any feature. |
| 214 if (location == COMPONENT_LOCATION) | 233 if (location == COMPONENT_LOCATION) |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 240 | 259 |
| 241 if (platform_ != UNSPECIFIED_PLATFORM && platform_ != platform) | 260 if (platform_ != UNSPECIFIED_PLATFORM && platform_ != platform) |
| 242 return INVALID_PLATFORM; | 261 return INVALID_PLATFORM; |
| 243 | 262 |
| 244 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) | 263 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) |
| 245 return INVALID_MIN_MANIFEST_VERSION; | 264 return INVALID_MIN_MANIFEST_VERSION; |
| 246 | 265 |
| 247 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) | 266 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) |
| 248 return INVALID_MAX_MANIFEST_VERSION; | 267 return INVALID_MAX_MANIFEST_VERSION; |
| 249 | 268 |
| 269 if (supported_channel_ < channel_) | |
| 270 return UNSUPPORTED_CHANNEL; | |
| 271 | |
| 250 return IS_AVAILABLE; | 272 return IS_AVAILABLE; |
| 251 } | 273 } |
| 252 | 274 |
| 253 Feature::Availability Feature::IsAvailableToContext( | 275 Feature::Availability Feature::IsAvailableToContext( |
| 254 const Extension* extension, | 276 const Extension* extension, |
| 255 Feature::Context context, | 277 Feature::Context context, |
| 256 Feature::Platform platform) const { | 278 Feature::Platform platform) const { |
| 257 Availability result = IsAvailableToManifest( | 279 Availability result = IsAvailableToManifest( |
| 258 extension->id(), | 280 extension->id(), |
| 259 extension->GetType(), | 281 extension->GetType(), |
| 260 ConvertLocation(extension->location()), | 282 ConvertLocation(extension->location()), |
| 261 extension->manifest_version(), | 283 extension->manifest_version(), |
| 262 platform); | 284 platform); |
| 263 if (result != IS_AVAILABLE) | 285 if (result != IS_AVAILABLE) |
| 264 return result; | 286 return result; |
| 265 | 287 |
| 266 if (!contexts_.empty() && | 288 if (!contexts_.empty() && |
| 267 contexts_.find(context) == contexts_.end()) { | 289 contexts_.find(context) == contexts_.end()) { |
| 268 return INVALID_CONTEXT; | 290 return INVALID_CONTEXT; |
| 269 } | 291 } |
| 270 | 292 |
| 271 return IS_AVAILABLE; | 293 return IS_AVAILABLE; |
| 272 } | 294 } |
| 273 | 295 |
| 296 void Feature::SetChannelForTesting(VersionInfo::Channel channel) { | |
| 297 channel_ = channel; | |
| 298 } | |
| 299 | |
| 274 } // namespace | 300 } // namespace |
| OLD | NEW |