| 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 |
| 37 channels["trunk"] = VersionInfo::CHANNEL_UNKNOWN; |
| 38 channels["canary"] = VersionInfo::CHANNEL_CANARY; |
| 39 channels["dev"] = VersionInfo::CHANNEL_DEV; |
| 40 channels["beta"] = VersionInfo::CHANNEL_BETA; |
| 41 channels["stable"] = VersionInfo::CHANNEL_STABLE; |
| 34 } | 42 } |
| 35 | 43 |
| 36 std::map<std::string, Extension::Type> extension_types; | 44 std::map<std::string, Extension::Type> extension_types; |
| 37 std::map<std::string, extensions::Feature::Context> contexts; | 45 std::map<std::string, extensions::Feature::Context> contexts; |
| 38 std::map<std::string, extensions::Feature::Location> locations; | 46 std::map<std::string, extensions::Feature::Location> locations; |
| 39 std::map<std::string, extensions::Feature::Platform> platforms; | 47 std::map<std::string, extensions::Feature::Platform> platforms; |
| 48 std::map<std::string, VersionInfo::Channel> channels; |
| 40 }; | 49 }; |
| 41 | 50 |
| 42 static base::LazyInstance<Mappings> g_mappings = | 51 static base::LazyInstance<Mappings> g_mappings = LAZY_INSTANCE_INITIALIZER; |
| 43 LAZY_INSTANCE_INITIALIZER; | 52 |
| 53 struct Channel { |
| 54 Channel() : channel(chrome::VersionInfo::GetChannel()) {} |
| 55 |
| 56 chrome::VersionInfo::Channel channel; |
| 57 }; |
| 58 |
| 59 static base::LazyInstance<Channel> g_channel = LAZY_INSTANCE_INITIALIZER; |
| 44 | 60 |
| 45 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? | 61 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? |
| 46 | 62 |
| 47 void ParseSet(const DictionaryValue* value, | 63 void ParseSet(const DictionaryValue* value, |
| 48 const std::string& property, | 64 const std::string& property, |
| 49 std::set<std::string>* set) { | 65 std::set<std::string>* set) { |
| 50 ListValue* list_value = NULL; | 66 ListValue* list_value = NULL; |
| 51 if (!value->GetList(property, &list_value)) | 67 if (!value->GetList(property, &list_value)) |
| 52 return; | 68 return; |
| 53 | 69 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 } | 129 } |
| 114 | 130 |
| 115 } // namespace | 131 } // namespace |
| 116 | 132 |
| 117 namespace extensions { | 133 namespace extensions { |
| 118 | 134 |
| 119 Feature::Feature() | 135 Feature::Feature() |
| 120 : location_(UNSPECIFIED_LOCATION), | 136 : location_(UNSPECIFIED_LOCATION), |
| 121 platform_(UNSPECIFIED_PLATFORM), | 137 platform_(UNSPECIFIED_PLATFORM), |
| 122 min_manifest_version_(0), | 138 min_manifest_version_(0), |
| 123 max_manifest_version_(0) { | 139 max_manifest_version_(0), |
| 140 supported_channel_(VersionInfo::CHANNEL_UNKNOWN) { |
| 124 } | 141 } |
| 125 | 142 |
| 126 Feature::Feature(const Feature& other) | 143 Feature::Feature(const Feature& other) |
| 127 : whitelist_(other.whitelist_), | 144 : whitelist_(other.whitelist_), |
| 128 extension_types_(other.extension_types_), | 145 extension_types_(other.extension_types_), |
| 129 contexts_(other.contexts_), | 146 contexts_(other.contexts_), |
| 130 location_(other.location_), | 147 location_(other.location_), |
| 131 platform_(other.platform_), | 148 platform_(other.platform_), |
| 132 min_manifest_version_(other.min_manifest_version_), | 149 min_manifest_version_(other.min_manifest_version_), |
| 133 max_manifest_version_(other.max_manifest_version_) { | 150 max_manifest_version_(other.max_manifest_version_), |
| 151 supported_channel_(other.supported_channel_) { |
| 134 } | 152 } |
| 135 | 153 |
| 136 Feature::~Feature() { | 154 Feature::~Feature() { |
| 137 } | 155 } |
| 138 | 156 |
| 139 bool Feature::Equals(const Feature& other) const { | 157 bool Feature::Equals(const Feature& other) const { |
| 140 return whitelist_ == other.whitelist_ && | 158 return whitelist_ == other.whitelist_ && |
| 141 extension_types_ == other.extension_types_ && | 159 extension_types_ == other.extension_types_ && |
| 142 contexts_ == other.contexts_ && | 160 contexts_ == other.contexts_ && |
| 143 location_ == other.location_ && | 161 location_ == other.location_ && |
| 144 platform_ == other.platform_ && | 162 platform_ == other.platform_ && |
| 145 min_manifest_version_ == other.min_manifest_version_ && | 163 min_manifest_version_ == other.min_manifest_version_ && |
| 146 max_manifest_version_ == other.max_manifest_version_; | 164 max_manifest_version_ == other.max_manifest_version_ && |
| 165 supported_channel_ == other.supported_channel_; |
| 147 } | 166 } |
| 148 | 167 |
| 149 // static | 168 // static |
| 150 Feature::Platform Feature::GetCurrentPlatform() { | 169 Feature::Platform Feature::GetCurrentPlatform() { |
| 151 #if defined(OS_CHROMEOS) | 170 #if defined(OS_CHROMEOS) |
| 152 return CHROMEOS_PLATFORM; | 171 return CHROMEOS_PLATFORM; |
| 153 #else | 172 #else |
| 154 return UNSPECIFIED_PLATFORM; | 173 return UNSPECIFIED_PLATFORM; |
| 155 #endif | 174 #endif |
| 156 } | 175 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 168 ParseEnumSet<Extension::Type>(value, "extension_types", &extension_types_, | 187 ParseEnumSet<Extension::Type>(value, "extension_types", &extension_types_, |
| 169 g_mappings.Get().extension_types); | 188 g_mappings.Get().extension_types); |
| 170 ParseEnumSet<Context>(value, "contexts", &contexts_, | 189 ParseEnumSet<Context>(value, "contexts", &contexts_, |
| 171 g_mappings.Get().contexts); | 190 g_mappings.Get().contexts); |
| 172 ParseEnum<Location>(value, "location", &location_, | 191 ParseEnum<Location>(value, "location", &location_, |
| 173 g_mappings.Get().locations); | 192 g_mappings.Get().locations); |
| 174 ParseEnum<Platform>(value, "platform", &platform_, | 193 ParseEnum<Platform>(value, "platform", &platform_, |
| 175 g_mappings.Get().platforms); | 194 g_mappings.Get().platforms); |
| 176 value->GetInteger("min_manifest_version", &min_manifest_version_); | 195 value->GetInteger("min_manifest_version", &min_manifest_version_); |
| 177 value->GetInteger("max_manifest_version", &max_manifest_version_); | 196 value->GetInteger("max_manifest_version", &max_manifest_version_); |
| 197 ParseEnum<VersionInfo::Channel>( |
| 198 value, "supported_channel", &supported_channel_, |
| 199 g_mappings.Get().channels); |
| 178 } | 200 } |
| 179 | 201 |
| 180 std::string Feature::GetErrorMessage(Feature::Availability result) { | 202 std::string Feature::GetErrorMessage(Feature::Availability result) { |
| 181 switch (result) { | 203 switch (result) { |
| 182 case IS_AVAILABLE: | 204 case IS_AVAILABLE: |
| 183 return ""; | 205 return ""; |
| 184 case NOT_FOUND_IN_WHITELIST: | 206 case NOT_FOUND_IN_WHITELIST: |
| 185 return "Not allowed for specified extension ID."; | 207 return "Not allowed for specified extension ID."; |
| 186 case INVALID_TYPE: | 208 case INVALID_TYPE: |
| 187 return "Not allowed for specified package type (theme, app, etc.)."; | 209 return "Not allowed for specified package type (theme, app, etc.)."; |
| 188 case INVALID_CONTEXT: | 210 case INVALID_CONTEXT: |
| 189 return "Not allowed for specified context type content script, extension " | 211 return "Not allowed for specified context type content script, extension " |
| 190 "page, web page, etc.)."; | 212 "page, web page, etc.)."; |
| 191 case INVALID_LOCATION: | 213 case INVALID_LOCATION: |
| 192 return "Not allowed for specified install location."; | 214 return "Not allowed for specified install location."; |
| 193 case INVALID_PLATFORM: | 215 case INVALID_PLATFORM: |
| 194 return "Not allowed for specified platform."; | 216 return "Not allowed for specified platform."; |
| 195 case INVALID_MIN_MANIFEST_VERSION: | 217 case INVALID_MIN_MANIFEST_VERSION: |
| 196 return base::StringPrintf("Requires manifest version of at least %d.", | 218 return base::StringPrintf("Requires manifest version of at least %d.", |
| 197 min_manifest_version_); | 219 min_manifest_version_); |
| 198 case INVALID_MAX_MANIFEST_VERSION: | 220 case INVALID_MAX_MANIFEST_VERSION: |
| 199 return base::StringPrintf("Requires manifest version of %d or lower.", | 221 return base::StringPrintf("Requires manifest version of %d or lower.", |
| 200 max_manifest_version_); | 222 max_manifest_version_); |
| 201 default: | 223 case NOT_PRESENT: |
| 202 CHECK(false); | 224 return "Requires a different Feature that is not present."; |
| 203 return ""; | 225 case UNSUPPORTED_CHANNEL: |
| 226 return base::StringPrintf("Channel %d is unsupported.", |
| 227 supported_channel_); |
| 204 } | 228 } |
| 229 |
| 230 return ""; |
| 205 } | 231 } |
| 206 | 232 |
| 207 Feature::Availability Feature::IsAvailableToManifest( | 233 Feature::Availability Feature::IsAvailableToManifest( |
| 208 const std::string& extension_id, | 234 const std::string& extension_id, |
| 209 Extension::Type type, | 235 Extension::Type type, |
| 210 Location location, | 236 Location location, |
| 211 int manifest_version, | 237 int manifest_version, |
| 212 Platform platform) const { | 238 Platform platform) const { |
| 213 // Component extensions can access any feature. | 239 // Component extensions can access any feature. |
| 214 if (location == COMPONENT_LOCATION) | 240 if (location == COMPONENT_LOCATION) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 240 | 266 |
| 241 if (platform_ != UNSPECIFIED_PLATFORM && platform_ != platform) | 267 if (platform_ != UNSPECIFIED_PLATFORM && platform_ != platform) |
| 242 return INVALID_PLATFORM; | 268 return INVALID_PLATFORM; |
| 243 | 269 |
| 244 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) | 270 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) |
| 245 return INVALID_MIN_MANIFEST_VERSION; | 271 return INVALID_MIN_MANIFEST_VERSION; |
| 246 | 272 |
| 247 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) | 273 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) |
| 248 return INVALID_MAX_MANIFEST_VERSION; | 274 return INVALID_MAX_MANIFEST_VERSION; |
| 249 | 275 |
| 276 if (supported_channel_ < g_channel.Get().channel) |
| 277 return UNSUPPORTED_CHANNEL; |
| 278 |
| 250 return IS_AVAILABLE; | 279 return IS_AVAILABLE; |
| 251 } | 280 } |
| 252 | 281 |
| 253 Feature::Availability Feature::IsAvailableToContext( | 282 Feature::Availability Feature::IsAvailableToContext( |
| 254 const Extension* extension, | 283 const Extension* extension, |
| 255 Feature::Context context, | 284 Feature::Context context, |
| 256 Feature::Platform platform) const { | 285 Feature::Platform platform) const { |
| 257 Availability result = IsAvailableToManifest( | 286 Availability result = IsAvailableToManifest( |
| 258 extension->id(), | 287 extension->id(), |
| 259 extension->GetType(), | 288 extension->GetType(), |
| 260 ConvertLocation(extension->location()), | 289 ConvertLocation(extension->location()), |
| 261 extension->manifest_version(), | 290 extension->manifest_version(), |
| 262 platform); | 291 platform); |
| 263 if (result != IS_AVAILABLE) | 292 if (result != IS_AVAILABLE) |
| 264 return result; | 293 return result; |
| 265 | 294 |
| 266 if (!contexts_.empty() && | 295 if (!contexts_.empty() && |
| 267 contexts_.find(context) == contexts_.end()) { | 296 contexts_.find(context) == contexts_.end()) { |
| 268 return INVALID_CONTEXT; | 297 return INVALID_CONTEXT; |
| 269 } | 298 } |
| 270 | 299 |
| 271 return IS_AVAILABLE; | 300 return IS_AVAILABLE; |
| 272 } | 301 } |
| 273 | 302 |
| 303 // static |
| 304 void Feature::SetChannelForTesting(VersionInfo::Channel channel) { |
| 305 g_channel.Get().channel = channel; |
| 306 } |
| 307 |
| 274 } // namespace | 308 } // namespace |
| OLD | NEW |