OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/extensions_service.h" | 5 #include "chrome/browser/extensions/extensions_service.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/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 int update_frequency = kDefaultUpdateFrequencySeconds; | 100 int update_frequency = kDefaultUpdateFrequencySeconds; |
101 if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) { | 101 if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) { |
102 update_frequency = StringToInt(WideToASCII(command_line->GetSwitchValue( | 102 update_frequency = StringToInt(WideToASCII(command_line->GetSwitchValue( |
103 switches::kExtensionsUpdateFrequency))); | 103 switches::kExtensionsUpdateFrequency))); |
104 } | 104 } |
105 updater_ = new ExtensionUpdater(this, prefs, update_frequency, | 105 updater_ = new ExtensionUpdater(this, prefs, update_frequency, |
106 backend_loop_, ChromeThread::GetMessageLoop(ChromeThread::IO)); | 106 backend_loop_, ChromeThread::GetMessageLoop(ChromeThread::IO)); |
107 } | 107 } |
108 | 108 |
109 backend_ = new ExtensionsServiceBackend(install_directory_, frontend_loop); | 109 backend_ = new ExtensionsServiceBackend(install_directory_, frontend_loop); |
| 110 |
| 111 registrar_.Add(this, NotificationType::EXTENSION_PROCESS_CRASHED, |
| 112 Source<ExtensionsService>(this)); |
110 } | 113 } |
111 | 114 |
112 ExtensionsService::~ExtensionsService() { | 115 ExtensionsService::~ExtensionsService() { |
113 UnloadAllExtensions(); | 116 UnloadAllExtensions(); |
114 if (updater_.get()) { | 117 if (updater_.get()) { |
115 updater_->Stop(); | 118 updater_->Stop(); |
116 } | 119 } |
117 } | 120 } |
118 | 121 |
119 void ExtensionsService::Init() { | 122 void ExtensionsService::Init() { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 | 155 |
153 CrxInstaller::Start(extension_path, install_directory_, Extension::INTERNAL, | 156 CrxInstaller::Start(extension_path, install_directory_, Extension::INTERNAL, |
154 id, | 157 id, |
155 true, // delete crx when complete | 158 true, // delete crx when complete |
156 backend_loop_, | 159 backend_loop_, |
157 this, | 160 this, |
158 NULL); // no client (silent install) | 161 NULL); // no client (silent install) |
159 } | 162 } |
160 | 163 |
161 void ExtensionsService::ReloadExtension(const std::string& extension_id) { | 164 void ExtensionsService::ReloadExtension(const std::string& extension_id) { |
162 Extension* extension = GetExtensionById(extension_id); | 165 // Unload the extension if it's loaded. |
163 FilePath extension_path = extension->path(); | 166 if (GetExtensionById(extension_id)) |
| 167 UnloadExtension(extension_id); |
164 | 168 |
165 UnloadExtension(extension_id); | 169 // At this point we have to reconstruct the path from prefs, because |
166 LoadExtension(extension_path); | 170 // we have no information about this extension in memory. |
| 171 LoadExtension(extension_prefs_->GetExtensionPath(extension_id)); |
167 } | 172 } |
168 | 173 |
169 void ExtensionsService::UninstallExtension(const std::string& extension_id, | 174 void ExtensionsService::UninstallExtension(const std::string& extension_id, |
170 bool external_uninstall) { | 175 bool external_uninstall) { |
171 Extension* extension = GetExtensionByIdInternal(extension_id, true, true); | 176 Extension* extension = GetExtensionByIdInternal(extension_id, true, true); |
172 | 177 |
173 // Callers should not send us nonexistant extensions. | 178 // Callers should not send us nonexistant extensions. |
174 DCHECK(extension); | 179 DCHECK(extension); |
175 | 180 |
176 extension_prefs_->OnExtensionUninstalled(extension, external_uninstall); | 181 extension_prefs_->OnExtensionUninstalled(extension, external_uninstall); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 } | 507 } |
503 } | 508 } |
504 | 509 |
505 CrxInstaller::Start(path, install_directory_, location, id, | 510 CrxInstaller::Start(path, install_directory_, location, id, |
506 false, // don't delete crx when complete | 511 false, // don't delete crx when complete |
507 backend_loop_, | 512 backend_loop_, |
508 this, | 513 this, |
509 NULL); // no client (silent install) | 514 NULL); // no client (silent install) |
510 } | 515 } |
511 | 516 |
| 517 void ExtensionsService::Observe(NotificationType type, |
| 518 const NotificationSource& source, |
| 519 const NotificationDetails& details) { |
| 520 switch (type.value) { |
| 521 case NotificationType::EXTENSION_PROCESS_CRASHED: { |
| 522 DCHECK_EQ(this, Source<ExtensionsService>(source).ptr()); |
| 523 ExtensionHost* host = Details<ExtensionHost>(details).ptr(); |
| 524 |
| 525 // Unload the entire extension to make sure its state is consistent |
| 526 // (either fully operational, or fully unloaded, but not half-crashed). |
| 527 UnloadExtension(host->extension()->id()); |
| 528 } |
| 529 break; |
| 530 |
| 531 default: |
| 532 NOTREACHED(); |
| 533 } |
| 534 } |
| 535 |
512 | 536 |
513 // ExtensionsServicesBackend | 537 // ExtensionsServicesBackend |
514 | 538 |
515 ExtensionsServiceBackend::ExtensionsServiceBackend( | 539 ExtensionsServiceBackend::ExtensionsServiceBackend( |
516 const FilePath& install_directory, MessageLoop* frontend_loop) | 540 const FilePath& install_directory, MessageLoop* frontend_loop) |
517 : frontend_(NULL), | 541 : frontend_(NULL), |
518 install_directory_(install_directory), | 542 install_directory_(install_directory), |
519 alert_on_error_(false), | 543 alert_on_error_(false), |
520 frontend_loop_(frontend_loop) { | 544 frontend_loop_(frontend_loop) { |
521 // TODO(aa): This ends up doing blocking IO on the UI thread because it reads | 545 // TODO(aa): This ends up doing blocking IO on the UI thread because it reads |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 linked_ptr<ExternalExtensionProvider>(test_provider); | 732 linked_ptr<ExternalExtensionProvider>(test_provider); |
709 } | 733 } |
710 | 734 |
711 void ExtensionsServiceBackend::OnExternalExtensionFound( | 735 void ExtensionsServiceBackend::OnExternalExtensionFound( |
712 const std::string& id, const Version* version, const FilePath& path, | 736 const std::string& id, const Version* version, const FilePath& path, |
713 Extension::Location location) { | 737 Extension::Location location) { |
714 frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(frontend_, | 738 frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(frontend_, |
715 &ExtensionsService::OnExternalExtensionFound, id, version->GetString(), | 739 &ExtensionsService::OnExternalExtensionFound, id, version->GetString(), |
716 path, location)); | 740 path, location)); |
717 } | 741 } |
OLD | NEW |