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

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: ready to land 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 std::string raw_key;
50 std::string id_input;
51 std::string id;
52 CHECK(manifest->GetString(extension_manifest_keys::kPublicKey, &raw_key));
53 CHECK(Extension::ParsePEMKeyBytes(raw_key, &id_input));
54 CHECK(Extension::GenerateId(id_input, &id));
55 return id;
56 }
57
58 } // namespace
59
60 ComponentLoader::ComponentExtensionInfo::ComponentExtensionInfo(
61 const DictionaryValue* manifest, const FilePath& directory)
62 : manifest(manifest),
63 root_directory(directory) {
64 if (!root_directory.IsAbsolute()) {
65 CHECK(PathService::Get(chrome::DIR_RESOURCES, &root_directory));
66 root_directory = root_directory.Append(directory);
67 }
68 extension_id = GenerateId(manifest, root_directory);
69 }
70
45 ComponentLoader::ComponentLoader(ExtensionServiceInterface* extension_service, 71 ComponentLoader::ComponentLoader(ExtensionServiceInterface* extension_service,
46 PrefService* prefs, 72 PrefService* prefs,
47 PrefService* local_state) 73 PrefService* local_state)
48 : prefs_(prefs), 74 : prefs_(prefs),
49 local_state_(local_state), 75 local_state_(local_state),
50 extension_service_(extension_service) { 76 extension_service_(extension_service) {
51 pref_change_registrar_.Init(prefs); 77 pref_change_registrar_.Init(prefs);
52 78
53 // This pref is set by policy. We have to watch it for change because on 79 // 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. 80 // ChromeOS, policy isn't loaded until after the browser process is started.
55 pref_change_registrar_.Add(prefs::kEnterpriseWebStoreURL, this); 81 pref_change_registrar_.Add(prefs::kEnterpriseWebStoreURL, this);
56 } 82 }
57 83
58 ComponentLoader::~ComponentLoader() { 84 ComponentLoader::~ComponentLoader() {
59 ClearAllRegistered(); 85 ClearAllRegistered();
60 } 86 }
61 87
88 const Extension* ComponentLoader::GetScriptBubble() const {
89 if (script_bubble_id_.empty())
90 return NULL;
91
92 return extension_service_->extensions()->GetByID(script_bubble_id_);
93 }
94
62 void ComponentLoader::LoadAll() { 95 void ComponentLoader::LoadAll() {
63 for (RegisteredComponentExtensions::iterator it = 96 for (RegisteredComponentExtensions::iterator it =
64 component_extensions_.begin(); 97 component_extensions_.begin();
65 it != component_extensions_.end(); ++it) { 98 it != component_extensions_.end(); ++it) {
66 Load(*it); 99 Load(*it);
67 } 100 }
68 } 101 }
69 102
70 DictionaryValue* ComponentLoader::ParseManifest( 103 DictionaryValue* ComponentLoader::ParseManifest(
71 const std::string& manifest_contents) const { 104 const std::string& manifest_contents) const {
(...skipping 11 matching lines...) Expand all
83 void ComponentLoader::ClearAllRegistered() { 116 void ComponentLoader::ClearAllRegistered() {
84 for (RegisteredComponentExtensions::iterator it = 117 for (RegisteredComponentExtensions::iterator it =
85 component_extensions_.begin(); 118 component_extensions_.begin();
86 it != component_extensions_.end(); ++it) { 119 it != component_extensions_.end(); ++it) {
87 delete it->manifest; 120 delete it->manifest;
88 } 121 }
89 122
90 component_extensions_.clear(); 123 component_extensions_.clear();
91 } 124 }
92 125
93 const Extension* ComponentLoader::Add( 126 std::string ComponentLoader::Add(int manifest_resource_id,
94 int manifest_resource_id, 127 const FilePath& root_directory) {
95 const FilePath& root_directory) {
96 std::string manifest_contents = 128 std::string manifest_contents =
97 ResourceBundle::GetSharedInstance().GetRawDataResource( 129 ResourceBundle::GetSharedInstance().GetRawDataResource(
98 manifest_resource_id, 130 manifest_resource_id,
99 ui::SCALE_FACTOR_NONE).as_string(); 131 ui::SCALE_FACTOR_NONE).as_string();
100 return Add(manifest_contents, root_directory); 132 return Add(manifest_contents, root_directory);
101 } 133 }
102 134
103 const Extension* ComponentLoader::Add( 135 std::string ComponentLoader::Add(const std::string& manifest_contents,
104 const std::string& manifest_contents, 136 const FilePath& root_directory) {
105 const FilePath& root_directory) {
106 // The Value is kept for the lifetime of the ComponentLoader. This is 137 // The Value is kept for the lifetime of the ComponentLoader. This is
107 // required in case LoadAll() is called again. 138 // required in case LoadAll() is called again.
108 DictionaryValue* manifest = ParseManifest(manifest_contents); 139 DictionaryValue* manifest = ParseManifest(manifest_contents);
109 if (manifest) 140 if (manifest)
110 return Add(manifest, root_directory); 141 return Add(manifest, root_directory);
111 return NULL; 142 return "";
112 } 143 }
113 144
114 const Extension* ComponentLoader::Add( 145 std::string ComponentLoader::Add(const DictionaryValue* parsed_manifest,
115 const DictionaryValue* parsed_manifest, 146 const FilePath& root_directory) {
116 const FilePath& root_directory) {
117 CHECK(!Exists(GenerateId(parsed_manifest)));
118 ComponentExtensionInfo info(parsed_manifest, root_directory); 147 ComponentExtensionInfo info(parsed_manifest, root_directory);
119 component_extensions_.push_back(info); 148 component_extensions_.push_back(info);
120 if (extension_service_->is_ready()) 149 if (extension_service_->is_ready())
121 return Load(info); 150 Load(info);
122 return NULL; 151 return info.extension_id;
123 } 152 }
124 153
125 const Extension* ComponentLoader::AddOrReplace(const FilePath& path) { 154 std::string ComponentLoader::AddOrReplace(const FilePath& path) {
126 FilePath absolute_path = path; 155 FilePath absolute_path = path;
127 file_util::AbsolutePath(&absolute_path); 156 file_util::AbsolutePath(&absolute_path);
128 std::string error; 157 std::string error;
129 scoped_ptr<DictionaryValue> manifest( 158 scoped_ptr<DictionaryValue> manifest(
130 extension_file_util::LoadManifest(absolute_path, &error)); 159 extension_file_util::LoadManifest(absolute_path, &error));
131 if (!manifest.get()) { 160 if (!manifest.get()) {
132 LOG(ERROR) << "Could not load extension from '" << 161 LOG(ERROR) << "Could not load extension from '" <<
133 absolute_path.value() << "'. " << error; 162 absolute_path.value() << "'. " << error;
134 return NULL; 163 return NULL;
135 } 164 }
136 Remove(GenerateId(manifest.get())); 165 Remove(GenerateId(manifest.get(), absolute_path));
137 166
138 return Add(manifest.release(), absolute_path); 167 return Add(manifest.release(), absolute_path);
139 } 168 }
140 169
141 void ComponentLoader::Reload(const std::string& extension_id) { 170 void ComponentLoader::Reload(const std::string& extension_id) {
142 for (RegisteredComponentExtensions::iterator it = 171 for (RegisteredComponentExtensions::iterator it =
143 component_extensions_.begin(); it != component_extensions_.end(); 172 component_extensions_.begin(); it != component_extensions_.end();
144 ++it) { 173 ++it) {
145 if (GenerateId(it->manifest) == extension_id) { 174 if (it->extension_id == extension_id) {
146 Load(*it); 175 Load(*it);
147 break; 176 break;
148 } 177 }
149 } 178 }
150 } 179 }
151 180
152 const Extension* ComponentLoader::Load(const ComponentExtensionInfo& info) { 181 const Extension* ComponentLoader::Load(const ComponentExtensionInfo& info) {
153 // TODO(abarth): We should REQUIRE_MODERN_MANIFEST_VERSION once we've updated 182 // TODO(abarth): We should REQUIRE_MODERN_MANIFEST_VERSION once we've updated
154 // our component extensions to the new manifest version. 183 // our component extensions to the new manifest version.
155 int flags = Extension::REQUIRE_KEY; 184 int flags = Extension::REQUIRE_KEY;
156 185
157 std::string error; 186 std::string error;
158 187
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( 188 scoped_refptr<const Extension> extension(Extension::Create(
170 absolute_path, 189 info.root_directory,
171 Extension::COMPONENT, 190 Extension::COMPONENT,
172 *info.manifest, 191 *info.manifest,
173 flags, 192 flags,
174 &error)); 193 &error));
175 if (!extension.get()) { 194 if (!extension.get()) {
176 LOG(ERROR) << error; 195 LOG(ERROR) << error;
177 return NULL; 196 return NULL;
178 } 197 }
198 CHECK_EQ(info.extension_id, extension->id()) << extension->name();
179 extension_service_->AddExtension(extension); 199 extension_service_->AddExtension(extension);
180 return extension; 200 return extension;
181 } 201 }
182 202
183 void ComponentLoader::Remove(const FilePath& root_directory) { 203 void ComponentLoader::Remove(const FilePath& root_directory) {
184 // Find the ComponentExtensionInfo for the extension. 204 // Find the ComponentExtensionInfo for the extension.
185 RegisteredComponentExtensions::iterator it = component_extensions_.begin(); 205 RegisteredComponentExtensions::iterator it = component_extensions_.begin();
186 for (; it != component_extensions_.end(); ++it) { 206 for (; it != component_extensions_.end(); ++it) {
187 if (it->root_directory == root_directory) { 207 if (it->root_directory == root_directory) {
188 Remove(GenerateId(it->manifest)); 208 Remove(GenerateId(it->manifest, root_directory));
189 break; 209 break;
190 } 210 }
191 } 211 }
192 } 212 }
193 213
194 void ComponentLoader::Remove(const std::string& id) { 214 void ComponentLoader::Remove(const std::string& id) {
195 RegisteredComponentExtensions::iterator it = component_extensions_.begin(); 215 RegisteredComponentExtensions::iterator it = component_extensions_.begin();
196 for (; it != component_extensions_.end(); ++it) { 216 for (; it != component_extensions_.end(); ++it) {
197 if (GenerateId(it->manifest) == id) { 217 if (it->extension_id == id) {
198 delete it->manifest; 218 delete it->manifest;
199 it = component_extensions_.erase(it); 219 it = component_extensions_.erase(it);
200 if (extension_service_->is_ready()) 220 if (extension_service_->is_ready())
201 extension_service_-> 221 extension_service_->
202 UnloadExtension(id, extension_misc::UNLOAD_REASON_DISABLE); 222 UnloadExtension(id, extension_misc::UNLOAD_REASON_DISABLE);
203 break; 223 break;
204 } 224 }
205 } 225 }
206 } 226 }
207 227
208 bool ComponentLoader::Exists(const std::string& id) const { 228 bool ComponentLoader::Exists(const std::string& id) const {
209 RegisteredComponentExtensions::const_iterator it = 229 RegisteredComponentExtensions::const_iterator it =
210 component_extensions_.begin(); 230 component_extensions_.begin();
211 for (; it != component_extensions_.end(); ++it) 231 for (; it != component_extensions_.end(); ++it)
212 if (GenerateId(it->manifest) == id) 232 if (it->extension_id == id)
213 return true; 233 return true;
214 return false; 234 return false;
215 } 235 }
216 236
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() { 237 void ComponentLoader::AddFileManagerExtension() {
231 #if defined(FILE_MANAGER_EXTENSION) 238 #if defined(FILE_MANAGER_EXTENSION)
232 #ifndef NDEBUG 239 #ifndef NDEBUG
233 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 240 const CommandLine* command_line = CommandLine::ForCurrentProcess();
234 if (command_line->HasSwitch(switches::kFileManagerExtensionPath)) { 241 if (command_line->HasSwitch(switches::kFileManagerExtensionPath)) {
235 FilePath filemgr_extension_path( 242 FilePath filemgr_extension_path(
236 command_line->GetSwitchValuePath(switches::kFileManagerExtensionPath)); 243 command_line->GetSwitchValuePath(switches::kFileManagerExtensionPath));
237 Add(IDR_FILEMANAGER_MANIFEST, filemgr_extension_path); 244 Add(IDR_FILEMANAGER_MANIFEST, filemgr_extension_path);
238 return; 245 return;
239 } 246 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 302
296 // Update manifest to use a proper name. 303 // Update manifest to use a proper name.
297 manifest->SetString(extension_manifest_keys::kName, 304 manifest->SetString(extension_manifest_keys::kName,
298 l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME)); 305 l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME));
299 306
300 if (manifest) 307 if (manifest)
301 Add(manifest, FilePath(FILE_PATH_LITERAL("chrome_app"))); 308 Add(manifest, FilePath(FILE_PATH_LITERAL("chrome_app")));
302 #endif 309 #endif
303 } 310 }
304 311
312 void ComponentLoader::AddScriptBubble() {
313 if (FeatureSwitch::GetScriptBubble()->IsEnabled()) {
314 script_bubble_id_ =
315 Add(IDR_SCRIPT_BUBBLE_MANIFEST,
316 FilePath(FILE_PATH_LITERAL("script_bubble")));
317 }
318 }
319
305 void ComponentLoader::AddDefaultComponentExtensions() { 320 void ComponentLoader::AddDefaultComponentExtensions() {
306 #if defined(OS_CHROMEOS) 321 #if defined(OS_CHROMEOS)
307 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession)) 322 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession))
308 Add(IDR_BOOKMARKS_MANIFEST, 323 Add(IDR_BOOKMARKS_MANIFEST,
309 FilePath(FILE_PATH_LITERAL("bookmark_manager"))); 324 FilePath(FILE_PATH_LITERAL("bookmark_manager")));
310 #else 325 #else
311 Add(IDR_BOOKMARKS_MANIFEST, FilePath(FILE_PATH_LITERAL("bookmark_manager"))); 326 Add(IDR_BOOKMARKS_MANIFEST, FilePath(FILE_PATH_LITERAL("bookmark_manager")));
312 #endif 327 #endif
313 328
314 #if defined(OS_CHROMEOS) 329 #if defined(OS_CHROMEOS)
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 388
374 // If a URL for the enterprise webstore has been specified, load the 389 // If a URL for the enterprise webstore has been specified, load the
375 // component extension. This extension might also be loaded later, because 390 // component extension. This extension might also be loaded later, because
376 // it is specified by policy, and on ChromeOS policies are loaded after 391 // it is specified by policy, and on ChromeOS policies are loaded after
377 // the browser process has started. 392 // the browser process has started.
378 AddOrReloadEnterpriseWebStore(); 393 AddOrReloadEnterpriseWebStore();
379 394
380 #if defined(USE_ASH) 395 #if defined(USE_ASH)
381 AddChromeApp(); 396 AddChromeApp();
382 #endif 397 #endif
398
399 AddScriptBubble();
383 } 400 }
384 401
385 void ComponentLoader::Observe( 402 void ComponentLoader::Observe(
386 int type, 403 int type,
387 const content::NotificationSource& source, 404 const content::NotificationSource& source,
388 const content::NotificationDetails& details) { 405 const content::NotificationDetails& details) {
389 if (type == chrome::NOTIFICATION_PREF_CHANGED) { 406 if (type == chrome::NOTIFICATION_PREF_CHANGED) {
390 const std::string* name = 407 const std::string* name =
391 content::Details<const std::string>(details).ptr(); 408 content::Details<const std::string>(details).ptr();
392 if (*name == prefs::kEnterpriseWebStoreURL) 409 if (*name == prefs::kEnterpriseWebStoreURL)
393 AddOrReloadEnterpriseWebStore(); 410 AddOrReloadEnterpriseWebStore();
394 else 411 else
395 NOTREACHED(); 412 NOTREACHED();
396 } else { 413 } else {
397 NOTREACHED(); 414 NOTREACHED();
398 } 415 }
399 } 416 }
400 417
401 // static 418 // static
402 void ComponentLoader::RegisterUserPrefs(PrefService* prefs) { 419 void ComponentLoader::RegisterUserPrefs(PrefService* prefs) {
403 prefs->RegisterStringPref(prefs::kEnterpriseWebStoreURL, 420 prefs->RegisterStringPref(prefs::kEnterpriseWebStoreURL,
404 std::string() /* default_value */, 421 std::string() /* default_value */,
405 PrefService::UNSYNCABLE_PREF); 422 PrefService::UNSYNCABLE_PREF);
406 prefs->RegisterStringPref(prefs::kEnterpriseWebStoreName, 423 prefs->RegisterStringPref(prefs::kEnterpriseWebStoreName,
407 std::string() /* default_value */, 424 std::string() /* default_value */,
408 PrefService::UNSYNCABLE_PREF); 425 PrefService::UNSYNCABLE_PREF);
409 } 426 }
410 427
411 } // namespace extensions 428 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/component_loader.h ('k') | chrome/browser/extensions/component_loader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698