| 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;
|
| }
|
|
|
|
|