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