Index: chrome/browser/extensions/extension_disabled_ui.cc |
diff --git a/chrome/browser/extensions/extension_disabled_ui.cc b/chrome/browser/extensions/extension_disabled_ui.cc |
index 42767a1bf1f50f90fb4f771d9bf01f22a57dbf10..f3e145f7dd416ffdcfb6a4d27851febef439afe2 100644 |
--- a/chrome/browser/extensions/extension_disabled_ui.cc |
+++ b/chrome/browser/extensions/extension_disabled_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" |
@@ -168,8 +170,11 @@ class ExtensionDisabledGlobalError : 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); |
+ |
private: |
- ExtensionService* service_; |
+ base::WeakPtr<ExtensionService> service_weak_; |
const Extension* extension_; |
gfx::Image icon_; |
@@ -188,6 +193,8 @@ class ExtensionDisabledGlobalError : public GlobalError, |
int menu_command_id_; |
content::NotificationRegistrar registrar_; |
+ base::WeakPtrFactory<ExtensionDisabledGlobalError> weak_factory_; |
+ base::Callback<void(const Extension*)> on_removed_callback_; |
}; |
// TODO(yoz): create error at startup for disabled extensions. |
@@ -195,11 +202,12 @@ ExtensionDisabledGlobalError::ExtensionDisabledGlobalError( |
ExtensionService* service, |
const Extension* extension, |
const gfx::Image& icon) |
- : service_(service), |
+ : service_weak_(service->AsWeakPtr()), |
extension_(extension), |
icon_(icon), |
user_response_(IGNORED), |
- menu_command_id_(GetMenuCommandID()) { |
+ menu_command_id_(GetMenuCommandID()), |
+ weak_factory_(this) { |
if (icon_.IsEmpty()) { |
icon_ = gfx::Image( |
gfx::ImageSkiaOperations::CreateResizedImage( |
@@ -211,11 +219,18 @@ ExtensionDisabledGlobalError::ExtensionDisabledGlobalError( |
} |
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
content::Source<Profile>(service->profile())); |
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_REMOVED, |
- content::Source<Profile>(service->profile())); |
+ if (service_weak_.get()) { |
+ on_removed_callback_ = base::Bind( |
+ &ExtensionDisabledGlobalError::HandleExtensionRemoved, |
+ weak_factory_.GetWeakPtr()); |
+ service_weak_->RegisterExtensionRemovedCallback(on_removed_callback_); |
+ } |
+ |
} |
ExtensionDisabledGlobalError::~ExtensionDisabledGlobalError() { |
+ if (service_weak_.get()) |
+ service_weak_->RemoveExtensionRemovedCallback(on_removed_callback_); |
ReleaseMenuCommandID(menu_command_id_); |
UMA_HISTOGRAM_ENUMERATION("Extensions.DisabledUIUserResponse", |
user_response_, |
@@ -290,14 +305,14 @@ void ExtensionDisabledGlobalError::BubbleViewAcceptButtonPressed( |
// Delay extension reenabling so this bubble closes properly. |
base::MessageLoop::current()->PostTask(FROM_HERE, |
base::Bind(&ExtensionService::GrantPermissionsAndEnableExtension, |
- service_->AsWeakPtr(), extension_)); |
+ service_weak_, extension_)); |
} |
void ExtensionDisabledGlobalError::BubbleViewCancelButtonPressed( |
Browser* browser) { |
#if !defined(OS_ANDROID) |
- uninstall_dialog_.reset( |
- ExtensionUninstallDialog::Create(service_->profile(), browser, this)); |
+ uninstall_dialog_.reset(ExtensionUninstallDialog::Create( |
+ service_weak_->profile(), browser, this)); |
// Delay showing the uninstall dialog, so that this function returns |
// immediately, to close the bubble properly. See crbug.com/121544. |
base::MessageLoop::current()->PostTask(FROM_HERE, |
@@ -307,7 +322,8 @@ void ExtensionDisabledGlobalError::BubbleViewCancelButtonPressed( |
} |
void ExtensionDisabledGlobalError::ExtensionUninstallAccepted() { |
- service_->UninstallExtension(extension_->id(), false, NULL); |
+ if (service_weak_.get()) |
+ service_weak_->UninstallExtension(extension_->id(), false, NULL); |
} |
void ExtensionDisabledGlobalError::ExtensionUninstallCanceled() { |
@@ -319,18 +335,27 @@ void ExtensionDisabledGlobalError::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; |
- GlobalErrorServiceFactory::GetForProfile(service_->profile())-> |
- RemoveGlobalError(this); |
+ if (service_weak_.get()) { |
+ GlobalErrorServiceFactory::GetForProfile(service_weak_->profile())-> |
+ RemoveGlobalError(this); |
+ } |
+ user_response_ = REENABLE; |
+ delete this; |
+} |
- if (type == chrome::NOTIFICATION_EXTENSION_LOADED) |
- user_response_ = REENABLE; |
- else if (type == chrome::NOTIFICATION_EXTENSION_REMOVED) |
- user_response_ = UNINSTALL; |
+void ExtensionDisabledGlobalError::HandleExtensionRemoved( |
+ const Extension* extension) { |
+ if (extension != extension_) |
+ return; |
+ if (service_weak_.get()) { |
+ GlobalErrorServiceFactory::GetForProfile(service_weak_->profile())-> |
+ RemoveGlobalError(this); |
+ } |
+ user_response_ = UNINSTALL; |
delete this; |
} |