| 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) {
|
| + 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() {
|
|
|