Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/extensions/component_loader.h" | |
| 6 | |
| 7 #include "base/command_line.h" | |
| 8 #include "base/path_service.h" | |
| 9 #include "base/json/json_value_serializer.h" | |
| 10 #include "chrome/browser/extensions/extension_service.h" | |
| 11 #include "chrome/common/chrome_paths.h" | |
| 12 #include "chrome/common/chrome_switches.h" | |
| 13 #include "chrome/common/extensions/extension.h" | |
| 14 #include "grit/browser_resources.h" | |
| 15 #include "ui/base/resource/resource_bundle.h" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 typedef std::list<std::pair<FilePath::StringType, int> > | |
| 20 ComponentExtensionList; | |
| 21 | |
| 22 #if defined(FILE_MANAGER_EXTENSION) | |
| 23 void AddFileManagerExtension(ComponentExtensionList* component_extensions) { | |
| 24 #ifndef NDEBUG | |
| 25 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 26 if (command_line->HasSwitch(switches::kFileManagerExtensionPath)) { | |
| 27 FilePath filemgr_extension_path = | |
| 28 command_line->GetSwitchValuePath(switches::kFileManagerExtensionPath); | |
| 29 component_extensions->push_back(std::make_pair( | |
| 30 filemgr_extension_path.value(), | |
| 31 IDR_FILEMANAGER_MANIFEST)); | |
| 32 return; | |
| 33 } | |
| 34 #endif // NDEBUG | |
| 35 component_extensions->push_back(std::make_pair( | |
| 36 FILE_PATH_LITERAL("file_manager"), | |
| 37 IDR_FILEMANAGER_MANIFEST)); | |
| 38 } | |
| 39 #endif // defined(FILE_MANAGER_EXTENSION) | |
| 40 | |
| 41 } // namespace | |
| 42 | |
| 43 namespace extensions { | |
| 44 | |
| 45 bool ComponentLoader::ComponentExtensionInfo::Equals( | |
| 46 const ComponentExtensionInfo& other) const { | |
| 47 return other.manifest == manifest && other.root_directory == root_directory; | |
| 48 } | |
| 49 | |
| 50 ComponentLoader::ComponentLoader(ExtensionService* extension_service) | |
| 51 : extension_service_(extension_service) { | |
| 52 } | |
| 53 | |
| 54 ComponentLoader::~ComponentLoader() { | |
| 55 } | |
| 56 | |
| 57 void ComponentLoader::LoadAll() { | |
| 58 for (RegisteredComponentExtensions::iterator it = | |
| 59 component_extensions_.begin(); | |
| 60 it != component_extensions_.end(); ++it) { | |
| 61 Load(*it); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 const Extension* ComponentLoader::Add( | |
| 66 const std::string& manifest, const FilePath& root_directory) { | |
| 67 ComponentExtensionInfo info(manifest, root_directory); | |
| 68 Register(info); | |
| 69 if (extension_service_->is_ready()) | |
| 70 return Load(info); | |
| 71 return NULL; | |
| 72 } | |
| 73 | |
| 74 const Extension* ComponentLoader::Load(const ComponentExtensionInfo& info) { | |
| 75 JSONStringValueSerializer serializer(info.manifest); | |
| 76 scoped_ptr<Value> manifest(serializer.Deserialize(NULL, NULL)); | |
| 77 if (!manifest.get()) { | |
| 78 LOG(ERROR) << "Failed to parse manifest for extension"; | |
| 79 return NULL; | |
| 80 } | |
| 81 | |
| 82 int flags = Extension::REQUIRE_KEY; | |
| 83 if (Extension::ShouldDoStrictErrorChecking(Extension::COMPONENT)) | |
| 84 flags |= Extension::STRICT_ERROR_CHECKS; | |
| 85 std::string error; | |
| 86 scoped_refptr<const Extension> extension(Extension::Create( | |
| 87 info.root_directory, | |
| 88 Extension::COMPONENT, | |
| 89 *static_cast<DictionaryValue*>(manifest.get()), | |
| 90 flags, | |
| 91 &error)); | |
| 92 if (!extension.get()) { | |
| 93 LOG(ERROR) << error; | |
| 94 return NULL; | |
| 95 } | |
| 96 extension_service_->AddExtension(extension); | |
| 97 return extension; | |
| 98 } | |
| 99 | |
| 100 void ComponentLoader::Remove(const std::string& manifest_str) { | |
| 101 // Unload the extension. | |
| 102 JSONStringValueSerializer serializer(manifest_str); | |
| 103 scoped_ptr<Value> manifest(serializer.Deserialize(NULL, NULL)); | |
| 104 if (!manifest.get()) { | |
| 105 LOG(ERROR) << "Failed to parse manifest for extension"; | |
| 106 return; | |
| 107 } | |
| 108 std::string public_key; | |
| 109 std::string public_key_bytes; | |
| 110 std::string id; | |
| 111 if (!static_cast<DictionaryValue*>(manifest.get())-> | |
| 112 GetString(extension_manifest_keys::kPublicKey, &public_key) || | |
| 113 !Extension::ParsePEMKeyBytes(public_key, &public_key_bytes) || | |
| 114 !Extension::GenerateId(public_key_bytes, &id)) { | |
| 115 LOG(ERROR) << "Failed to get extension id"; | |
| 116 return; | |
| 117 } | |
| 118 extension_service_-> | |
| 119 UnloadExtension(id, extension_misc::UNLOAD_REASON_DISABLE); | |
| 120 | |
| 121 // Unregister the extension. | |
| 122 RegisteredComponentExtensions new_component_extensions; | |
| 123 for (RegisteredComponentExtensions::iterator it = | |
| 124 component_extensions_.begin(); | |
| 125 it != component_extensions_.end(); ++it) { | |
| 126 if (it->manifest != manifest_str) | |
| 127 new_component_extensions.push_back(*it); | |
| 128 } | |
| 129 component_extensions_.swap(new_component_extensions); | |
| 130 } | |
| 131 | |
| 132 // We take ComponentExtensionList: | |
| 133 // path, manifest ID => full manifest, absolute path | |
| 134 void ComponentLoader::AddDefaultComponentExtensions() { | |
|
Aaron Boodman
2011/11/01 22:15:47
Can this just be done implicitly in the constructo
Yoyo Zhou
2011/11/01 22:45:07
IIRC, some tests that create an ExtensionService w
| |
| 135 ComponentExtensionList component_extensions; | |
| 136 | |
| 137 // Bookmark manager. | |
| 138 component_extensions.push_back(std::make_pair( | |
| 139 FILE_PATH_LITERAL("bookmark_manager"), | |
| 140 IDR_BOOKMARKS_MANIFEST)); | |
| 141 | |
| 142 #if defined(FILE_MANAGER_EXTENSION) | |
| 143 AddFileManagerExtension(&component_extensions); | |
| 144 #endif | |
| 145 | |
| 146 #if defined(TOUCH_UI) | |
| 147 component_extensions.push_back(std::make_pair( | |
| 148 FILE_PATH_LITERAL("keyboard"), | |
| 149 IDR_KEYBOARD_MANIFEST)); | |
| 150 #endif | |
| 151 | |
| 152 #if defined(OS_CHROMEOS) | |
| 153 component_extensions.push_back(std::make_pair( | |
| 154 FILE_PATH_LITERAL("/usr/share/chromeos-assets/mobile"), | |
| 155 IDR_MOBILE_MANIFEST)); | |
| 156 | |
| 157 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 158 if (command_line->HasSwitch(switches::kAuthExtensionPath)) { | |
| 159 FilePath auth_extension_path = | |
| 160 command_line->GetSwitchValuePath(switches::kAuthExtensionPath); | |
| 161 component_extensions.push_back(std::make_pair( | |
| 162 auth_extension_path.value(), | |
| 163 IDR_GAIA_TEST_AUTH_MANIFEST)); | |
| 164 } else { | |
| 165 component_extensions.push_back(std::make_pair( | |
| 166 FILE_PATH_LITERAL("/usr/share/chromeos-assets/gaia_auth"), | |
| 167 IDR_GAIA_AUTH_MANIFEST)); | |
| 168 } | |
| 169 | |
| 170 #if defined(OFFICIAL_BUILD) | |
| 171 if (browser_defaults::enable_help_app) { | |
| 172 component_extensions.push_back(std::make_pair( | |
| 173 FILE_PATH_LITERAL("/usr/share/chromeos-assets/helpapp"), | |
| 174 IDR_HELP_MANIFEST)); | |
| 175 } | |
| 176 #endif | |
| 177 #endif | |
| 178 | |
| 179 // Web Store. | |
| 180 component_extensions.push_back(std::make_pair( | |
| 181 FILE_PATH_LITERAL("web_store"), | |
| 182 IDR_WEBSTORE_MANIFEST)); | |
| 183 | |
| 184 #if !defined(OS_CHROMEOS) | |
| 185 // Cloud Print component app. Not required on Chrome OS. | |
| 186 component_extensions.push_back(std::make_pair( | |
| 187 FILE_PATH_LITERAL("cloud_print"), | |
| 188 IDR_CLOUDPRINT_MANIFEST)); | |
| 189 #endif // !defined(OS_CHROMEOS) | |
| 190 | |
| 191 for (ComponentExtensionList::iterator iter = component_extensions.begin(); | |
| 192 iter != component_extensions.end(); ++iter) { | |
| 193 FilePath path(iter->first); | |
| 194 if (!path.IsAbsolute()) { | |
| 195 if (PathService::Get(chrome::DIR_RESOURCES, &path)) { | |
| 196 path = path.Append(iter->first); | |
| 197 } else { | |
| 198 NOTREACHED(); | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 std::string manifest = | |
| 203 ResourceBundle::GetSharedInstance().GetRawDataResource( | |
| 204 iter->second).as_string(); | |
| 205 Add(manifest, path); | |
| 206 } | |
| 207 | |
| 208 #if defined(OS_CHROMEOS) | |
| 209 // Register access extensions only if accessibility is enabled. | |
| 210 if (g_browser_process->local_state()-> | |
| 211 GetBoolean(prefs::kAccessibilityEnabled)) { | |
| 212 FilePath path = FilePath(extension_misc::kAccessExtensionPath) | |
| 213 .AppendASCII(extension_misc::kChromeVoxDirectoryName); | |
| 214 std::string manifest = | |
| 215 ResourceBundle::GetSharedInstance().GetRawDataResource( | |
| 216 IDR_CHROMEVOX_MANIFEST).as_string(); | |
| 217 RegisterComponentExtension(manifest, path); | |
|
Aaron Boodman
2011/11/01 22:15:47
Should be Add() now?
Yoyo Zhou
2011/11/01 22:45:07
Yes.
| |
| 218 } | |
| 219 #endif | |
| 220 } | |
| 221 | |
| 222 } // namespace extensions | |
| OLD | NEW |