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

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

Issue 8417012: Refactor loading out of ExtensionService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month 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) 2011 The Chromium Authors. All rights reserved. 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 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/extension_service.h" 5 #include "chrome/browser/extensions/extension_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/file_util.h" 14 #include "base/file_util.h"
15 #include "base/json/json_value_serializer.h"
16 #include "base/logging.h" 15 #include "base/logging.h"
17 #include "base/metrics/field_trial.h" 16 #include "base/metrics/field_trial.h"
18 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
19 #include "base/path_service.h"
20 #include "base/stl_util.h" 18 #include "base/stl_util.h"
21 #include "base/string16.h" 19 #include "base/string16.h"
22 #include "base/string_number_conversions.h" 20 #include "base/string_number_conversions.h"
23 #include "base/string_util.h" 21 #include "base/string_util.h"
24 #include "base/stringprintf.h" 22 #include "base/stringprintf.h"
25 #include "base/threading/thread_restrictions.h" 23 #include "base/threading/thread_restrictions.h"
26 #include "base/time.h" 24 #include "base/time.h"
27 #include "base/utf_string_conversions.h" 25 #include "base/utf_string_conversions.h"
28 #include "base/values.h" 26 #include "base/values.h"
29 #include "base/version.h" 27 #include "base/version.h"
30 #include "chrome/browser/bookmarks/bookmark_extension_api.h" 28 #include "chrome/browser/bookmarks/bookmark_extension_api.h"
31 #include "chrome/browser/browser_process.h" 29 #include "chrome/browser/browser_process.h"
32 #include "chrome/browser/chrome_plugin_service_filter.h" 30 #include "chrome/browser/chrome_plugin_service_filter.h"
33 #include "chrome/browser/extensions/app_notification_manager.h" 31 #include "chrome/browser/extensions/app_notification_manager.h"
34 #include "chrome/browser/extensions/apps_promo.h" 32 #include "chrome/browser/extensions/apps_promo.h"
33 #include "chrome/browser/extensions/component_loader.h"
35 #include "chrome/browser/extensions/crx_installer.h" 34 #include "chrome/browser/extensions/crx_installer.h"
36 #include "chrome/browser/extensions/default_apps_trial.h" 35 #include "chrome/browser/extensions/default_apps_trial.h"
37 #include "chrome/browser/extensions/extension_accessibility_api.h" 36 #include "chrome/browser/extensions/extension_accessibility_api.h"
38 #include "chrome/browser/extensions/extension_browser_event_router.h" 37 #include "chrome/browser/extensions/extension_browser_event_router.h"
39 #include "chrome/browser/extensions/extension_cookies_api.h" 38 #include "chrome/browser/extensions/extension_cookies_api.h"
40 #include "chrome/browser/extensions/extension_data_deleter.h" 39 #include "chrome/browser/extensions/extension_data_deleter.h"
41 #include "chrome/browser/extensions/extension_downloads_api.h" 40 #include "chrome/browser/extensions/extension_downloads_api.h"
42 #include "chrome/browser/extensions/extension_error_reporter.h" 41 #include "chrome/browser/extensions/extension_error_reporter.h"
43 #include "chrome/browser/extensions/extension_global_error.h" 42 #include "chrome/browser/extensions/extension_global_error.h"
44 #include "chrome/browser/extensions/extension_host.h" 43 #include "chrome/browser/extensions/extension_host.h"
45 #include "chrome/browser/extensions/extension_input_ime_api.h" 44 #include "chrome/browser/extensions/extension_input_ime_api.h"
46 #include "chrome/browser/extensions/extension_install_ui.h"
47 #include "chrome/browser/extensions/extension_management_api.h" 45 #include "chrome/browser/extensions/extension_management_api.h"
48 #include "chrome/browser/extensions/extension_preference_api.h" 46 #include "chrome/browser/extensions/extension_preference_api.h"
49 #include "chrome/browser/extensions/extension_process_manager.h" 47 #include "chrome/browser/extensions/extension_process_manager.h"
50 #include "chrome/browser/extensions/extension_processes_api.h" 48 #include "chrome/browser/extensions/extension_processes_api.h"
51 #include "chrome/browser/extensions/extension_special_storage_policy.h" 49 #include "chrome/browser/extensions/extension_special_storage_policy.h"
52 #include "chrome/browser/extensions/extension_sync_data.h" 50 #include "chrome/browser/extensions/extension_sync_data.h"
53 #include "chrome/browser/extensions/extension_updater.h" 51 #include "chrome/browser/extensions/extension_updater.h"
54 #include "chrome/browser/extensions/extension_web_ui.h" 52 #include "chrome/browser/extensions/extension_web_ui.h"
55 #include "chrome/browser/extensions/extension_webnavigation_api.h" 53 #include "chrome/browser/extensions/extension_webnavigation_api.h"
56 #include "chrome/browser/extensions/external_extension_provider_impl.h" 54 #include "chrome/browser/extensions/external_extension_provider_impl.h"
57 #include "chrome/browser/extensions/external_extension_provider_interface.h" 55 #include "chrome/browser/extensions/external_extension_provider_interface.h"
56 #include "chrome/browser/extensions/installed_extension_loader.h"
58 #include "chrome/browser/extensions/pending_extension_manager.h" 57 #include "chrome/browser/extensions/pending_extension_manager.h"
58 #include "chrome/browser/extensions/unpacked_installer.h"
59 #include "chrome/browser/history/history_extension_api.h" 59 #include "chrome/browser/history/history_extension_api.h"
60 #include "chrome/browser/net/chrome_url_request_context.h" 60 #include "chrome/browser/net/chrome_url_request_context.h"
61 #include "chrome/browser/prefs/pref_service.h" 61 #include "chrome/browser/prefs/pref_service.h"
62 #include "chrome/browser/profiles/profile.h" 62 #include "chrome/browser/profiles/profile.h"
63 #include "chrome/browser/search_engines/template_url_service.h" 63 #include "chrome/browser/search_engines/template_url_service.h"
64 #include "chrome/browser/search_engines/template_url_service_factory.h" 64 #include "chrome/browser/search_engines/template_url_service_factory.h"
65 #include "chrome/browser/sync/api/sync_change.h" 65 #include "chrome/browser/sync/api/sync_change.h"
66 #include "chrome/browser/themes/theme_service.h" 66 #include "chrome/browser/themes/theme_service.h"
67 #include "chrome/browser/themes/theme_service_factory.h" 67 #include "chrome/browser/themes/theme_service_factory.h"
68 #include "chrome/browser/ui/browser.h" 68 #include "chrome/browser/ui/browser.h"
69 #include "chrome/browser/ui/browser_list.h" 69 #include "chrome/browser/ui/browser_list.h"
70 #include "chrome/browser/ui/global_error_service.h" 70 #include "chrome/browser/ui/global_error_service.h"
71 #include "chrome/browser/ui/global_error_service_factory.h" 71 #include "chrome/browser/ui/global_error_service_factory.h"
72 #include "chrome/browser/ui/webui/chrome_url_data_manager.h" 72 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
73 #include "chrome/browser/ui/webui/favicon_source.h" 73 #include "chrome/browser/ui/webui/favicon_source.h"
74 #include "chrome/browser/ui/webui/ntp/shown_sections_handler.h" 74 #include "chrome/browser/ui/webui/ntp/shown_sections_handler.h"
75 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" 75 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h"
76 #include "chrome/common/child_process_logging.h" 76 #include "chrome/common/child_process_logging.h"
77 #include "chrome/common/chrome_notification_types.h" 77 #include "chrome/common/chrome_notification_types.h"
78 #include "chrome/common/chrome_paths.h"
79 #include "chrome/common/chrome_switches.h" 78 #include "chrome/common/chrome_switches.h"
80 #include "chrome/common/extensions/extension.h" 79 #include "chrome/common/extensions/extension.h"
81 #include "chrome/common/extensions/extension_constants.h" 80 #include "chrome/common/extensions/extension_constants.h"
82 #include "chrome/common/extensions/extension_error_utils.h" 81 #include "chrome/common/extensions/extension_error_utils.h"
83 #include "chrome/common/extensions/extension_file_util.h" 82 #include "chrome/common/extensions/extension_file_util.h"
84 #include "chrome/common/extensions/extension_l10n_util.h"
85 #include "chrome/common/extensions/extension_messages.h" 83 #include "chrome/common/extensions/extension_messages.h"
86 #include "chrome/common/extensions/extension_resource.h" 84 #include "chrome/common/extensions/extension_resource.h"
87 #include "chrome/common/pref_names.h" 85 #include "chrome/common/pref_names.h"
88 #include "chrome/common/url_constants.h" 86 #include "chrome/common/url_constants.h"
89 #include "content/browser/browser_thread.h" 87 #include "content/browser/browser_thread.h"
90 #include "content/browser/debugger/devtools_manager.h" 88 #include "content/browser/debugger/devtools_manager.h"
91 #include "content/browser/plugin_process_host.h" 89 #include "content/browser/plugin_process_host.h"
92 #include "content/browser/plugin_service.h" 90 #include "content/browser/plugin_service.h"
93 #include "content/browser/renderer_host/render_process_host.h" 91 #include "content/browser/renderer_host/render_process_host.h"
94 #include "content/browser/user_metrics.h" 92 #include "content/browser/user_metrics.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 #elif defined(OS_MACOSX) 127 #elif defined(OS_MACOSX)
130 static const int kOmniboxIconPaddingLeft = 0; 128 static const int kOmniboxIconPaddingLeft = 0;
131 static const int kOmniboxIconPaddingRight = 2; 129 static const int kOmniboxIconPaddingRight = 2;
132 #else 130 #else
133 static const int kOmniboxIconPaddingLeft = 0; 131 static const int kOmniboxIconPaddingLeft = 0;
134 static const int kOmniboxIconPaddingRight = 0; 132 static const int kOmniboxIconPaddingRight = 0;
135 #endif 133 #endif
136 134
137 const char* kNaClPluginMimeType = "application/x-nacl"; 135 const char* kNaClPluginMimeType = "application/x-nacl";
138 136
139 // The following enumeration is used in histograms matching
140 // Extensions.ManifestReload* . Values may be added, as long
141 // as existing values are not changed.
142 enum ManifestReloadReason {
143 NOT_NEEDED = 0, // Reload not needed.
144 UNPACKED_DIR, // Unpacked directory
145 NEEDS_RELOCALIZATION, // The local has changed since we read this extension.
146 NUM_MANIFEST_RELOAD_REASONS
147 };
148
149 ManifestReloadReason ShouldReloadExtensionManifest(const ExtensionInfo& info) {
150 // Always reload manifests of unpacked extensions, because they can change
151 // on disk independent of the manifest in our prefs.
152 if (info.extension_location == Extension::LOAD)
153 return UNPACKED_DIR;
154
155 // Reload the manifest if it needs to be relocalized.
156 if (extension_l10n_util::ShouldRelocalizeManifest(info))
157 return NEEDS_RELOCALIZATION;
158
159 return NOT_NEEDED;
160 }
161
162 static void ForceShutdownPlugin(const FilePath& plugin_path) { 137 static void ForceShutdownPlugin(const FilePath& plugin_path) {
163 PluginProcessHost* plugin = 138 PluginProcessHost* plugin =
164 PluginService::GetInstance()->FindNpapiPluginProcess(plugin_path); 139 PluginService::GetInstance()->FindNpapiPluginProcess(plugin_path);
165 if (plugin) 140 if (plugin)
166 plugin->ForceShutdown(); 141 plugin->ForceShutdown();
167 } 142 }
168 143
169 static bool IsSyncableExtension(const Extension& extension) { 144 static bool IsSyncableExtension(const Extension& extension) {
170 return extension.GetSyncType() == Extension::SYNC_TYPE_EXTENSION; 145 return extension.GetSyncType() == Extension::SYNC_TYPE_EXTENSION;
171 } 146 }
172 147
173 static bool IsSyncableApp(const Extension& extension) { 148 static bool IsSyncableApp(const Extension& extension) {
174 return extension.GetSyncType() == Extension::SYNC_TYPE_APP; 149 return extension.GetSyncType() == Extension::SYNC_TYPE_APP;
175 } 150 }
176 151
177 // Manages an ExtensionInstallUI for a particular extension.
178 class SimpleExtensionLoadPrompt : public ExtensionInstallUI::Delegate {
179 public:
180 SimpleExtensionLoadPrompt(Profile* profile,
181 base::WeakPtr<ExtensionService> extension_service,
182 const Extension* extension);
183 ~SimpleExtensionLoadPrompt();
184
185 void ShowPrompt();
186
187 // ExtensionInstallUI::Delegate
188 virtual void InstallUIProceed();
189 virtual void InstallUIAbort(bool user_initiated);
190
191 private:
192 base::WeakPtr<ExtensionService> extension_service_;
193 scoped_ptr<ExtensionInstallUI> install_ui_;
194 scoped_refptr<const Extension> extension_;
195 };
196
197 SimpleExtensionLoadPrompt::SimpleExtensionLoadPrompt(
198 Profile* profile,
199 base::WeakPtr<ExtensionService> extension_service,
200 const Extension* extension)
201 : extension_service_(extension_service),
202 install_ui_(new ExtensionInstallUI(profile)),
203 extension_(extension) {
204 }
205
206 SimpleExtensionLoadPrompt::~SimpleExtensionLoadPrompt() {
207 }
208
209 void SimpleExtensionLoadPrompt::ShowPrompt() {
210 install_ui_->ConfirmInstall(this, extension_);
211 }
212
213 void SimpleExtensionLoadPrompt::InstallUIProceed() {
214 if (extension_service_.get())
215 extension_service_->OnExtensionInstalled(
216 extension_, false, -1); // Not from web store.
217 delete this;
218 }
219
220 void SimpleExtensionLoadPrompt::InstallUIAbort(bool user_initiated) {
221 delete this;
222 }
223
224 } // namespace 152 } // namespace
225 153
226 bool ExtensionService::ComponentExtensionInfo::Equals(
227 const ComponentExtensionInfo& other) const {
228 return other.manifest == manifest && other.root_directory == root_directory;
229 }
230
231 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData() 154 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData()
232 : background_page_ready(false), 155 : background_page_ready(false),
233 being_upgraded(false), 156 being_upgraded(false),
234 has_used_webrequest(false) { 157 has_used_webrequest(false) {
235 } 158 }
236 159
237 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { 160 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() {
238 } 161 }
239 162
240 ExtensionService::NaClModuleInfo::NaClModuleInfo() { 163 ExtensionService::NaClModuleInfo::NaClModuleInfo() {
241 } 164 }
242 165
243 ExtensionService::NaClModuleInfo::~NaClModuleInfo() { 166 ExtensionService::NaClModuleInfo::~NaClModuleInfo() {
244 } 167 }
245 168
246 // ExtensionService. 169 // ExtensionService.
247 170
248 const char* ExtensionService::kInstallDirectoryName = "Extensions"; 171 const char* ExtensionService::kInstallDirectoryName = "Extensions";
249 const char* ExtensionService::kSettingsDirectoryName = "Extension Settings"; 172 const char* ExtensionService::kSettingsDirectoryName = "Extension Settings";
250 173
251 // Implements IO for the ExtensionService.
252
253 class ExtensionServiceBackend
254 : public base::RefCountedThreadSafe<ExtensionServiceBackend> {
255 public:
256 // |install_directory| is a path where to look for extensions to load.
257 ExtensionServiceBackend(
258 base::WeakPtr<ExtensionService> frontend,
259 const FilePath& install_directory);
260
261 // Loads a single extension from |path| where |path| is the top directory of
262 // a specific extension where its manifest file lives. If |prompt_for_plugins|
263 // is true and the extension contains plugins, we prompt the user before
264 // loading.
265 // Errors are reported through ExtensionErrorReporter. On success,
266 // AddExtension() is called.
267 // TODO(erikkay): It might be useful to be able to load a packed extension
268 // (presumably into memory) without installing it.
269 void LoadSingleExtension(const FilePath &path, bool prompt_for_plugins);
270
271 private:
272 friend class base::RefCountedThreadSafe<ExtensionServiceBackend>;
273
274 virtual ~ExtensionServiceBackend();
275
276 // LoadSingleExtension needs to check the file access preference, which needs
277 // to happen back on the UI thread, so it posts CheckExtensionFileAccess on
278 // the UI thread. In turn, once that gets the pref, it goes back to the
279 // file thread with LoadSingleExtensionWithFileAccess.
280 void CheckExtensionFileAccess(const FilePath& extension_path,
281 bool prompt_for_plugins);
282 void LoadSingleExtensionWithFileAccess(
283 const FilePath &path, bool allow_file_access, bool prompt_for_plugins);
284
285 // Notify the frontend that there was an error loading an extension.
286 void ReportExtensionLoadError(const FilePath& extension_path,
287 const std::string& error);
288
289 // Notify the frontend that an extension was installed.
290 void OnLoadSingleExtension(const scoped_refptr<const Extension>& extension,
291 bool prompt_for_plugins);
292
293 base::WeakPtr<ExtensionService> frontend_;
294
295 // The top-level extensions directory being installed to.
296 FilePath install_directory_;
297
298 DISALLOW_COPY_AND_ASSIGN(ExtensionServiceBackend);
299 };
300
301 ExtensionServiceBackend::ExtensionServiceBackend(
302 base::WeakPtr<ExtensionService> frontend,
303 const FilePath& install_directory)
304 : frontend_(frontend),
305 install_directory_(install_directory) {
306 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
307 }
308
309 ExtensionServiceBackend::~ExtensionServiceBackend() {
310 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
311 BrowserThread::CurrentlyOn(BrowserThread::FILE));
312 }
313
314 void ExtensionServiceBackend::LoadSingleExtension(const FilePath& path_in,
315 bool prompt_for_plugins) {
316 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
317
318 FilePath extension_path = path_in;
319 file_util::AbsolutePath(&extension_path);
320
321 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
322 base::Bind(&ExtensionServiceBackend::CheckExtensionFileAccess,
323 this, extension_path, prompt_for_plugins));
324 }
325
326 void ExtensionServiceBackend::CheckExtensionFileAccess(
327 const FilePath& extension_path, bool prompt_for_plugins) {
328 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
329 std::string id = Extension::GenerateIdForPath(extension_path);
330 // Unpacked extensions default to allowing file access, but if that has been
331 // overridden, don't reset the value.
332 bool allow_file_access =
333 Extension::ShouldAlwaysAllowFileAccess(Extension::LOAD);
334 if (frontend_->extension_prefs()->HasAllowFileAccessSetting(id))
335 allow_file_access = frontend_->extension_prefs()->AllowFileAccess(id);
336
337 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
338 base::Bind(
339 &ExtensionServiceBackend::LoadSingleExtensionWithFileAccess,
340 this, extension_path, allow_file_access, prompt_for_plugins));
341 }
342
343 void ExtensionServiceBackend::LoadSingleExtensionWithFileAccess(
344 const FilePath& extension_path,
345 bool allow_file_access,
346 bool prompt_for_plugins) {
347 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
348 int flags = allow_file_access ?
349 Extension::ALLOW_FILE_ACCESS : Extension::NO_FLAGS;
350 if (Extension::ShouldDoStrictErrorChecking(Extension::LOAD))
351 flags |= Extension::STRICT_ERROR_CHECKS;
352 std::string error;
353 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension(
354 extension_path,
355 Extension::LOAD,
356 flags,
357 &error));
358
359 if (!extension) {
360 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
361 base::Bind(
362 &ExtensionServiceBackend::ReportExtensionLoadError,
363 this,
364 extension_path, error));
365 return;
366 }
367
368 // Report this as an installed extension so that it gets remembered in the
369 // prefs.
370 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
371 base::Bind(
372 &ExtensionServiceBackend::OnLoadSingleExtension,
373 this, extension, prompt_for_plugins));
374 }
375
376 void ExtensionServiceBackend::ReportExtensionLoadError(
377 const FilePath& extension_path, const std::string &error) {
378 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
379 if (frontend_.get())
380 frontend_->ReportExtensionLoadError(
381 extension_path, error, true /* alert_on_error */);
382 }
383
384 void ExtensionServiceBackend::OnLoadSingleExtension(
385 const scoped_refptr<const Extension>& extension, bool prompt_for_plugins) {
386 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
387 if (frontend_.get())
388 frontend_->OnLoadSingleExtension(extension, prompt_for_plugins);
389 }
390
391 void ExtensionService::CheckExternalUninstall(const std::string& id) { 174 void ExtensionService::CheckExternalUninstall(const std::string& id) {
392 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 175 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
393 176
394 // Check if the providers know about this extension. 177 // Check if the providers know about this extension.
395 ProviderCollection::const_iterator i; 178 ProviderCollection::const_iterator i;
396 for (i = external_extension_providers_.begin(); 179 for (i = external_extension_providers_.begin();
397 i != external_extension_providers_.end(); ++i) { 180 i != external_extension_providers_.end(); ++i) {
398 DCHECK(i->get()->IsReady()); 181 DCHECK(i->get()->IsReady());
399 if (i->get()->HasExtension(id)) 182 if (i->get()->HasExtension(id))
400 return; // Yup, known extension, don't uninstall. 183 return; // Yup, known extension, don't uninstall.
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 switches::kExtensionsUpdateFrequency), 402 switches::kExtensionsUpdateFrequency),
620 &update_frequency); 403 &update_frequency);
621 } 404 }
622 updater_.reset(new ExtensionUpdater(this, 405 updater_.reset(new ExtensionUpdater(this,
623 extension_prefs, 406 extension_prefs,
624 profile->GetPrefs(), 407 profile->GetPrefs(),
625 profile, 408 profile,
626 update_frequency)); 409 update_frequency));
627 } 410 }
628 411
629 backend_ = 412 component_loader_.reset(new ComponentLoader(this));
630 new ExtensionServiceBackend(weak_ptr_factory_.GetWeakPtr(),
631 install_directory_);
632 413
633 app_notification_manager_->Init(); 414 app_notification_manager_->Init();
634 415
635 if (extensions_enabled_) { 416 if (extensions_enabled_) {
636 ExternalExtensionProviderImpl::CreateExternalProviders( 417 ExternalExtensionProviderImpl::CreateExternalProviders(
637 this, profile_, &external_extension_providers_); 418 this, profile_, &external_extension_providers_);
638 } 419 }
639 420
640 // Use monochrome icons for Omnibox icons. 421 // Use monochrome icons for Omnibox icons.
641 omnibox_popup_icon_manager_.set_monochrome(true); 422 omnibox_popup_icon_manager_.set_monochrome(true);
(...skipping 15 matching lines...) Expand all
657 } 438 }
658 439
659 const ExtensionList* ExtensionService::terminated_extensions() const { 440 const ExtensionList* ExtensionService::terminated_extensions() const {
660 return &terminated_extensions_; 441 return &terminated_extensions_;
661 } 442 }
662 443
663 PendingExtensionManager* ExtensionService::pending_extension_manager() { 444 PendingExtensionManager* ExtensionService::pending_extension_manager() {
664 return &pending_extension_manager_; 445 return &pending_extension_manager_;
665 } 446 }
666 447
667 void ExtensionService::UnregisterComponentExtension(
668 const ComponentExtensionInfo& info) {
669 RegisteredComponentExtensions new_component_extension_manifests;
670 for (RegisteredComponentExtensions::iterator it =
671 component_extension_manifests_.begin();
672 it != component_extension_manifests_.end(); ++it) {
673 if (!it->Equals(info))
674 new_component_extension_manifests.push_back(*it);
675 }
676 component_extension_manifests_.swap(new_component_extension_manifests);
677 }
678
679 ExtensionService::~ExtensionService() { 448 ExtensionService::~ExtensionService() {
680 // No need to unload extensions here because they are profile-scoped, and the 449 // No need to unload extensions here because they are profile-scoped, and the
681 // profile is in the process of being deleted. 450 // profile is in the process of being deleted.
682 451
683 ProviderCollection::const_iterator i; 452 ProviderCollection::const_iterator i;
684 for (i = external_extension_providers_.begin(); 453 for (i = external_extension_providers_.begin();
685 i != external_extension_providers_.end(); ++i) { 454 i != external_extension_providers_.end(); ++i) {
686 ExternalExtensionProviderInterface* provider = i->get(); 455 ExternalExtensionProviderInterface* provider = i->get();
687 provider->ServiceShutdown(); 456 provider->ServiceShutdown();
688 } 457 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 void ExtensionService::Init() { 511 void ExtensionService::Init() {
743 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 512 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
744 513
745 DCHECK(!ready_); // Can't redo init. 514 DCHECK(!ready_); // Can't redo init.
746 DCHECK_EQ(extensions_.size(), 0u); 515 DCHECK_EQ(extensions_.size(), 0u);
747 516
748 // Hack: we need to ensure the ResourceDispatcherHost is ready before we load 517 // Hack: we need to ensure the ResourceDispatcherHost is ready before we load
749 // the first extension, because its members listen for loaded notifications. 518 // the first extension, because its members listen for loaded notifications.
750 g_browser_process->resource_dispatcher_host(); 519 g_browser_process->resource_dispatcher_host();
751 520
752 LoadAllExtensions(); 521 component_loader_->LoadComponentExtensions();
522 MakeInstalledExtensionLoader()->LoadAllExtensions();
753 523
754 // TODO(erikkay) this should probably be deferred to a future point 524 // TODO(erikkay) this should probably be deferred to a future point
755 // rather than running immediately at startup. 525 // rather than running immediately at startup.
756 CheckForExternalUpdates(); 526 CheckForExternalUpdates();
757 527
758 // TODO(erikkay) this should probably be deferred as well. 528 // TODO(erikkay) this should probably be deferred as well.
759 GarbageCollectExtensions(); 529 GarbageCollectExtensions();
760 } 530 }
761 531
762 bool ExtensionService::UpdateExtension( 532 bool ExtensionService::UpdateExtension(
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 } else { 609 } else {
840 path = unloaded_extension_paths_[extension_id]; 610 path = unloaded_extension_paths_[extension_id];
841 } 611 }
842 612
843 // Check the installed extensions to see if what we're reloading was already 613 // Check the installed extensions to see if what we're reloading was already
844 // installed. 614 // installed.
845 scoped_ptr<ExtensionInfo> installed_extension( 615 scoped_ptr<ExtensionInfo> installed_extension(
846 extension_prefs_->GetInstalledExtensionInfo(extension_id)); 616 extension_prefs_->GetInstalledExtensionInfo(extension_id));
847 if (installed_extension.get() && 617 if (installed_extension.get() &&
848 installed_extension->extension_manifest.get()) { 618 installed_extension->extension_manifest.get()) {
849 LoadInstalledExtension(*installed_extension, false); 619 MakeInstalledExtensionLoader()->Load(*installed_extension, false);
850 } else { 620 } else {
621 // Otherwise, the extension is unpacked (location LOAD).
851 // We should always be able to remember the extension's path. If it's not in 622 // We should always be able to remember the extension's path. If it's not in
852 // the map, someone failed to update |unloaded_extension_paths_|. 623 // the map, someone failed to update |unloaded_extension_paths_|.
853 CHECK(!path.empty()); 624 CHECK(!path.empty());
854 LoadExtension(path); 625 MakeUnpackedInstaller()->Load(path);
855 } 626 }
856 } 627 }
857 628
858 bool ExtensionService::UninstallExtension( 629 bool ExtensionService::UninstallExtension(
859 const std::string& extension_id_unsafe, 630 const std::string& extension_id_unsafe,
860 bool external_uninstall, 631 bool external_uninstall,
861 std::string* error) { 632 std::string* error) {
862 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 633 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
863 634
864 // Copy the extension identifier since the reference might have been 635 // Copy the extension identifier since the reference might have been
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 EnableExtension(extension->id()); 866 EnableExtension(extension->id());
1096 } 867 }
1097 868
1098 void ExtensionService::UpdateActivePermissions( 869 void ExtensionService::UpdateActivePermissions(
1099 const Extension* extension, 870 const Extension* extension,
1100 const ExtensionPermissionSet* permissions) { 871 const ExtensionPermissionSet* permissions) {
1101 extension_prefs()->SetActivePermissions(extension->id(), permissions); 872 extension_prefs()->SetActivePermissions(extension->id(), permissions);
1102 extension->SetActivePermissions(permissions); 873 extension->SetActivePermissions(permissions);
1103 } 874 }
1104 875
1105 void ExtensionService::LoadExtension(const FilePath& extension_path) {
1106 LoadExtension(extension_path, true);
1107 }
1108
1109 void ExtensionService::LoadExtension(const FilePath& extension_path,
1110 bool prompt_for_plugins) {
1111 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
1112 base::Bind(&ExtensionServiceBackend::LoadSingleExtension, backend_.get(),
1113 extension_path, prompt_for_plugins));
1114 }
1115
1116 void ExtensionService::LoadExtensionFromCommandLine(
1117 const FilePath& path_in) {
1118
1119 // Load extensions from the command line synchronously to avoid a race
1120 // between extension loading and loading an URL from the command line.
1121 base::ThreadRestrictions::ScopedAllowIO allow_io;
1122
1123 FilePath extension_path = path_in;
1124 file_util::AbsolutePath(&extension_path);
1125
1126 std::string id = Extension::GenerateIdForPath(extension_path);
1127 bool allow_file_access =
1128 Extension::ShouldAlwaysAllowFileAccess(Extension::LOAD);
1129 if (extension_prefs()->HasAllowFileAccessSetting(id))
1130 allow_file_access = extension_prefs()->AllowFileAccess(id);
1131
1132 int flags = Extension::NO_FLAGS;
1133 if (allow_file_access)
1134 flags |= Extension::ALLOW_FILE_ACCESS;
1135 if (Extension::ShouldDoStrictErrorChecking(Extension::LOAD))
1136 flags |= Extension::STRICT_ERROR_CHECKS;
1137
1138 std::string error;
1139 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension(
1140 extension_path,
1141 Extension::LOAD,
1142 flags,
1143 &error));
1144
1145 if (!extension) {
1146 ReportExtensionLoadError(extension_path, error, true);
1147 return;
1148 }
1149
1150 OnLoadSingleExtension(extension, false);
1151 }
1152
1153 void ExtensionService::LoadComponentExtensions() {
1154 for (RegisteredComponentExtensions::iterator it =
1155 component_extension_manifests_.begin();
1156 it != component_extension_manifests_.end(); ++it) {
1157 LoadComponentExtension(*it);
1158 }
1159 }
1160
1161 const Extension* ExtensionService::LoadComponentExtension(
1162 const ComponentExtensionInfo &info) {
1163 JSONStringValueSerializer serializer(info.manifest);
1164 scoped_ptr<Value> manifest(serializer.Deserialize(NULL, NULL));
1165 if (!manifest.get()) {
1166 LOG(ERROR) << "Failed to parse manifest for extension";
1167 return NULL;
1168 }
1169
1170 int flags = Extension::REQUIRE_KEY;
1171 if (Extension::ShouldDoStrictErrorChecking(Extension::COMPONENT))
1172 flags |= Extension::STRICT_ERROR_CHECKS;
1173 std::string error;
1174 scoped_refptr<const Extension> extension(Extension::Create(
1175 info.root_directory,
1176 Extension::COMPONENT,
1177 *static_cast<DictionaryValue*>(manifest.get()),
1178 flags,
1179 &error));
1180 if (!extension.get()) {
1181 LOG(ERROR) << error;
1182 return NULL;
1183 }
1184 AddExtension(extension);
1185 return extension;
1186 }
1187
1188 void ExtensionService::UnloadComponentExtension(
1189 const ComponentExtensionInfo& info) {
1190 JSONStringValueSerializer serializer(info.manifest);
1191 scoped_ptr<Value> manifest(serializer.Deserialize(NULL, NULL));
1192 if (!manifest.get()) {
1193 LOG(ERROR) << "Failed to parse manifest for extension";
1194 return;
1195 }
1196 std::string public_key;
1197 std::string public_key_bytes;
1198 std::string id;
1199 if (!static_cast<DictionaryValue*>(manifest.get())->
1200 GetString(extension_manifest_keys::kPublicKey, &public_key) ||
1201 !Extension::ParsePEMKeyBytes(public_key, &public_key_bytes) ||
1202 !Extension::GenerateId(public_key_bytes, &id)) {
1203 LOG(ERROR) << "Failed to get extension id";
1204 return;
1205 }
1206 UnloadExtension(id, extension_misc::UNLOAD_REASON_DISABLE);
1207 }
1208
1209 void ExtensionService::LoadAllExtensions() {
1210 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1211
1212 base::TimeTicks start_time = base::TimeTicks::Now();
1213
1214 // Load any component extensions.
1215 LoadComponentExtensions();
1216
1217 // Load the previously installed extensions.
1218 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
1219 extension_prefs_->GetInstalledExtensionsInfo());
1220
1221 std::vector<int> reload_reason_counts(NUM_MANIFEST_RELOAD_REASONS, 0);
1222 bool should_write_prefs = false;
1223
1224 for (size_t i = 0; i < extensions_info->size(); ++i) {
1225 ExtensionInfo* info = extensions_info->at(i).get();
1226
1227 ManifestReloadReason reload_reason = ShouldReloadExtensionManifest(*info);
1228 ++reload_reason_counts[reload_reason];
1229 UMA_HISTOGRAM_ENUMERATION("Extensions.ManifestReloadEnumValue",
1230 reload_reason, 100);
1231
1232 if (reload_reason != NOT_NEEDED) {
1233 // Reloading and extension reads files from disk. We do this on the
1234 // UI thread because reloads should be very rare, and the complexity
1235 // added by delaying the time when the extensions service knows about
1236 // all extensions is significant. See crbug.com/37548 for details.
1237 // |allow_io| disables tests that file operations run on the file
1238 // thread.
1239 base::ThreadRestrictions::ScopedAllowIO allow_io;
1240
1241 std::string error;
1242 scoped_refptr<const Extension> extension(
1243 extension_file_util::LoadExtension(
1244 info->extension_path,
1245 info->extension_location,
1246 GetExtensionCreateFlagsForInstalledExtension(info),
1247 &error));
1248
1249 if (extension.get()) {
1250 extensions_info->at(i)->extension_manifest.reset(
1251 static_cast<DictionaryValue*>(
1252 extension->manifest_value()->DeepCopy()));
1253 should_write_prefs = true;
1254 }
1255 }
1256 }
1257
1258 for (size_t i = 0; i < extensions_info->size(); ++i) {
1259 LoadInstalledExtension(*extensions_info->at(i), should_write_prefs);
1260 }
1261
1262 OnLoadedInstalledExtensions();
1263
1264 // The histograms Extensions.ManifestReload* allow us to validate
1265 // the assumption that reloading manifest is a rare event.
1266 UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadNotNeeded",
1267 reload_reason_counts[NOT_NEEDED]);
1268 UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadUnpackedDir",
1269 reload_reason_counts[UNPACKED_DIR]);
1270 UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadNeedsRelocalization",
1271 reload_reason_counts[NEEDS_RELOCALIZATION]);
1272
1273 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAll", extensions_.size());
1274 UMA_HISTOGRAM_COUNTS_100("Extensions.Disabled", disabled_extensions_.size());
1275
1276 UMA_HISTOGRAM_TIMES("Extensions.LoadAllTime",
1277 base::TimeTicks::Now() - start_time);
1278
1279 int app_user_count = 0;
1280 int app_external_count = 0;
1281 int hosted_app_count = 0;
1282 int packaged_app_count = 0;
1283 int user_script_count = 0;
1284 int extension_user_count = 0;
1285 int extension_external_count = 0;
1286 int theme_count = 0;
1287 int page_action_count = 0;
1288 int browser_action_count = 0;
1289 ExtensionList::iterator ex;
1290 for (ex = extensions_.begin(); ex != extensions_.end(); ++ex) {
1291 Extension::Location location = (*ex)->location();
1292 Extension::Type type = (*ex)->GetType();
1293 if ((*ex)->is_app()) {
1294 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLocation",
1295 location, 100);
1296 } else if (type == Extension::TYPE_EXTENSION) {
1297 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionLocation",
1298 location, 100);
1299 }
1300
1301 // Don't count component extensions, since they are only extensions as an
1302 // implementation detail.
1303 if (location == Extension::COMPONENT)
1304 continue;
1305
1306 // Don't count unpacked extensions, since they're a developer-specific
1307 // feature.
1308 if (location == Extension::LOAD)
1309 continue;
1310
1311 // Using an enumeration shows us the total installed ratio across all users.
1312 // Using the totals per user at each startup tells us the distribution of
1313 // usage for each user (e.g. 40% of users have at least one app installed).
1314 UMA_HISTOGRAM_ENUMERATION("Extensions.LoadType", type, 100);
1315 switch (type) {
1316 case Extension::TYPE_THEME:
1317 ++theme_count;
1318 break;
1319 case Extension::TYPE_USER_SCRIPT:
1320 ++user_script_count;
1321 break;
1322 case Extension::TYPE_HOSTED_APP:
1323 ++hosted_app_count;
1324 if (Extension::IsExternalLocation(location)) {
1325 ++app_external_count;
1326 } else {
1327 ++app_user_count;
1328 }
1329 break;
1330 case Extension::TYPE_PACKAGED_APP:
1331 ++packaged_app_count;
1332 if (Extension::IsExternalLocation(location)) {
1333 ++app_external_count;
1334 } else {
1335 ++app_user_count;
1336 }
1337 break;
1338 case Extension::TYPE_EXTENSION:
1339 default:
1340 if (Extension::IsExternalLocation(location)) {
1341 ++extension_external_count;
1342 } else {
1343 ++extension_user_count;
1344 }
1345 break;
1346 }
1347 if ((*ex)->page_action() != NULL)
1348 ++page_action_count;
1349 if ((*ex)->browser_action() != NULL)
1350 ++browser_action_count;
1351
1352 RecordPermissionMessagesHistogram(
1353 ex->get(), "Extensions.Permissions_Load");
1354 }
1355 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadApp",
1356 app_user_count + app_external_count);
1357 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAppUser", app_user_count);
1358 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAppExternal", app_external_count);
1359 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadHostedApp", hosted_app_count);
1360 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPackagedApp", packaged_app_count);
1361 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtension",
1362 extension_user_count + extension_external_count);
1363 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtensionUser",
1364 extension_user_count);
1365 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtensionExternal",
1366 extension_external_count);
1367 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count);
1368 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count);
1369 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count);
1370 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction",
1371 browser_action_count);
1372 }
1373
1374 // static 876 // static
1375 void ExtensionService::RecordPermissionMessagesHistogram( 877 void ExtensionService::RecordPermissionMessagesHistogram(
1376 const Extension* e, const char* histogram) { 878 const Extension* e, const char* histogram) {
1377 // Since this is called from multiple sources, and since the Histogram macros 879 // Since this is called from multiple sources, and since the Histogram macros
1378 // use statics, we need to manually lookup the Histogram ourselves. 880 // use statics, we need to manually lookup the Histogram ourselves.
1379 base::Histogram* counter = base::LinearHistogram::FactoryGet( 881 base::Histogram* counter = base::LinearHistogram::FactoryGet(
1380 histogram, 882 histogram,
1381 1, 883 1,
1382 ExtensionPermissionMessage::kEnumBoundary, 884 ExtensionPermissionMessage::kEnumBoundary,
1383 ExtensionPermissionMessage::kEnumBoundary + 1, 885 ExtensionPermissionMessage::kEnumBoundary + 1,
1384 base::Histogram::kUmaTargetedHistogramFlag); 886 base::Histogram::kUmaTargetedHistogramFlag);
1385 887
1386 ExtensionPermissionMessages permissions = e->GetPermissionMessages(); 888 ExtensionPermissionMessages permissions = e->GetPermissionMessages();
1387 if (permissions.empty()) { 889 if (permissions.empty()) {
1388 counter->Add(ExtensionPermissionMessage::kNone); 890 counter->Add(ExtensionPermissionMessage::kNone);
1389 } else { 891 } else {
1390 for (ExtensionPermissionMessages::iterator it = permissions.begin(); 892 for (ExtensionPermissionMessages::iterator it = permissions.begin();
1391 it != permissions.end(); ++it) 893 it != permissions.end(); ++it)
1392 counter->Add(it->id()); 894 counter->Add(it->id());
1393 } 895 }
1394 } 896 }
1395 897
1396 void ExtensionService::LoadInstalledExtension(const ExtensionInfo& info,
1397 bool write_to_prefs) {
1398 std::string error;
1399 scoped_refptr<const Extension> extension(NULL);
1400 if (!extension_prefs_->IsExtensionAllowedByPolicy(info.extension_id)) {
1401 error = errors::kDisabledByPolicy;
1402 } else if (info.extension_manifest.get()) {
1403 extension = Extension::Create(
1404 info.extension_path,
1405 info.extension_location,
1406 *info.extension_manifest,
1407 GetExtensionCreateFlagsForInstalledExtension(&info),
1408 &error);
1409 } else {
1410 error = errors::kManifestUnreadable;
1411 }
1412
1413 // Once installed, non-unpacked extensions cannot change their IDs (e.g., by
1414 // updating the 'key' field in their manifest).
1415 if (extension &&
1416 extension->location() != Extension::LOAD &&
1417 info.extension_id != extension->id()) {
1418 error = errors::kCannotChangeExtensionID;
1419 extension = NULL;
1420 UserMetrics::RecordAction(UserMetricsAction("Extensions.IDChangedError"));
1421 }
1422
1423 if (!extension) {
1424 ReportExtensionLoadError(info.extension_path, error, false);
1425 return;
1426 }
1427
1428 if (write_to_prefs)
1429 extension_prefs_->UpdateManifest(extension);
1430
1431 AddExtension(extension);
1432 }
1433
1434 int ExtensionService::GetExtensionCreateFlagsForInstalledExtension(
1435 const ExtensionInfo* info) {
1436 int flags = Extension::NO_FLAGS;
1437 if (info->extension_location != Extension::LOAD)
1438 flags |= Extension::REQUIRE_KEY;
1439 if (Extension::ShouldDoStrictErrorChecking(info->extension_location))
1440 flags |= Extension::STRICT_ERROR_CHECKS;
1441 if (extension_prefs_->AllowFileAccess(info->extension_id))
1442 flags |= Extension::ALLOW_FILE_ACCESS;
1443 if (extension_prefs_->IsFromWebStore(info->extension_id))
1444 flags |= Extension::FROM_WEBSTORE;
1445 if (extension_prefs_->IsFromBookmark(info->extension_id))
1446 flags |= Extension::FROM_BOOKMARK;
1447 return flags;
1448 }
1449
1450 void ExtensionService::NotifyExtensionLoaded(const Extension* extension) { 898 void ExtensionService::NotifyExtensionLoaded(const Extension* extension) {
1451 // The ChromeURLRequestContexts need to be first to know that the extension 899 // The ChromeURLRequestContexts need to be first to know that the extension
1452 // was loaded, otherwise a race can arise where a renderer that is created 900 // was loaded, otherwise a race can arise where a renderer that is created
1453 // for the extension may try to load an extension URL with an extension id 901 // for the extension may try to load an extension URL with an extension id
1454 // that the request context doesn't yet know about. The profile is responsible 902 // that the request context doesn't yet know about. The profile is responsible
1455 // for ensuring its URLRequestContexts appropriately discover the loaded 903 // for ensuring its URLRequestContexts appropriately discover the loaded
1456 // extension. 904 // extension.
1457 profile_->RegisterExtensionWithRequestContexts(extension); 905 profile_->RegisterExtensionWithRequestContexts(extension);
1458 906
1459 // Tell subsystems that use the EXTENSION_LOADED notification about the new 907 // Tell subsystems that use the EXTENSION_LOADED notification about the new
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after
2302 terminated_extensions_.clear(); 1750 terminated_extensions_.clear();
2303 extension_runtime_data_.clear(); 1751 extension_runtime_data_.clear();
2304 1752
2305 // TODO(erikkay) should there be a notification for this? We can't use 1753 // TODO(erikkay) should there be a notification for this? We can't use
2306 // EXTENSION_UNLOADED since that implies that the extension has been disabled 1754 // EXTENSION_UNLOADED since that implies that the extension has been disabled
2307 // or uninstalled, and UnloadAll is just part of shutdown. 1755 // or uninstalled, and UnloadAll is just part of shutdown.
2308 } 1756 }
2309 1757
2310 void ExtensionService::ReloadExtensions() { 1758 void ExtensionService::ReloadExtensions() {
2311 UnloadAllExtensions(); 1759 UnloadAllExtensions();
2312 LoadAllExtensions(); 1760 component_loader_->LoadComponentExtensions();
1761 MakeInstalledExtensionLoader()->LoadAllExtensions();
2313 } 1762 }
2314 1763
2315 void ExtensionService::GarbageCollectExtensions() { 1764 void ExtensionService::GarbageCollectExtensions() {
2316 if (extension_prefs_->pref_service()->ReadOnly()) 1765 if (extension_prefs_->pref_service()->ReadOnly())
2317 return; 1766 return;
2318 1767
2319 scoped_ptr<ExtensionPrefs::ExtensionsInfo> info( 1768 scoped_ptr<ExtensionPrefs::ExtensionsInfo> info(
2320 extension_prefs_->GetInstalledExtensionsInfo()); 1769 extension_prefs_->GetInstalledExtensionsInfo());
2321 1770
2322 std::map<std::string, FilePath> extension_paths; 1771 std::map<std::string, FilePath> extension_paths;
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
2508 std::set<std::string> extension_ids; 1957 std::set<std::string> extension_ids;
2509 for (size_t i = 0; i < extensions_.size(); ++i) { 1958 for (size_t i = 0; i < extensions_.size(); ++i) {
2510 if (!extensions_[i]->is_theme() && 1959 if (!extensions_[i]->is_theme() &&
2511 extensions_[i]->location() != Extension::COMPONENT) 1960 extensions_[i]->location() != Extension::COMPONENT)
2512 extension_ids.insert(extensions_[i]->id()); 1961 extension_ids.insert(extensions_[i]->id());
2513 } 1962 }
2514 1963
2515 child_process_logging::SetActiveExtensions(extension_ids); 1964 child_process_logging::SetActiveExtensions(extension_ids);
2516 } 1965 }
2517 1966
2518 void ExtensionService::OnLoadSingleExtension(const Extension* extension,
2519 bool prompt_for_plugins) {
2520 // If this is a new install of an extension with plugins, prompt the user
2521 // first.
2522 if (show_extensions_prompts_ && prompt_for_plugins &&
2523 !extension->plugins().empty() &&
2524 disabled_extension_paths_.find(extension->id()) ==
2525 disabled_extension_paths_.end()) {
2526 SimpleExtensionLoadPrompt* prompt = new SimpleExtensionLoadPrompt(
2527 profile_, weak_ptr_factory_.GetWeakPtr(), extension);
2528 prompt->ShowPrompt();
2529 return; // continues in SimpleExtensionLoadPrompt::InstallUI*
2530 }
2531 OnExtensionInstalled(extension, false, -1); // Not from web store.
2532 }
2533
2534 void ExtensionService::OnExtensionInstalled( 1967 void ExtensionService::OnExtensionInstalled(
2535 const Extension* extension, bool from_webstore, int page_index) { 1968 const Extension* extension, bool from_webstore, int page_index) {
2536 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1969 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2537 1970
2538 // Ensure extension is deleted unless we transfer ownership. 1971 // Ensure extension is deleted unless we transfer ownership.
2539 scoped_refptr<const Extension> scoped_extension(extension); 1972 scoped_refptr<const Extension> scoped_extension(extension);
2540 const std::string& id = extension->id(); 1973 const std::string& id = extension->id();
2541 // Extensions installed by policy can't be disabled. So even if a previous 1974 // Extensions installed by policy can't be disabled. So even if a previous
2542 // installation disabled the extension, make sure it is now enabled. 1975 // installation disabled the extension, make sure it is now enabled.
2543 bool initial_enable = 1976 bool initial_enable =
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
2774 installer->set_expected_version(*version); 2207 installer->set_expected_version(*version);
2775 installer->set_install_cause(extension_misc::INSTALL_CAUSE_EXTERNAL_FILE); 2208 installer->set_install_cause(extension_misc::INSTALL_CAUSE_EXTERNAL_FILE);
2776 installer->set_creation_flags(creation_flags); 2209 installer->set_creation_flags(creation_flags);
2777 installer->InstallCrx(path); 2210 installer->InstallCrx(path);
2778 } 2211 }
2779 2212
2780 void ExtensionService::ReportExtensionLoadError( 2213 void ExtensionService::ReportExtensionLoadError(
2781 const FilePath& extension_path, 2214 const FilePath& extension_path,
2782 const std::string &error, 2215 const std::string &error,
2783 bool be_noisy) { 2216 bool be_noisy) {
2784 content::NotificationService* service = 2217 content::NotificationService::current()->Notify(
2785 content::NotificationService::current(); 2218 chrome::NOTIFICATION_EXTENSION_LOAD_ERROR,
2786 service->Notify(chrome::NOTIFICATION_EXTENSION_LOAD_ERROR, 2219 content::Source<Profile>(profile_),
2787 content::Source<Profile>(profile_), 2220 content::Details<const std::string>(&error));
2788 content::Details<const std::string>(&error));
2789 2221
2790 std::string path_str = UTF16ToUTF8(extension_path.LossyDisplayName()); 2222 std::string path_str = UTF16ToUTF8(extension_path.LossyDisplayName());
2791 std::string message = base::StringPrintf( 2223 std::string message = base::StringPrintf(
2792 "Could not load extension from '%s'. %s", 2224 "Could not load extension from '%s'. %s",
2793 path_str.c_str(), error.c_str()); 2225 path_str.c_str(), error.c_str());
2794 ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy); 2226 ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy);
2795 } 2227 }
2796 2228
2797 void ExtensionService::DidCreateRenderViewForBackgroundPage( 2229 void ExtensionService::DidCreateRenderViewForBackgroundPage(
2798 ExtensionHost* host) { 2230 ExtensionHost* host) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
2902 } 2334 }
2903 2335
2904 return result; 2336 return result;
2905 } 2337 }
2906 2338
2907 scoped_refptr<CrxInstaller> ExtensionService::MakeCrxInstaller( 2339 scoped_refptr<CrxInstaller> ExtensionService::MakeCrxInstaller(
2908 ExtensionInstallUI* client) { 2340 ExtensionInstallUI* client) {
2909 return new CrxInstaller(weak_ptr_factory_.GetWeakPtr(), client); 2341 return new CrxInstaller(weak_ptr_factory_.GetWeakPtr(), client);
2910 } 2342 }
2911 2343
2344 scoped_refptr<UnpackedInstaller> ExtensionService::MakeUnpackedInstaller() {
2345 return new UnpackedInstaller(weak_ptr_factory_.GetWeakPtr());
2346 }
2347
2348 scoped_refptr<InstalledExtensionLoader>
2349 ExtensionService::MakeInstalledExtensionLoader() {
2350 return new InstalledExtensionLoader(this, extension_prefs_);
2351 }
2352
2912 bool ExtensionService::IsBackgroundPageReady(const Extension* extension) { 2353 bool ExtensionService::IsBackgroundPageReady(const Extension* extension) {
2913 return (extension->background_url().is_empty() || 2354 return (extension->background_url().is_empty() ||
2914 extension_runtime_data_[extension->id()].background_page_ready); 2355 extension_runtime_data_[extension->id()].background_page_ready);
2915 } 2356 }
2916 2357
2917 void ExtensionService::SetBackgroundPageReady(const Extension* extension) { 2358 void ExtensionService::SetBackgroundPageReady(const Extension* extension) {
2918 DCHECK(!extension->background_url().is_empty()); 2359 DCHECK(!extension->background_url().is_empty());
2919 extension_runtime_data_[extension->id()].background_page_ready = true; 2360 extension_runtime_data_[extension->id()].background_page_ready = true;
2920 content::NotificationService::current()->Notify( 2361 content::NotificationService::current()->Notify(
2921 chrome::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY, 2362 chrome::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3014 2455
3015 ExtensionService::NaClModuleInfoList::iterator 2456 ExtensionService::NaClModuleInfoList::iterator
3016 ExtensionService::FindNaClModule(const GURL& url) { 2457 ExtensionService::FindNaClModule(const GURL& url) {
3017 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); 2458 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin();
3018 iter != nacl_module_list_.end(); ++iter) { 2459 iter != nacl_module_list_.end(); ++iter) {
3019 if (iter->url == url) 2460 if (iter->url == url)
3020 return iter; 2461 return iter;
3021 } 2462 }
3022 return nacl_module_list_.end(); 2463 return nacl_module_list_.end();
3023 } 2464 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698