Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/common/features/simple_feature.h" | 5 #include "extensions/common/features/simple_feature.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/sha1.h" | 15 #include "base/sha1.h" |
| 16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 20 #include "components/crx_file/id_util.h" | 20 #include "components/crx_file/id_util.h" |
| 21 #include "extensions/common/extension_api.h" | 21 #include "extensions/common/extension_api.h" |
| 22 #include "extensions/common/features/feature_channel.h" | |
| 22 #include "extensions/common/features/feature_provider.h" | 23 #include "extensions/common/features/feature_provider.h" |
| 23 #include "extensions/common/features/feature_util.h" | 24 #include "extensions/common/features/feature_util.h" |
| 24 #include "extensions/common/switches.h" | 25 #include "extensions/common/switches.h" |
| 25 | 26 |
| 26 using crx_file::id_util::HashedIdInHex; | 27 using crx_file::id_util::HashedIdInHex; |
| 27 | 28 |
| 28 namespace extensions { | 29 namespace extensions { |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| 31 | 32 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 template<typename T> | 75 template<typename T> |
| 75 void ParseEnum(const std::string& string_value, | 76 void ParseEnum(const std::string& string_value, |
| 76 T* enum_value, | 77 T* enum_value, |
| 77 const std::map<std::string, T>& mapping) { | 78 const std::map<std::string, T>& mapping) { |
| 78 const auto& iter = mapping.find(string_value); | 79 const auto& iter = mapping.find(string_value); |
| 79 if (iter == mapping.end()) | 80 if (iter == mapping.end()) |
| 80 CRASH_WITH_MINIDUMP("Enum value not found: " + string_value); | 81 CRASH_WITH_MINIDUMP("Enum value not found: " + string_value); |
| 81 *enum_value = iter->second; | 82 *enum_value = iter->second; |
| 82 } | 83 } |
| 83 | 84 |
| 84 template<typename T> | 85 template <typename T> |
| 85 void ParseEnum(const base::DictionaryValue* value, | 86 void ParseEnum(const base::Value* value, |
| 86 const std::string& property, | |
| 87 T* enum_value, | 87 T* enum_value, |
| 88 const std::map<std::string, T>& mapping) { | 88 const std::map<std::string, T>& mapping) { |
| 89 std::string string_value; | 89 std::string string_value; |
| 90 if (!value->GetString(property, &string_value)) | 90 if (!value->GetAsString(&string_value)) |
| 91 return; | 91 return; |
| 92 | 92 |
| 93 ParseEnum(string_value, enum_value, mapping); | 93 ParseEnum(string_value, enum_value, mapping); |
| 94 } | 94 } |
| 95 | 95 |
| 96 template<typename T> | 96 template<typename T> |
| 97 void ParseEnumVector(const base::Value* value, | 97 void ParseEnumVector(const base::Value* value, |
| 98 std::vector<T>* enum_vector, | 98 std::vector<T>* enum_vector, |
| 99 const std::map<std::string, T>& mapping) { | 99 const std::map<std::string, T>& mapping) { |
| 100 enum_vector->clear(); | 100 enum_vector->clear(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 183 return "hosted app"; | 183 return "hosted app"; |
| 184 case Feature::WEBUI_CONTEXT: | 184 case Feature::WEBUI_CONTEXT: |
| 185 return "webui"; | 185 return "webui"; |
| 186 case Feature::SERVICE_WORKER_CONTEXT: | 186 case Feature::SERVICE_WORKER_CONTEXT: |
| 187 return "service worker"; | 187 return "service worker"; |
| 188 } | 188 } |
| 189 NOTREACHED(); | 189 NOTREACHED(); |
| 190 return ""; | 190 return ""; |
| 191 } | 191 } |
| 192 | 192 |
| 193 std::string GetDisplayName(version_info::Channel channel) { | |
| 194 switch (channel) { | |
| 195 case version_info::Channel::UNKNOWN: | |
| 196 return "trunk"; | |
| 197 case version_info::Channel::CANARY: | |
| 198 return "canary"; | |
| 199 case version_info::Channel::DEV: | |
| 200 return "dev"; | |
| 201 case version_info::Channel::BETA: | |
| 202 return "beta"; | |
| 203 case version_info::Channel::STABLE: | |
| 204 return "stable"; | |
| 205 } | |
| 206 NOTREACHED(); | |
| 207 return ""; | |
| 208 } | |
| 209 | |
| 193 // Gets a human-readable list of the display names (pluralized, comma separated | 210 // Gets a human-readable list of the display names (pluralized, comma separated |
| 194 // with the "and" in the correct place) for each of |enum_types|. | 211 // with the "and" in the correct place) for each of |enum_types|. |
| 195 template <typename EnumType> | 212 template <typename EnumType> |
| 196 std::string ListDisplayNames(const std::vector<EnumType>& enum_types) { | 213 std::string ListDisplayNames(const std::vector<EnumType>& enum_types) { |
| 197 std::string display_name_list; | 214 std::string display_name_list; |
| 198 for (size_t i = 0; i < enum_types.size(); ++i) { | 215 for (size_t i = 0; i < enum_types.size(); ++i) { |
| 199 // Pluralize type name. | 216 // Pluralize type name. |
| 200 display_name_list += GetDisplayName(enum_types[i]) + "s"; | 217 display_name_list += GetDisplayName(enum_types[i]) + "s"; |
| 201 // Comma-separate entries, with an Oxford comma if there is more than 2 | 218 // Comma-separate entries, with an Oxford comma if there is more than 2 |
| 202 // total entries. | 219 // total entries. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 267 | 284 |
| 268 locations["component"] = SimpleFeature::COMPONENT_LOCATION; | 285 locations["component"] = SimpleFeature::COMPONENT_LOCATION; |
| 269 locations["external_component"] = | 286 locations["external_component"] = |
| 270 SimpleFeature::EXTERNAL_COMPONENT_LOCATION; | 287 SimpleFeature::EXTERNAL_COMPONENT_LOCATION; |
| 271 locations["policy"] = SimpleFeature::POLICY_LOCATION; | 288 locations["policy"] = SimpleFeature::POLICY_LOCATION; |
| 272 | 289 |
| 273 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; | 290 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; |
| 274 platforms["linux"] = Feature::LINUX_PLATFORM; | 291 platforms["linux"] = Feature::LINUX_PLATFORM; |
| 275 platforms["mac"] = Feature::MACOSX_PLATFORM; | 292 platforms["mac"] = Feature::MACOSX_PLATFORM; |
| 276 platforms["win"] = Feature::WIN_PLATFORM; | 293 platforms["win"] = Feature::WIN_PLATFORM; |
| 294 | |
| 295 channels["trunk"] = version_info::Channel::UNKNOWN; | |
| 296 channels["canary"] = version_info::Channel::CANARY; | |
| 297 channels["dev"] = version_info::Channel::DEV; | |
| 298 channels["beta"] = version_info::Channel::BETA; | |
| 299 channels["stable"] = version_info::Channel::STABLE; | |
| 277 } | 300 } |
| 278 | 301 |
| 279 std::map<std::string, Manifest::Type> extension_types; | 302 std::map<std::string, Manifest::Type> extension_types; |
| 303 std::map<std::string, version_info::Channel> channels; | |
|
lazyboy
2016/07/12 00:35:13
nit: any reason this is here and not after |platfo
Devlin
2016/07/12 19:10:00
Nope, moved.
| |
| 280 std::map<std::string, Feature::Context> contexts; | 304 std::map<std::string, Feature::Context> contexts; |
| 281 std::map<std::string, SimpleFeature::Location> locations; | 305 std::map<std::string, SimpleFeature::Location> locations; |
| 282 std::map<std::string, Feature::Platform> platforms; | 306 std::map<std::string, Feature::Platform> platforms; |
| 283 }; | 307 }; |
| 284 | 308 |
| 285 SimpleFeature::SimpleFeature() | 309 SimpleFeature::SimpleFeature() |
| 286 : location_(UNSPECIFIED_LOCATION), | 310 : location_(UNSPECIFIED_LOCATION), |
| 287 min_manifest_version_(0), | 311 min_manifest_version_(0), |
| 288 max_manifest_version_(0), | 312 max_manifest_version_(0), |
| 289 component_extensions_auto_granted_(true) {} | 313 component_extensions_auto_granted_(true) {} |
| 290 | 314 |
| 291 SimpleFeature::~SimpleFeature() {} | 315 SimpleFeature::~SimpleFeature() {} |
| 292 | 316 |
| 293 bool SimpleFeature::HasDependencies() const { | |
| 294 return !dependencies_.empty(); | |
| 295 } | |
| 296 | |
| 297 void SimpleFeature::AddFilter(std::unique_ptr<SimpleFeatureFilter> filter) { | |
|
lazyboy
2016/07/12 00:35:12
As we're not using SimpleFeatureFilter anymore, we
Devlin
2016/07/12 19:10:00
Whoops! Meant to do that, but looks like I only g
| |
| 298 filters_.push_back(std::move(filter)); | |
| 299 } | |
| 300 | |
| 301 std::string SimpleFeature::Parse(const base::DictionaryValue* dictionary) { | 317 std::string SimpleFeature::Parse(const base::DictionaryValue* dictionary) { |
| 302 static base::LazyInstance<SimpleFeature::Mappings> mappings = | 318 static base::LazyInstance<SimpleFeature::Mappings> mappings = |
| 303 LAZY_INSTANCE_INITIALIZER; | 319 LAZY_INSTANCE_INITIALIZER; |
| 304 | 320 |
| 305 no_parent_ = false; | 321 no_parent_ = false; |
| 306 for (base::DictionaryValue::Iterator it(*dictionary); | 322 for (base::DictionaryValue::Iterator it(*dictionary); |
| 307 !it.IsAtEnd(); | 323 !it.IsAtEnd(); |
| 308 it.Advance()) { | 324 it.Advance()) { |
| 309 std::string key = it.key(); | 325 std::string key = it.key(); |
| 310 const base::Value* value = &it.value(); | 326 const base::Value* value = &it.value(); |
| 311 if (key == "matches") { | 327 if (key == "matches") { |
| 312 ParseURLPatterns(dictionary, "matches", &matches_); | 328 ParseURLPatterns(dictionary, "matches", &matches_); |
| 313 } else if (key == "blacklist") { | 329 } else if (key == "blacklist") { |
| 314 ParseVector(value, &blacklist_); | 330 ParseVector(value, &blacklist_); |
| 315 } else if (key == "whitelist") { | 331 } else if (key == "whitelist") { |
| 316 ParseVector(value, &whitelist_); | 332 ParseVector(value, &whitelist_); |
| 317 } else if (key == "dependencies") { | 333 } else if (key == "dependencies") { |
| 318 ParseVector(value, &dependencies_); | 334 ParseVector(value, &dependencies_); |
| 319 } else if (key == "extension_types") { | 335 } else if (key == "extension_types") { |
| 320 ParseEnumVector<Manifest::Type>(value, &extension_types_, | 336 ParseEnumVector<Manifest::Type>(value, &extension_types_, |
| 321 mappings.Get().extension_types); | 337 mappings.Get().extension_types); |
| 322 } else if (key == "contexts") { | 338 } else if (key == "contexts") { |
| 323 ParseEnumVector<Context>(value, &contexts_, | 339 ParseEnumVector<Context>(value, &contexts_, |
| 324 mappings.Get().contexts); | 340 mappings.Get().contexts); |
| 325 } else if (key == "location") { | 341 } else if (key == "location") { |
| 326 ParseEnum<Location>(dictionary, "location", &location_, | 342 ParseEnum<Location>(value, &location_, mappings.Get().locations); |
| 327 mappings.Get().locations); | |
| 328 } else if (key == "platforms") { | 343 } else if (key == "platforms") { |
| 329 ParseEnumVector<Platform>(value, &platforms_, | 344 ParseEnumVector<Platform>(value, &platforms_, |
| 330 mappings.Get().platforms); | 345 mappings.Get().platforms); |
| 331 } else if (key == "min_manifest_version") { | 346 } else if (key == "min_manifest_version") { |
| 332 dictionary->GetInteger("min_manifest_version", &min_manifest_version_); | 347 dictionary->GetInteger("min_manifest_version", &min_manifest_version_); |
| 333 } else if (key == "max_manifest_version") { | 348 } else if (key == "max_manifest_version") { |
| 334 dictionary->GetInteger("max_manifest_version", &max_manifest_version_); | 349 dictionary->GetInteger("max_manifest_version", &max_manifest_version_); |
| 335 } else if (key == "noparent") { | 350 } else if (key == "noparent") { |
| 336 dictionary->GetBoolean("noparent", &no_parent_); | 351 dictionary->GetBoolean("noparent", &no_parent_); |
| 337 } else if (key == "component_extensions_auto_granted") { | 352 } else if (key == "component_extensions_auto_granted") { |
| 338 dictionary->GetBoolean("component_extensions_auto_granted", | 353 dictionary->GetBoolean("component_extensions_auto_granted", |
| 339 &component_extensions_auto_granted_); | 354 &component_extensions_auto_granted_); |
| 340 } else if (key == "command_line_switch") { | 355 } else if (key == "command_line_switch") { |
| 341 dictionary->GetString("command_line_switch", &command_line_switch_); | 356 dictionary->GetString("command_line_switch", &command_line_switch_); |
| 357 } else if (key == "channel") { | |
| 358 channel_.reset(new version_info::Channel(version_info::Channel::UNKNOWN)); | |
| 359 ParseEnum<version_info::Channel>(value, channel_.get(), | |
| 360 mappings.Get().channels); | |
| 342 } | 361 } |
| 343 } | 362 } |
| 344 | 363 |
| 345 // NOTE: ideally we'd sanity check that "matches" can be specified if and | 364 // NOTE: ideally we'd sanity check that "matches" can be specified if and |
| 346 // only if there's a "web_page" or "webui" context, but without | 365 // only if there's a "web_page" or "webui" context, but without |
| 347 // (Simple)Features being aware of their own heirarchy this is impossible. | 366 // (Simple)Features being aware of their own heirarchy this is impossible. |
| 348 // | 367 // |
| 349 // For example, we might have feature "foo" available to "web_page" context | 368 // For example, we might have feature "foo" available to "web_page" context |
| 350 // and "matches" google.com/*. Then a sub-feature "foo.bar" might override | 369 // and "matches" google.com/*. Then a sub-feature "foo.bar" might override |
| 351 // "matches" to be chromium.org/*. That sub-feature doesn't need to specify | 370 // "matches" to be chromium.org/*. That sub-feature doesn't need to specify |
| 352 // "web_page" context because it's inherited, but we don't know that here. | 371 // "web_page" context because it's inherited, but we don't know that here. |
| 353 | 372 |
| 354 std::string result; | 373 // All features must be channel-restricted, either directly or through |
| 355 for (const auto& filter : filters_) { | 374 // dependents. |
| 356 result = filter->Parse(dictionary); | 375 if (!channel_ && dependencies_.empty()) |
| 357 if (!result.empty()) | 376 return name() + ": Must supply a value for channel or dependencies."; |
| 358 break; | |
| 359 } | |
| 360 | 377 |
| 361 return result; | 378 return std::string(); |
| 362 } | 379 } |
| 363 | 380 |
| 364 Feature::Availability SimpleFeature::IsAvailableToManifest( | 381 Feature::Availability SimpleFeature::IsAvailableToManifest( |
| 365 const std::string& extension_id, | 382 const std::string& extension_id, |
| 366 Manifest::Type type, | 383 Manifest::Type type, |
| 367 Manifest::Location location, | 384 Manifest::Location location, |
| 368 int manifest_version, | 385 int manifest_version, |
| 369 Platform platform) const { | 386 Platform platform) const { |
| 370 // Check extension type first to avoid granting platform app permissions | 387 // Check extension type first to avoid granting platform app permissions |
| 371 // to component extensions. | 388 // to component extensions. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); | 420 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); |
| 404 | 421 |
| 405 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) | 422 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) |
| 406 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); | 423 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); |
| 407 | 424 |
| 408 if (!command_line_switch_.empty() && | 425 if (!command_line_switch_.empty() && |
| 409 !IsCommandLineSwitchEnabled(command_line_switch_)) { | 426 !IsCommandLineSwitchEnabled(command_line_switch_)) { |
| 410 return CreateAvailability(MISSING_COMMAND_LINE_SWITCH, type); | 427 return CreateAvailability(MISSING_COMMAND_LINE_SWITCH, type); |
| 411 } | 428 } |
| 412 | 429 |
| 413 for (const auto& filter : filters_) { | 430 if (channel_ && *channel_ < GetCurrentChannel()) { |
|
lazyboy
2016/07/12 00:35:13
nit: drop {}
Devlin
2016/07/12 19:10:00
Done.
| |
| 414 Availability availability = filter->IsAvailableToManifest( | 431 return CreateAvailability(UNSUPPORTED_CHANNEL, *channel_); |
| 415 extension_id, type, location, manifest_version, platform); | |
| 416 if (!availability.is_available()) | |
| 417 return availability; | |
| 418 } | 432 } |
| 419 | 433 |
| 420 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, | 434 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, |
| 421 extension_id, | 435 extension_id, |
| 422 type, | 436 type, |
| 423 location, | 437 location, |
| 424 manifest_version, | 438 manifest_version, |
| 425 platform)); | 439 platform)); |
| 426 } | 440 } |
| 427 | 441 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 448 return CreateAvailability(INVALID_CONTEXT, context); | 462 return CreateAvailability(INVALID_CONTEXT, context); |
| 449 | 463 |
| 450 // TODO(kalman): Consider checking |matches_| regardless of context type. | 464 // TODO(kalman): Consider checking |matches_| regardless of context type. |
| 451 // Fewer surprises, and if the feature configuration wants to isolate | 465 // Fewer surprises, and if the feature configuration wants to isolate |
| 452 // "matches" from say "blessed_extension" then they can use complex features. | 466 // "matches" from say "blessed_extension" then they can use complex features. |
| 453 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && | 467 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && |
| 454 !matches_.MatchesURL(url)) { | 468 !matches_.MatchesURL(url)) { |
| 455 return CreateAvailability(INVALID_URL, url); | 469 return CreateAvailability(INVALID_URL, url); |
| 456 } | 470 } |
| 457 | 471 |
| 458 for (const auto& filter : filters_) { | |
| 459 Availability availability = | |
| 460 filter->IsAvailableToContext(extension, context, url, platform); | |
| 461 if (!availability.is_available()) | |
| 462 return availability; | |
| 463 } | |
| 464 | |
| 465 // TODO(kalman): Assert that if the context was a webpage or WebUI context | 472 // TODO(kalman): Assert that if the context was a webpage or WebUI context |
| 466 // then at some point a "matches" restriction was checked. | 473 // then at some point a "matches" restriction was checked. |
| 467 return CheckDependencies(base::Bind( | 474 return CheckDependencies(base::Bind( |
| 468 &IsAvailableToContextForBind, extension, context, url, platform)); | 475 &IsAvailableToContextForBind, extension, context, url, platform)); |
| 469 } | 476 } |
| 470 | 477 |
| 471 std::string SimpleFeature::GetAvailabilityMessage( | 478 std::string SimpleFeature::GetAvailabilityMessage( |
| 472 AvailabilityResult result, | 479 AvailabilityResult result, |
| 473 Manifest::Type type, | 480 Manifest::Type type, |
| 474 const GURL& url, | 481 const GURL& url, |
| 475 Context context) const { | 482 Context context, |
| 483 version_info::Channel channel) const { | |
| 476 switch (result) { | 484 switch (result) { |
| 477 case IS_AVAILABLE: | 485 case IS_AVAILABLE: |
| 478 return std::string(); | 486 return std::string(); |
| 479 case NOT_FOUND_IN_WHITELIST: | 487 case NOT_FOUND_IN_WHITELIST: |
| 480 case FOUND_IN_BLACKLIST: | 488 case FOUND_IN_BLACKLIST: |
| 481 return base::StringPrintf( | 489 return base::StringPrintf( |
| 482 "'%s' is not allowed for specified extension ID.", | 490 "'%s' is not allowed for specified extension ID.", |
| 483 name().c_str()); | 491 name().c_str()); |
| 484 case INVALID_URL: | 492 case INVALID_URL: |
| 485 return base::StringPrintf("'%s' is not allowed on %s.", | 493 return base::StringPrintf("'%s' is not allowed on %s.", |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 515 return base::StringPrintf( | 523 return base::StringPrintf( |
| 516 "'%s' requires manifest version of %d or lower.", | 524 "'%s' requires manifest version of %d or lower.", |
| 517 name().c_str(), | 525 name().c_str(), |
| 518 max_manifest_version_); | 526 max_manifest_version_); |
| 519 case NOT_PRESENT: | 527 case NOT_PRESENT: |
| 520 return base::StringPrintf( | 528 return base::StringPrintf( |
| 521 "'%s' requires a different Feature that is not present.", | 529 "'%s' requires a different Feature that is not present.", |
| 522 name().c_str()); | 530 name().c_str()); |
| 523 case UNSUPPORTED_CHANNEL: | 531 case UNSUPPORTED_CHANNEL: |
| 524 return base::StringPrintf( | 532 return base::StringPrintf( |
| 525 "'%s' is unsupported in this version of the platform.", | 533 "'%s' requires %s channel or newer, but this is the %s channel.", |
| 526 name().c_str()); | 534 name().c_str(), GetDisplayName(channel).c_str(), |
| 535 GetDisplayName(GetCurrentChannel()).c_str()); | |
| 527 case MISSING_COMMAND_LINE_SWITCH: | 536 case MISSING_COMMAND_LINE_SWITCH: |
| 528 return base::StringPrintf( | 537 return base::StringPrintf( |
| 529 "'%s' requires the '%s' command line switch to be enabled.", | 538 "'%s' requires the '%s' command line switch to be enabled.", |
| 530 name().c_str(), command_line_switch_.c_str()); | 539 name().c_str(), command_line_switch_.c_str()); |
| 531 } | 540 } |
| 532 | 541 |
| 533 NOTREACHED(); | 542 NOTREACHED(); |
| 534 return std::string(); | 543 return std::string(); |
| 535 } | 544 } |
| 536 | 545 |
| 537 Feature::Availability SimpleFeature::CreateAvailability( | 546 Feature::Availability SimpleFeature::CreateAvailability( |
| 538 AvailabilityResult result) const { | 547 AvailabilityResult result) const { |
| 539 return Availability( | 548 return Availability( |
| 540 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | 549 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), |
| 541 UNSPECIFIED_CONTEXT)); | 550 UNSPECIFIED_CONTEXT, |
| 551 version_info::Channel::UNKNOWN)); | |
| 542 } | 552 } |
| 543 | 553 |
| 544 Feature::Availability SimpleFeature::CreateAvailability( | 554 Feature::Availability SimpleFeature::CreateAvailability( |
| 545 AvailabilityResult result, Manifest::Type type) const { | 555 AvailabilityResult result, Manifest::Type type) const { |
| 546 return Availability(result, GetAvailabilityMessage(result, type, GURL(), | 556 return Availability( |
| 547 UNSPECIFIED_CONTEXT)); | 557 result, GetAvailabilityMessage(result, type, GURL(), UNSPECIFIED_CONTEXT, |
| 558 version_info::Channel::UNKNOWN)); | |
| 548 } | 559 } |
| 549 | 560 |
| 550 Feature::Availability SimpleFeature::CreateAvailability( | 561 Feature::Availability SimpleFeature::CreateAvailability( |
| 551 AvailabilityResult result, | 562 AvailabilityResult result, |
| 552 const GURL& url) const { | 563 const GURL& url) const { |
| 553 return Availability( | 564 return Availability( |
| 554 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, url, | 565 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, url, |
| 555 UNSPECIFIED_CONTEXT)); | 566 UNSPECIFIED_CONTEXT, |
| 567 version_info::Channel::UNKNOWN)); | |
| 556 } | 568 } |
| 557 | 569 |
| 558 Feature::Availability SimpleFeature::CreateAvailability( | 570 Feature::Availability SimpleFeature::CreateAvailability( |
| 559 AvailabilityResult result, | 571 AvailabilityResult result, |
| 560 Context context) const { | 572 Context context) const { |
| 561 return Availability( | 573 return Availability( |
| 562 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | 574 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), |
| 563 context)); | 575 context, version_info::Channel::UNKNOWN)); |
| 576 } | |
| 577 | |
| 578 Feature::Availability SimpleFeature::CreateAvailability( | |
| 579 AvailabilityResult result, | |
| 580 version_info::Channel channel) const { | |
| 581 return Availability( | |
| 582 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | |
| 583 UNSPECIFIED_CONTEXT, channel)); | |
| 564 } | 584 } |
| 565 | 585 |
| 566 bool SimpleFeature::IsInternal() const { | 586 bool SimpleFeature::IsInternal() const { |
| 567 return false; | 587 return false; |
| 568 } | 588 } |
| 569 | 589 |
| 570 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { | 590 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { |
| 571 return IsIdInList(extension_id, blacklist_); | 591 return IsIdInList(extension_id, blacklist_); |
| 572 } | 592 } |
| 573 | 593 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 634 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { | 654 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { |
| 635 // Belt-and-suspenders philosophy here. We should be pretty confident by this | 655 // Belt-and-suspenders philosophy here. We should be pretty confident by this |
| 636 // point that we've validated the extension ID format, but in case something | 656 // point that we've validated the extension ID format, but in case something |
| 637 // slips through, we avoid a class of attack where creative ID manipulation | 657 // slips through, we avoid a class of attack where creative ID manipulation |
| 638 // leads to hash collisions. | 658 // leads to hash collisions. |
| 639 // 128 bits / 4 = 32 mpdecimal characters | 659 // 128 bits / 4 = 32 mpdecimal characters |
| 640 return (extension_id.length() == 32); | 660 return (extension_id.length() == 32); |
| 641 } | 661 } |
| 642 | 662 |
| 643 } // namespace extensions | 663 } // namespace extensions |
| OLD | NEW |