Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: chrome/browser/extensions/extension_disabled_ui.cc

Issue 9718008: Replace extension disabled infobar with a global error. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: moar Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/extension_disabled_ui.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/lazy_instance.h"
11 #include "base/message_loop.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/utf_string_conversions.h"
15 #include "chrome/app/chrome_command_ids.h"
16 #include "chrome/browser/extensions/extension_install_ui.h"
17 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/global_error.h"
22 #include "chrome/browser/ui/global_error_service.h"
23 #include "chrome/browser/ui/global_error_service_factory.h"
24 #include "chrome/common/chrome_notification_types.h"
25 #include "chrome/common/extensions/extension.h"
26 #include "content/public/browser/notification_details.h"
27 #include "content/public/browser/notification_observer.h"
28 #include "content/public/browser/notification_registrar.h"
29 #include "content/public/browser/notification_source.h"
30 #include "grit/chromium_strings.h"
31 #include "grit/generated_resources.h"
32 #include "ui/base/l10n/l10n_util.h"
33
34 namespace {
35
36 static base::LazyInstance<
37 std::bitset<IDC_EXTENSION_DISABLED_LAST -
38 IDC_EXTENSION_DISABLED_FIRST + 1> >
39 menu_command_ids = LAZY_INSTANCE_INITIALIZER;
40
41 // Get an available menu ID.
42 int GetMenuCommandID() {
43 int id;
44 for (id = IDC_EXTENSION_DISABLED_FIRST;
45 id <= IDC_EXTENSION_DISABLED_LAST; ++id) {
46 if (!menu_command_ids.Get()[id - IDC_EXTENSION_DISABLED_FIRST]) {
47 menu_command_ids.Get().set(id - IDC_EXTENSION_DISABLED_FIRST);
48 return id;
49 }
50 }
51 // This should not happen.
52 DCHECK(id <= IDC_EXTENSION_DISABLED_LAST) <<
53 "No available menu command IDs for ExtensionDisabledGlobalError";
54 return IDC_EXTENSION_DISABLED_LAST;
55 }
56
57 // Make a menu ID available when it is no longer used.
58 void ReleaseMenuCommandID(int id) {
59 menu_command_ids.Get().reset(id - IDC_EXTENSION_DISABLED_FIRST);
60 }
61
62 } // namespace
63
64 // ExtensionDisabledDialogDelegate --------------------------------------------
65
66 class ExtensionDisabledDialogDelegate
67 : public ExtensionInstallUI::Delegate,
68 public base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate> {
69 public:
70 ExtensionDisabledDialogDelegate(Profile* profile,
71 ExtensionService* service,
72 const Extension* extension);
73
74 private:
75 friend class base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate>;
76
77 virtual ~ExtensionDisabledDialogDelegate();
78
79 // ExtensionInstallUI::Delegate:
80 virtual void InstallUIProceed() OVERRIDE;
81 virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
82
83 // The UI for showing the install dialog when enabling.
84 scoped_ptr<ExtensionInstallUI> install_ui_;
85
86 ExtensionService* service_;
87 const Extension* extension_;
88 };
89
90 ExtensionDisabledDialogDelegate::ExtensionDisabledDialogDelegate(
91 Profile* profile,
92 ExtensionService* service,
93 const Extension* extension)
94 : service_(service), extension_(extension) {
95 AddRef(); // Balanced in Proceed or Abort.
96
97 install_ui_.reset(new ExtensionInstallUI(profile));
98 install_ui_->ConfirmReEnable(this, extension_);
99 }
100
101 ExtensionDisabledDialogDelegate::~ExtensionDisabledDialogDelegate() {
102 }
103
104 void ExtensionDisabledDialogDelegate::InstallUIProceed() {
105 service_->GrantPermissionsAndEnableExtension(extension_);
106 Release();
107 }
108
109 void ExtensionDisabledDialogDelegate::InstallUIAbort(bool user_initiated) {
110 std::string histogram_name = user_initiated ?
111 "Extensions.Permissions_ReEnableCancel" :
112 "Extensions.Permissions_ReEnableAbort";
113 ExtensionService::RecordPermissionMessagesHistogram(
114 extension_, histogram_name.c_str());
115
116 // Do nothing. The extension will remain disabled.
117 Release();
118 }
119
120 // ExtensionDisabledGlobalError -----------------------------------------------
121
122 class ExtensionDisabledGlobalError : public GlobalError,
123 public content::NotificationObserver,
124 public ExtensionUninstallDialog::Delegate {
125 public:
126 ExtensionDisabledGlobalError(ExtensionService* service,
127 const Extension* extension);
128 virtual ~ExtensionDisabledGlobalError();
129
130 // GlobalError implementation.
131 virtual bool HasBadge() OVERRIDE;
132 virtual bool HasMenuItem() OVERRIDE;
133 virtual int MenuItemCommandID() OVERRIDE;
134 virtual string16 MenuItemLabel() OVERRIDE;
135 virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
136 virtual bool HasBubbleView() OVERRIDE;
137 virtual string16 GetBubbleViewTitle() OVERRIDE;
138 virtual string16 GetBubbleViewMessage() OVERRIDE;
139 virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
140 virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
141 virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
142 virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
143 virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
144
145 // ExtensionUninstallDialog::Delegate implementation.
146 virtual void ExtensionUninstallAccepted() OVERRIDE;
147 virtual void ExtensionUninstallCanceled() OVERRIDE;
148
149 // content::NotificationObserver implementation.
150 virtual void Observe(int type,
151 const content::NotificationSource& source,
152 const content::NotificationDetails& details) OVERRIDE;
153
154 private:
155 ExtensionService* service_;
156 const Extension* extension_;
157
158 scoped_ptr<ExtensionUninstallDialog> uninstall_dialog_;
159
160 // Menu command ID assigned for this extension's error.
161 int menu_command_id_;
162
163 content::NotificationRegistrar registrar_;
164 };
165
166 // TODO(yoz): create error at startup for disabled extensions.
167 ExtensionDisabledGlobalError::ExtensionDisabledGlobalError(
168 ExtensionService* service,
169 const Extension* extension)
170 : service_(service),
171 extension_(extension),
172 menu_command_id_(GetMenuCommandID()) {
173 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
174 content::Source<Profile>(service->profile()));
175 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
176 content::Source<Profile>(service->profile()));
177 }
178
179 ExtensionDisabledGlobalError::~ExtensionDisabledGlobalError() {
180 }
181
182 bool ExtensionDisabledGlobalError::HasBadge() {
183 return true;
184 }
185
186 bool ExtensionDisabledGlobalError::HasMenuItem() {
187 return true;
188 }
189
190 int ExtensionDisabledGlobalError::MenuItemCommandID() {
191 return menu_command_id_;
192 }
193
194 string16 ExtensionDisabledGlobalError::MenuItemLabel() {
195 return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
196 UTF8ToUTF16(extension_->name()));
197 }
198
199 void ExtensionDisabledGlobalError::ExecuteMenuItem(Browser* browser) {
200 ShowBubbleView(browser);
201 }
202
203 bool ExtensionDisabledGlobalError::HasBubbleView() {
204 return true;
205 }
206
207 string16 ExtensionDisabledGlobalError::GetBubbleViewTitle() {
208 return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
209 UTF8ToUTF16(extension_->name()));
210 }
211
212 string16 ExtensionDisabledGlobalError::GetBubbleViewMessage() {
213 return l10n_util::GetStringFUTF16(extension_->is_app() ?
214 IDS_APP_DISABLED_ERROR_LABEL : IDS_EXTENSION_DISABLED_ERROR_LABEL,
215 UTF8ToUTF16(extension_->name()));
216 }
217
218 string16 ExtensionDisabledGlobalError::GetBubbleViewAcceptButtonLabel() {
219 return l10n_util::GetStringUTF16(
220 IDS_EXTENSION_DISABLED_ERROR_ENABLE_BUTTON);
221 }
222
223 string16 ExtensionDisabledGlobalError::GetBubbleViewCancelButtonLabel() {
224 return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL);
225 }
226
227 void ExtensionDisabledGlobalError::OnBubbleViewDidClose(Browser* browser) {
228 }
229
230 void ExtensionDisabledGlobalError::BubbleViewAcceptButtonPressed(
231 Browser* browser) {
232 new ExtensionDisabledDialogDelegate(service_->profile(), service_,
233 extension_);
234 }
235
236 void ExtensionDisabledGlobalError::BubbleViewCancelButtonPressed(
237 Browser* browser) {
238 uninstall_dialog_.reset(
239 ExtensionUninstallDialog::Create(service_->profile(), this));
240 uninstall_dialog_->ConfirmUninstall(extension_);
241 }
242
243 void ExtensionDisabledGlobalError::ExtensionUninstallAccepted() {
244 service_->UninstallExtension(extension_->id(), false, NULL);
245 }
246
247 void ExtensionDisabledGlobalError::ExtensionUninstallCanceled() {
248 // Nothing happens, and the error is still there.
249 }
250
251 void ExtensionDisabledGlobalError::Observe(
252 int type,
253 const content::NotificationSource& source,
254 const content::NotificationDetails& details) {
255 const Extension* extension = NULL;
256 // The error is invalidated if the extension has been reloaded
257 // or unloaded.
258 if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
259 extension = content::Details<const Extension>(details).ptr();
260 } else {
261 DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNLOADED, type);
262 UnloadedExtensionInfo* info =
263 content::Details<UnloadedExtensionInfo>(details).ptr();
264 extension = info->extension;
265 }
266 if (extension == extension_) {
267 GlobalErrorServiceFactory::GetForProfile(service_->profile())->
268 RemoveGlobalError(this);
269 ReleaseMenuCommandID(menu_command_id_);
270 delete this;
271 }
272 }
273
274 // Globals --------------------------------------------------------------------
275
276 namespace extensions {
277
278 void ShowExtensionDisabledUI(ExtensionService* service,
279 Profile* profile,
280 const Extension* extension) {
281 GlobalErrorServiceFactory::GetForProfile(service->profile())->
282 AddGlobalError(new ExtensionDisabledGlobalError(service, extension));
283 }
284
285 void ShowExtensionDisabledDialog(ExtensionService* service, Profile* profile,
286 const Extension* extension) {
287 // This object manages its own lifetime.
288 new ExtensionDisabledDialogDelegate(profile, service, extension);
289 }
290
291 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_disabled_ui.h ('k') | chrome/browser/extensions/extension_disabled_ui_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698