Chromium Code Reviews| Index: chrome/browser/extensions/component_loader.cc |
| diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc |
| index 60a73aabf76732057ff7d78d10a91bf2ea570fbd..5d3a9f85057018184d3e6d830a37eac28768c585 100644 |
| --- a/chrome/browser/extensions/component_loader.cc |
| +++ b/chrome/browser/extensions/component_loader.cc |
| @@ -5,6 +5,7 @@ |
| #include "chrome/browser/extensions/component_loader.h" |
| #include "base/command_line.h" |
| +#include "base/file_util.h" |
| #include "base/path_service.h" |
| #include "base/json/json_value_serializer.h" |
| #include "chrome/browser/browser_process.h" |
| @@ -16,6 +17,7 @@ |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/extensions/extension.h" |
| +#include "chrome/common/extensions/extension_file_util.h" |
| #include "chrome/common/pref_names.h" |
| #include "content/public/browser/notification_details.h" |
| #include "content/public/browser/notification_source.h" |
| @@ -99,23 +101,30 @@ const Extension* ComponentLoader::Add( |
| const Extension* ComponentLoader::Add( |
| const DictionaryValue* parsed_manifest, |
| const FilePath& root_directory) { |
| - // Get the absolute path to the extension. |
| - FilePath absolute_path(root_directory); |
| - if (!absolute_path.IsAbsolute()) { |
| - if (PathService::Get(chrome::DIR_RESOURCES, &absolute_path)) { |
| - absolute_path = absolute_path.Append(root_directory); |
| - } else { |
| - NOTREACHED(); |
| - } |
| - } |
| - |
| - ComponentExtensionInfo info(parsed_manifest, absolute_path); |
| + CHECK(!Exists(GenerateId(parsed_manifest))); |
| + ComponentExtensionInfo info(parsed_manifest, root_directory); |
| component_extensions_.push_back(info); |
| if (extension_service_->is_ready()) |
| return Load(info); |
| return NULL; |
| } |
| +const Extension* ComponentLoader::AddOrReplace(const FilePath& path) { |
| + FilePath absolute_path = path; |
| + file_util::AbsolutePath(&absolute_path); |
| + std::string error; |
| + scoped_ptr<DictionaryValue> manifest( |
| + extension_file_util::LoadManifest(absolute_path, &error)); |
| + if (!manifest.get()) { |
| + LOG(ERROR) << "Could not load extension from '" << |
| + absolute_path.value() << "'. " << error; |
| + return NULL; |
| + } |
| + Remove(GenerateId(manifest.get())); |
| + |
| + return Add(manifest.release(), absolute_path); |
| +} |
| + |
| const Extension* ComponentLoader::Load(const ComponentExtensionInfo& info) { |
| int flags = Extension::REQUIRE_KEY; |
| // TODO(abarth): We should REQUIRE_MODERN_MANIFEST_VERSION once we've updated |
| @@ -123,8 +132,19 @@ const Extension* ComponentLoader::Load(const ComponentExtensionInfo& info) { |
| if (Extension::ShouldDoStrictErrorChecking(Extension::COMPONENT)) |
| flags |= Extension::STRICT_ERROR_CHECKS; |
| std::string error; |
| + |
| + // Get the absolute path to the extension. |
| + FilePath absolute_path(info.root_directory); |
| + if (!absolute_path.IsAbsolute()) { |
| + if (PathService::Get(chrome::DIR_RESOURCES, &absolute_path)) { |
| + absolute_path = absolute_path.Append(info.root_directory); |
| + } else { |
| + NOTREACHED(); |
| + } |
| + } |
| + |
| scoped_refptr<const Extension> extension(Extension::Create( |
| - info.root_directory, |
| + absolute_path, |
| Extension::COMPONENT, |
| *info.manifest, |
| flags, |
| @@ -141,21 +161,37 @@ void ComponentLoader::Remove(const FilePath& root_directory) { |
| // Find the ComponentExtensionInfo for the extension. |
| RegisteredComponentExtensions::iterator it = component_extensions_.begin(); |
| for (; it != component_extensions_.end(); ++it) { |
| - if (it->root_directory == root_directory) |
| + if (it->root_directory == root_directory) { |
| + Remove(GenerateId(it->manifest)); |
| break; |
| + } |
| } |
| - // If the extension is not in the list, there's nothing to do. |
| - if (it == component_extensions_.end()) |
| - return; |
| +} |
| - // The list owns the dictionary, so it must be deleted after removal. |
| - scoped_ptr<const DictionaryValue> manifest(it->manifest); |
| +void ComponentLoader::Remove(const std::string& id) { |
| + RegisteredComponentExtensions::iterator it = component_extensions_.begin(); |
| + for (; it != component_extensions_.end(); ++it) { |
|
Aaron Boodman
2011/12/06 19:43:35
It seems like this class spends a lot of time find
SeRya
2011/12/06 22:19:37
It only does it when reloads Enterprise Web Store
Aaron Boodman
2011/12/07 00:09:02
I didn't mean compute time, I meant lines of code.
|
| + if (GenerateId(it->manifest) == id) { |
| + delete it->manifest; |
| + it = component_extensions_.erase(it); |
| + if (extension_service_->is_ready()) |
| + extension_service_-> |
| + UnloadExtension(id, extension_misc::UNLOAD_REASON_DISABLE); |
| + break; |
| + } |
| + } |
| +} |
| - // Remove the extension from the list of registered extensions. |
| - *it = component_extensions_.back(); |
| - component_extensions_.pop_back(); |
| +bool ComponentLoader::Exists(const std::string& id) const { |
| + RegisteredComponentExtensions::const_iterator it = |
| + component_extensions_.begin(); |
| + for (; it != component_extensions_.end(); ++it) |
| + if (GenerateId(it->manifest) == id) |
| + return true; |
| + return false; |
| +} |
| - // Determine the extension id and unload the extension. |
| +std::string ComponentLoader::GenerateId(const DictionaryValue* manifest) { |
| std::string public_key; |
| std::string public_key_bytes; |
| std::string id; |
| @@ -163,11 +199,9 @@ void ComponentLoader::Remove(const FilePath& root_directory) { |
| extension_manifest_keys::kPublicKey, &public_key) || |
| !Extension::ParsePEMKeyBytes(public_key, &public_key_bytes) || |
| !Extension::GenerateId(public_key_bytes, &id)) { |
| - LOG(ERROR) << "Failed to get extension id"; |
| - return; |
| + return std::string(); |
| } |
| - extension_service_-> |
| - UnloadExtension(id, extension_misc::UNLOAD_REASON_DISABLE); |
| + return id; |
| } |
| void ComponentLoader::AddFileManagerExtension() { |