| Index: chrome/common/extensions/manifest.cc
|
| diff --git a/chrome/common/extensions/manifest.cc b/chrome/common/extensions/manifest.cc
|
| index f17f4c6303fe39246bf15f0f417869fd3c668e4d..2ca07a23b9247ba79254507d68ed049dcab12dc6 100644
|
| --- a/chrome/common/extensions/manifest.cc
|
| +++ b/chrome/common/extensions/manifest.cc
|
| @@ -13,32 +13,107 @@
|
| #include "chrome/common/extensions/extension_manifest_constants.h"
|
| #include "chrome/common/extensions/features/base_feature_provider.h"
|
| #include "extensions/common/error_utils.h"
|
| +#include "extensions/common/install_warning.h"
|
|
|
| namespace errors = extension_manifest_errors;
|
| namespace keys = extension_manifest_keys;
|
|
|
| namespace extensions {
|
|
|
| -Manifest::Manifest(Extension::Location location,
|
| - scoped_ptr<DictionaryValue> value)
|
| +namespace {
|
| +
|
| +// Rank extension locations in a way that allows
|
| +// Manifest::GetHigherPriorityLocation() to compare locations.
|
| +// An extension installed from two locations will have the location
|
| +// with the higher rank, as returned by this function. The actual
|
| +// integer values may change, and should never be persisted.
|
| +int GetLocationRank(Manifest::Location location) {
|
| + const int kInvalidRank = -1;
|
| + int rank = kInvalidRank; // Will CHECK that rank is not kInvalidRank.
|
| +
|
| + switch (location) {
|
| + // Component extensions can not be overriden by any other type.
|
| + case Manifest::COMPONENT:
|
| + rank = 6;
|
| + break;
|
| +
|
| + // Policy controlled extensions may not be overridden by any type
|
| + // that is not part of chrome.
|
| + case Manifest::EXTERNAL_POLICY_DOWNLOAD:
|
| + rank = 5;
|
| + break;
|
| +
|
| + // A developer-loaded extension should override any installed type
|
| + // that a user can disable.
|
| + case Manifest::LOAD:
|
| + rank = 4;
|
| + break;
|
| +
|
| + // The relative priority of various external sources is not important,
|
| + // but having some order ensures deterministic behavior.
|
| + case Manifest::EXTERNAL_REGISTRY:
|
| + rank = 3;
|
| + break;
|
| +
|
| + case Manifest::EXTERNAL_PREF:
|
| + rank = 2;
|
| + break;
|
| +
|
| + case Manifest::EXTERNAL_PREF_DOWNLOAD:
|
| + rank = 1;
|
| + break;
|
| +
|
| + // User installed extensions are overridden by any external type.
|
| + case Manifest::INTERNAL:
|
| + rank = 0;
|
| + break;
|
| +
|
| + default:
|
| + NOTREACHED() << "Need to add new extension location " << location;
|
| + }
|
| +
|
| + CHECK(rank != kInvalidRank);
|
| + return rank;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +Manifest::Location Manifest::GetHigherPriorityLocation(
|
| + Location loc1, Location loc2) {
|
| + if (loc1 == loc2)
|
| + return loc1;
|
| +
|
| + int loc1_rank = GetLocationRank(loc1);
|
| + int loc2_rank = GetLocationRank(loc2);
|
| +
|
| + // If two different locations have the same rank, then we can not
|
| + // deterministicly choose a location.
|
| + CHECK(loc1_rank != loc2_rank);
|
| +
|
| + // Highest rank has highest priority.
|
| + return (loc1_rank > loc2_rank ? loc1 : loc2 );
|
| +}
|
| +
|
| +Manifest::Manifest(Location location, scoped_ptr<DictionaryValue> value)
|
| : location_(location),
|
| value_(value.Pass()),
|
| - type_(Extension::TYPE_UNKNOWN) {
|
| + type_(TYPE_UNKNOWN) {
|
| if (value_->HasKey(keys::kTheme)) {
|
| - type_ = Extension::TYPE_THEME;
|
| + type_ = TYPE_THEME;
|
| } else if (value_->HasKey(keys::kApp)) {
|
| if (value_->Get(keys::kWebURLs, NULL) ||
|
| value_->Get(keys::kLaunchWebURL, NULL)) {
|
| - type_ = Extension::TYPE_HOSTED_APP;
|
| + type_ = TYPE_HOSTED_APP;
|
| } else if (value_->Get(keys::kPlatformAppBackground, NULL)) {
|
| - type_ = Extension::TYPE_PLATFORM_APP;
|
| + type_ = TYPE_PLATFORM_APP;
|
| } else {
|
| - type_ = Extension::TYPE_LEGACY_PACKAGED_APP;
|
| + type_ = TYPE_LEGACY_PACKAGED_APP;
|
| }
|
| } else {
|
| - type_ = Extension::TYPE_EXTENSION;
|
| + type_ = TYPE_EXTENSION;
|
| }
|
| - CHECK_NE(type_, Extension::TYPE_UNKNOWN);
|
| + CHECK_NE(type_, TYPE_UNKNOWN);
|
| }
|
|
|
| Manifest::~Manifest() {
|
| @@ -46,9 +121,9 @@ Manifest::~Manifest() {
|
|
|
| void Manifest::ValidateManifest(
|
| std::string* error,
|
| - Extension::InstallWarningVector* warnings) const {
|
| + std::vector<InstallWarning>* warnings) const {
|
| *error = "";
|
| - if (type_ == Extension::TYPE_PLATFORM_APP && GetManifestVersion() < 2) {
|
| + if (type_ == Manifest::TYPE_PLATFORM_APP && GetManifestVersion() < 2) {
|
| *error = errors::kPlatformAppNeedsManifestVersion2;
|
| return;
|
| }
|
| @@ -73,16 +148,16 @@ void Manifest::ValidateManifest(
|
| extension_id_, type_, Feature::ConvertLocation(location_),
|
| GetManifestVersion());
|
| if (!result.is_available())
|
| - warnings->push_back(Extension::InstallWarning(
|
| - Extension::InstallWarning::FORMAT_TEXT, result.message()));
|
| + warnings->push_back(InstallWarning(
|
| + InstallWarning::FORMAT_TEXT, result.message()));
|
| }
|
|
|
| // Also generate warnings for keys that are not features.
|
| for (DictionaryValue::key_iterator key = value_->begin_keys();
|
| key != value_->end_keys(); ++key) {
|
| if (!BaseFeatureProvider::GetManifestFeatures()->GetFeature(*key)) {
|
| - warnings->push_back(Extension::InstallWarning(
|
| - Extension::InstallWarning::FORMAT_TEXT,
|
| + warnings->push_back(InstallWarning(
|
| + InstallWarning::FORMAT_TEXT,
|
| base::StringPrintf("Unrecognized manifest key '%s'.",
|
| (*key).c_str())));
|
| }
|
| @@ -157,7 +232,7 @@ bool Manifest::Equals(const Manifest* other) const {
|
| int Manifest::GetManifestVersion() const {
|
| // Platform apps were launched after manifest version 2 was the preferred
|
| // version, so they default to that.
|
| - int manifest_version = type_ == Extension::TYPE_PLATFORM_APP ? 2 : 1;
|
| + int manifest_version = type_ == TYPE_PLATFORM_APP ? 2 : 1;
|
| value_->GetInteger(keys::kManifestVersion, &manifest_version);
|
| return manifest_version;
|
| }
|
|
|