Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: chrome/browser/extensions/component_loader.cc

Issue 11014009: Beginnings of the script bubble. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More minor cleanup Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/extensions/component_loader.h" 5 #include "chrome/browser/extensions/component_loader.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/json/json_string_value_serializer.h" 9 #include "base/json/json_string_value_serializer.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
11 #include "chrome/browser/api/prefs/pref_change_registrar.h" 11 #include "chrome/browser/api/prefs/pref_change_registrar.h"
12 #include "chrome/browser/browser_process.h" 12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/extensions/extension_service.h" 13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/prefs/pref_notifier.h" 14 #include "chrome/browser/prefs/pref_notifier.h"
15 #include "chrome/browser/prefs/pref_service.h" 15 #include "chrome/browser/prefs/pref_service.h"
16 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/chrome_notification_types.h" 17 #include "chrome/common/chrome_notification_types.h"
18 #include "chrome/common/chrome_paths.h" 18 #include "chrome/common/chrome_paths.h"
19 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/extensions/extension.h" 20 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/extensions/extension_file_util.h" 21 #include "chrome/common/extensions/extension_file_util.h"
22 #include "chrome/common/extensions/extension_manifest_constants.h" 22 #include "chrome/common/extensions/extension_manifest_constants.h"
23 #include "chrome/common/extensions/feature_switch.h"
23 #include "chrome/common/pref_names.h" 24 #include "chrome/common/pref_names.h"
24 #include "content/public/browser/notification_details.h" 25 #include "content/public/browser/notification_details.h"
25 #include "content/public/browser/notification_source.h" 26 #include "content/public/browser/notification_source.h"
26 #include "grit/browser_resources.h" 27 #include "grit/browser_resources.h"
27 #include "ui/base/layout.h" 28 #include "ui/base/layout.h"
28 #include "ui/base/resource/resource_bundle.h" 29 #include "ui/base/resource/resource_bundle.h"
29 30
30 #if defined(OFFICIAL_BUILD) 31 #if defined(OFFICIAL_BUILD)
31 #include "chrome/browser/defaults.h" 32 #include "chrome/browser/defaults.h"
32 #endif 33 #endif
33 34
34 #if defined(OS_CHROMEOS) 35 #if defined(OS_CHROMEOS)
35 #include "chrome/browser/chromeos/login/user_manager.h" 36 #include "chrome/browser/chromeos/login/user_manager.h"
36 #endif 37 #endif
37 38
38 #if defined(USE_ASH) 39 #if defined(USE_ASH)
39 #include "grit/chromium_strings.h" 40 #include "grit/chromium_strings.h"
40 #include "ui/base/l10n/l10n_util.h" 41 #include "ui/base/l10n/l10n_util.h"
41 #endif 42 #endif
42 43
43 namespace extensions { 44 namespace extensions {
44 45
46 namespace {
47
48 std::string GenerateId(const DictionaryValue* manifest, const FilePath& path) {
49 if (manifest->HasKey(extension_manifest_keys::kPublicKey)) {
50 std::string public_key;
51 std::string public_key_bytes;
52 std::string id;
53 CHECK(manifest->GetString(extension_manifest_keys::kPublicKey,
54 &public_key));
55 CHECK(Extension::ParsePEMKeyBytes(public_key, &public_key_bytes));
56 CHECK(Extension::GenerateId(public_key_bytes, &id));
57 return id;
58 }
59 return Extension::GenerateIdForPath(path);
Yoyo Zhou 2012/10/02 01:21:01 Is this a good idea? The path to a component exten
Aaron Boodman 2012/10/02 01:42:22 Good point, I reverted this bit.
60 }
61
62 } // namespace
63
64 ComponentLoader::ComponentExtensionInfo::ComponentExtensionInfo(
65 const DictionaryValue* manifest, const FilePath& directory)
66 : manifest(manifest),
67 root_directory(directory) {
68 if (!root_directory.IsAbsolute()) {
69 CHECK(PathService::Get(chrome::DIR_RESOURCES, &root_directory));
70 root_directory = root_directory.Append(directory);
71 }
72 id = GenerateId(manifest, root_directory);
73 }
74
45 ComponentLoader::ComponentLoader(ExtensionServiceInterface* extension_service, 75 ComponentLoader::ComponentLoader(ExtensionServiceInterface* extension_service,
46 PrefService* prefs, 76 PrefService* prefs,
47 PrefService* local_state) 77 PrefService* local_state)
48 : prefs_(prefs), 78 : prefs_(prefs),
49 local_state_(local_state), 79 local_state_(local_state),
50 extension_service_(extension_service) { 80 extension_service_(extension_service) {
51 pref_change_registrar_.Init(prefs); 81 pref_change_registrar_.Init(prefs);
52 82
53 // This pref is set by policy. We have to watch it for change because on 83 // This pref is set by policy. We have to watch it for change because on
54 // ChromeOS, policy isn't loaded until after the browser process is started. 84 // ChromeOS, policy isn't loaded until after the browser process is started.
55 pref_change_registrar_.Add(prefs::kEnterpriseWebStoreURL, this); 85 pref_change_registrar_.Add(prefs::kEnterpriseWebStoreURL, this);
56 } 86 }
57 87
58 ComponentLoader::~ComponentLoader() { 88 ComponentLoader::~ComponentLoader() {
59 ClearAllRegistered(); 89 ClearAllRegistered();
60 } 90 }
61 91
92 const Extension* ComponentLoader::GetScriptBubble() const {
93 if (script_bubble_id_.empty())
94 return NULL;
95
96 return extension_service_->extensions()->GetByID(script_bubble_id_);
97 }
98
62 void ComponentLoader::LoadAll() { 99 void ComponentLoader::LoadAll() {
63 for (RegisteredComponentExtensions::iterator it = 100 for (RegisteredComponentExtensions::iterator it =
64 component_extensions_.begin(); 101 component_extensions_.begin();
65 it != component_extensions_.end(); ++it) { 102 it != component_extensions_.end(); ++it) {
66 Load(*it); 103 Load(*it);
67 } 104 }
68 } 105 }
69 106
70 DictionaryValue* ComponentLoader::ParseManifest( 107 DictionaryValue* ComponentLoader::ParseManifest(
71 const std::string& manifest_contents) const { 108 const std::string& manifest_contents) const {
(...skipping 11 matching lines...) Expand all
83 void ComponentLoader::ClearAllRegistered() { 120 void ComponentLoader::ClearAllRegistered() {
84 for (RegisteredComponentExtensions::iterator it = 121 for (RegisteredComponentExtensions::iterator it =
85 component_extensions_.begin(); 122 component_extensions_.begin();
86 it != component_extensions_.end(); ++it) { 123 it != component_extensions_.end(); ++it) {
87 delete it->manifest; 124 delete it->manifest;
88 } 125 }
89 126
90 component_extensions_.clear(); 127 component_extensions_.clear();
91 } 128 }
92 129
93 const Extension* ComponentLoader::Add( 130 std::string ComponentLoader::Add(int manifest_resource_id,
94 int manifest_resource_id, 131 const FilePath& root_directory) {
95 const FilePath& root_directory) {
96 std::string manifest_contents = 132 std::string manifest_contents =
97 ResourceBundle::GetSharedInstance().GetRawDataResource( 133 ResourceBundle::GetSharedInstance().GetRawDataResource(
98 manifest_resource_id, 134 manifest_resource_id,
99 ui::SCALE_FACTOR_NONE).as_string(); 135 ui::SCALE_FACTOR_NONE).as_string();
100 return Add(manifest_contents, root_directory); 136 return Add(manifest_contents, root_directory);
101 } 137 }
102 138
103 const Extension* ComponentLoader::Add( 139 std::string ComponentLoader::Add(const std::string& manifest_contents,
104 const std::string& manifest_contents, 140 const FilePath& root_directory) {
105 const FilePath& root_directory) {
106 // The Value is kept for the lifetime of the ComponentLoader. This is 141 // The Value is kept for the lifetime of the ComponentLoader. This is
107 // required in case LoadAll() is called again. 142 // required in case LoadAll() is called again.
108 DictionaryValue* manifest = ParseManifest(manifest_contents); 143 DictionaryValue* manifest = ParseManifest(manifest_contents);
109 if (manifest) 144 if (manifest)
110 return Add(manifest, root_directory); 145 return Add(manifest, root_directory);
111 return NULL; 146 return "";
112 } 147 }
113 148
114 const Extension* ComponentLoader::Add( 149 std::string ComponentLoader::Add(const DictionaryValue* parsed_manifest,
115 const DictionaryValue* parsed_manifest, 150 const FilePath& root_directory) {
116 const FilePath& root_directory) {
117 CHECK(!Exists(GenerateId(parsed_manifest)));
118 ComponentExtensionInfo info(parsed_manifest, root_directory); 151 ComponentExtensionInfo info(parsed_manifest, root_directory);
119 component_extensions_.push_back(info); 152 component_extensions_.push_back(info);
120 if (extension_service_->is_ready()) 153 if (extension_service_->is_ready()) {
Jeffrey Yasskin 2012/10/02 00:26:31 Comment why you need to handle the !is_ready() cas
Aaron Boodman 2012/10/02 01:28:52 Don't need to. Just simplified instead.
121 return Load(info); 154 const Extension* extension = Load(info);
122 return NULL; 155 if (extension)
156 return extension->id();
157 return "";
158 }
159 return info.id;
123 } 160 }
124 161
125 const Extension* ComponentLoader::AddOrReplace(const FilePath& path) { 162 std::string ComponentLoader::AddOrReplace(const FilePath& path) {
126 FilePath absolute_path = path; 163 FilePath absolute_path = path;
127 file_util::AbsolutePath(&absolute_path); 164 file_util::AbsolutePath(&absolute_path);
128 std::string error; 165 std::string error;
129 scoped_ptr<DictionaryValue> manifest( 166 scoped_ptr<DictionaryValue> manifest(
130 extension_file_util::LoadManifest(absolute_path, &error)); 167 extension_file_util::LoadManifest(absolute_path, &error));
131 if (!manifest.get()) { 168 if (!manifest.get()) {
132 LOG(ERROR) << "Could not load extension from '" << 169 LOG(ERROR) << "Could not load extension from '" <<
133 absolute_path.value() << "'. " << error; 170 absolute_path.value() << "'. " << error;
134 return NULL; 171 return NULL;
135 } 172 }
136 Remove(GenerateId(manifest.get())); 173 Remove(GenerateId(manifest.get(), absolute_path));
137 174
138 return Add(manifest.release(), absolute_path); 175 return Add(manifest.release(), absolute_path);
139 } 176 }
140 177
141 void ComponentLoader::Reload(const std::string& extension_id) { 178 void ComponentLoader::Reload(const std::string& extension_id) {
142 for (RegisteredComponentExtensions::iterator it = 179 for (RegisteredComponentExtensions::iterator it =
143 component_extensions_.begin(); it != component_extensions_.end(); 180 component_extensions_.begin(); it != component_extensions_.end();
144 ++it) { 181 ++it) {
145 if (GenerateId(it->manifest) == extension_id) { 182 if (it->id == extension_id) {
146 Load(*it); 183 Load(*it);
147 break; 184 break;
148 } 185 }
149 } 186 }
150 } 187 }
151 188
152 const Extension* ComponentLoader::Load(const ComponentExtensionInfo& info) { 189 const Extension* ComponentLoader::Load(const ComponentExtensionInfo& info) {
153 // TODO(abarth): We should REQUIRE_MODERN_MANIFEST_VERSION once we've updated 190 // TODO(abarth): We should REQUIRE_MODERN_MANIFEST_VERSION once we've updated
154 // our component extensions to the new manifest version. 191 // our component extensions to the new manifest version.
155 int flags = Extension::REQUIRE_KEY; 192 int flags = Extension::NO_FLAGS;
156 193
157 std::string error; 194 std::string error;
158 195
159 // Get the absolute path to the extension.
160 FilePath absolute_path(info.root_directory);
161 if (!absolute_path.IsAbsolute()) {
162 if (PathService::Get(chrome::DIR_RESOURCES, &absolute_path)) {
163 absolute_path = absolute_path.Append(info.root_directory);
164 } else {
165 NOTREACHED();
166 }
167 }
168
169 scoped_refptr<const Extension> extension(Extension::Create( 196 scoped_refptr<const Extension> extension(Extension::Create(
170 absolute_path, 197 info.root_directory,
171 Extension::COMPONENT, 198 Extension::COMPONENT,
172 *info.manifest, 199 *info.manifest,
173 flags, 200 flags,
174 &error)); 201 &error));
175 if (!extension.get()) { 202 if (!extension.get()) {
176 LOG(ERROR) << error; 203 LOG(ERROR) << error;
177 return NULL; 204 return NULL;
178 } 205 }
206 CHECK_EQ(info.id, extension->id()) << extension->name();
179 extension_service_->AddExtension(extension); 207 extension_service_->AddExtension(extension);
180 return extension; 208 return extension;
181 } 209 }
182 210
183 void ComponentLoader::Remove(const FilePath& root_directory) { 211 void ComponentLoader::Remove(const FilePath& root_directory) {
184 // Find the ComponentExtensionInfo for the extension. 212 // Find the ComponentExtensionInfo for the extension.
185 RegisteredComponentExtensions::iterator it = component_extensions_.begin(); 213 RegisteredComponentExtensions::iterator it = component_extensions_.begin();
186 for (; it != component_extensions_.end(); ++it) { 214 for (; it != component_extensions_.end(); ++it) {
187 if (it->root_directory == root_directory) { 215 if (it->root_directory == root_directory) {
188 Remove(GenerateId(it->manifest)); 216 Remove(GenerateId(it->manifest, root_directory));
189 break; 217 break;
190 } 218 }
191 } 219 }
192 } 220 }
193 221
194 void ComponentLoader::Remove(const std::string& id) { 222 void ComponentLoader::Remove(const std::string& id) {
195 RegisteredComponentExtensions::iterator it = component_extensions_.begin(); 223 RegisteredComponentExtensions::iterator it = component_extensions_.begin();
196 for (; it != component_extensions_.end(); ++it) { 224 for (; it != component_extensions_.end(); ++it) {
197 if (GenerateId(it->manifest) == id) { 225 if (it->id == id) {
198 delete it->manifest; 226 delete it->manifest;
199 it = component_extensions_.erase(it); 227 it = component_extensions_.erase(it);
200 if (extension_service_->is_ready()) 228 if (extension_service_->is_ready())
201 extension_service_-> 229 extension_service_->
202 UnloadExtension(id, extension_misc::UNLOAD_REASON_DISABLE); 230 UnloadExtension(id, extension_misc::UNLOAD_REASON_DISABLE);
203 break; 231 break;
204 } 232 }
205 } 233 }
206 } 234 }
207 235
208 bool ComponentLoader::Exists(const std::string& id) const { 236 bool ComponentLoader::Exists(const std::string& id) const {
209 RegisteredComponentExtensions::const_iterator it = 237 RegisteredComponentExtensions::const_iterator it =
210 component_extensions_.begin(); 238 component_extensions_.begin();
211 for (; it != component_extensions_.end(); ++it) 239 for (; it != component_extensions_.end(); ++it)
212 if (GenerateId(it->manifest) == id) 240 if (it->id == id)
213 return true; 241 return true;
214 return false; 242 return false;
215 } 243 }
216 244
217 std::string ComponentLoader::GenerateId(const DictionaryValue* manifest) {
218 std::string public_key;
219 std::string public_key_bytes;
220 std::string id;
221 if (!manifest->GetString(
222 extension_manifest_keys::kPublicKey, &public_key) ||
223 !Extension::ParsePEMKeyBytes(public_key, &public_key_bytes) ||
224 !Extension::GenerateId(public_key_bytes, &id)) {
225 return std::string();
226 }
227 return id;
228 }
229
230 void ComponentLoader::AddFileManagerExtension() { 245 void ComponentLoader::AddFileManagerExtension() {
231 #if defined(FILE_MANAGER_EXTENSION) 246 #if defined(FILE_MANAGER_EXTENSION)
232 #ifndef NDEBUG 247 #ifndef NDEBUG
233 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 248 const CommandLine* command_line = CommandLine::ForCurrentProcess();
234 if (command_line->HasSwitch(switches::kFileManagerExtensionPath)) { 249 if (command_line->HasSwitch(switches::kFileManagerExtensionPath)) {
235 FilePath filemgr_extension_path( 250 FilePath filemgr_extension_path(
236 command_line->GetSwitchValuePath(switches::kFileManagerExtensionPath)); 251 command_line->GetSwitchValuePath(switches::kFileManagerExtensionPath));
237 Add(IDR_FILEMANAGER_MANIFEST, filemgr_extension_path); 252 Add(IDR_FILEMANAGER_MANIFEST, filemgr_extension_path);
238 return; 253 return;
239 } 254 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 310
296 // Update manifest to use a proper name. 311 // Update manifest to use a proper name.
297 manifest->SetString(extension_manifest_keys::kName, 312 manifest->SetString(extension_manifest_keys::kName,
298 l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME)); 313 l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME));
299 314
300 if (manifest) 315 if (manifest)
301 Add(manifest, FilePath(FILE_PATH_LITERAL("chrome_app"))); 316 Add(manifest, FilePath(FILE_PATH_LITERAL("chrome_app")));
302 #endif 317 #endif
303 } 318 }
304 319
320 void ComponentLoader::AddScriptBubble() {
321 if (FeatureSwitch::GetScriptBubble()->IsEnabled()) {
322 script_bubble_id_ =
323 Add(IDR_SCRIPT_BUBBLE_MANIFEST,
324 FilePath(FILE_PATH_LITERAL("script_bubble")));
325 }
326 }
327
305 void ComponentLoader::AddDefaultComponentExtensions() { 328 void ComponentLoader::AddDefaultComponentExtensions() {
306 #if defined(OS_CHROMEOS) 329 #if defined(OS_CHROMEOS)
307 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession)) 330 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession))
308 Add(IDR_BOOKMARKS_MANIFEST, 331 Add(IDR_BOOKMARKS_MANIFEST,
309 FilePath(FILE_PATH_LITERAL("bookmark_manager"))); 332 FilePath(FILE_PATH_LITERAL("bookmark_manager")));
310 #else 333 #else
311 Add(IDR_BOOKMARKS_MANIFEST, FilePath(FILE_PATH_LITERAL("bookmark_manager"))); 334 Add(IDR_BOOKMARKS_MANIFEST, FilePath(FILE_PATH_LITERAL("bookmark_manager")));
312 #endif 335 #endif
313 336
314 #if defined(OS_CHROMEOS) 337 #if defined(OS_CHROMEOS)
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 396
374 // If a URL for the enterprise webstore has been specified, load the 397 // If a URL for the enterprise webstore has been specified, load the
375 // component extension. This extension might also be loaded later, because 398 // component extension. This extension might also be loaded later, because
376 // it is specified by policy, and on ChromeOS policies are loaded after 399 // it is specified by policy, and on ChromeOS policies are loaded after
377 // the browser process has started. 400 // the browser process has started.
378 AddOrReloadEnterpriseWebStore(); 401 AddOrReloadEnterpriseWebStore();
379 402
380 #if defined(USE_ASH) 403 #if defined(USE_ASH)
381 AddChromeApp(); 404 AddChromeApp();
382 #endif 405 #endif
406
407 AddScriptBubble();
383 } 408 }
384 409
385 void ComponentLoader::Observe( 410 void ComponentLoader::Observe(
386 int type, 411 int type,
387 const content::NotificationSource& source, 412 const content::NotificationSource& source,
388 const content::NotificationDetails& details) { 413 const content::NotificationDetails& details) {
389 if (type == chrome::NOTIFICATION_PREF_CHANGED) { 414 if (type == chrome::NOTIFICATION_PREF_CHANGED) {
390 const std::string* name = 415 const std::string* name =
391 content::Details<const std::string>(details).ptr(); 416 content::Details<const std::string>(details).ptr();
392 if (*name == prefs::kEnterpriseWebStoreURL) 417 if (*name == prefs::kEnterpriseWebStoreURL)
393 AddOrReloadEnterpriseWebStore(); 418 AddOrReloadEnterpriseWebStore();
394 else 419 else
395 NOTREACHED(); 420 NOTREACHED();
396 } else { 421 } else {
397 NOTREACHED(); 422 NOTREACHED();
398 } 423 }
399 } 424 }
400 425
401 // static 426 // static
402 void ComponentLoader::RegisterUserPrefs(PrefService* prefs) { 427 void ComponentLoader::RegisterUserPrefs(PrefService* prefs) {
403 prefs->RegisterStringPref(prefs::kEnterpriseWebStoreURL, 428 prefs->RegisterStringPref(prefs::kEnterpriseWebStoreURL,
404 std::string() /* default_value */, 429 std::string() /* default_value */,
405 PrefService::UNSYNCABLE_PREF); 430 PrefService::UNSYNCABLE_PREF);
406 prefs->RegisterStringPref(prefs::kEnterpriseWebStoreName, 431 prefs->RegisterStringPref(prefs::kEnterpriseWebStoreName,
407 std::string() /* default_value */, 432 std::string() /* default_value */,
408 PrefService::UNSYNCABLE_PREF); 433 PrefService::UNSYNCABLE_PREF);
409 } 434 }
410 435
411 } // namespace extensions 436 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698