Index: chrome/browser/extensions/external_install_ui.cc |
diff --git a/chrome/browser/extensions/external_install_ui.cc b/chrome/browser/extensions/external_install_ui.cc |
index d2771943e6da391566e271701d14dd8df5aa8690..efa874844ba1805132e9a436504c60832230f130 100644 |
--- a/chrome/browser/extensions/external_install_ui.cc |
+++ b/chrome/browser/extensions/external_install_ui.cc |
@@ -7,9 +7,11 @@ |
#include <string> |
#include "base/bind.h" |
+#include "base/callback_forward.h" |
#include "base/lazy_instance.h" |
#include "base/memory/ref_counted.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/memory/weak_ptr.h" |
#include "base/message_loop/message_loop.h" |
#include "base/metrics/histogram.h" |
#include "base/strings/utf_string_conversions.h" |
@@ -119,10 +121,15 @@ class ExternalInstallMenuAlert : public GlobalError, |
const content::NotificationSource& source, |
const content::NotificationDetails& details) OVERRIDE; |
+ // Callback to notify UI that extension has been removed. |
+ void HandleExtensionRemoved(const Extension* extension); |
+ |
protected: |
- ExtensionService* service_; |
+ base::WeakPtr<ExtensionService> service_weak_; |
const Extension* extension_; |
content::NotificationRegistrar registrar_; |
+ base::WeakPtrFactory<ExternalInstallMenuAlert> weak_factory_; |
+ base::Callback<void(const Extension*)> on_removed_callback_; |
}; |
// Shows a menu item and a global error bubble, replacing the install dialog. |
@@ -240,15 +247,21 @@ void ExternalInstallDialogDelegate::InstallUIAbort(bool user_initiated) { |
ExternalInstallMenuAlert::ExternalInstallMenuAlert( |
ExtensionService* service, |
const Extension* extension) |
- : service_(service), |
- extension_(extension) { |
+ : service_weak_(service->AsWeakPtr()), |
+ extension_(extension), |
+ weak_factory_(this) { |
+ on_removed_callback_ = base::Bind( |
+ &ExternalInstallMenuAlert::HandleExtensionRemoved, |
+ weak_factory_.GetWeakPtr()); |
+ if (service_weak_.get()) |
+ service_weak_->RegisterExtensionRemovedCallback(on_removed_callback_); |
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
content::Source<Profile>(service->profile())); |
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_REMOVED, |
- content::Source<Profile>(service->profile())); |
} |
ExternalInstallMenuAlert::~ExternalInstallMenuAlert() { |
+ if (service_weak_.get()) |
+ service_weak_->RemoveExtensionRemovedCallback(on_removed_callback_); |
} |
GlobalError::Severity ExternalInstallMenuAlert::GetSeverity() { |
@@ -275,7 +288,7 @@ string16 ExternalInstallMenuAlert::MenuItemLabel() { |
} |
void ExternalInstallMenuAlert::ExecuteMenuItem(Browser* browser) { |
- ShowExternalInstallDialog(service_, browser, extension_); |
+ ShowExternalInstallDialog(service_weak_.get(), browser, extension_); |
} |
bool ExternalInstallMenuAlert::HasBubbleView() { |
@@ -316,15 +329,29 @@ void ExternalInstallMenuAlert::Observe( |
const content::NotificationSource& source, |
const content::NotificationDetails& details) { |
// The error is invalidated if the extension has been loaded or removed. |
- DCHECK(type == chrome::NOTIFICATION_EXTENSION_LOADED || |
- type == chrome::NOTIFICATION_EXTENSION_REMOVED); |
+ DCHECK(type == chrome::NOTIFICATION_EXTENSION_LOADED); |
const Extension* extension = content::Details<const Extension>(details).ptr(); |
if (extension != extension_) |
return; |
- GlobalErrorService* error_service = |
- GlobalErrorServiceFactory::GetForProfile(service_->profile()); |
- error_service->RemoveGlobalError(this); |
- service_->AcknowledgeExternalExtension(extension_->id()); |
+ if (service_weak_.get()) { |
+ GlobalErrorService* error_service = |
+ GlobalErrorServiceFactory::GetForProfile(service_weak_->profile()); |
+ error_service->RemoveGlobalError(this); |
+ service_weak_->AcknowledgeExternalExtension(extension_->id()); |
+ } |
+ delete this; |
+} |
+ |
+void ExternalInstallMenuAlert::HandleExtensionRemoved( |
+ const Extension* extension) { |
+ if (extension != extension_) |
+ return; |
+ if (service_weak_.get()) { |
+ GlobalErrorService* error_service = |
+ GlobalErrorServiceFactory::GetForProfile(service_weak_->profile()); |
+ error_service->RemoveGlobalError(this); |
+ service_weak_->AcknowledgeExternalExtension(extension_->id()); |
+ } |
delete this; |
} |