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

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

Issue 11150002: New post-sideload UI: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: !!! Created 8 years, 2 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/external_install_ui.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/lazy_instance.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop.h"
14 #include "base/metrics/histogram.h"
15 #include "base/utf_string_conversions.h"
16 #include "chrome/app/chrome_command_ids.h"
17 #include "chrome/browser/extensions/extension_install_prompt.h"
18 #include "chrome/browser/extensions/extension_service.h"
19 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/global_error/global_error.h"
23 #include "chrome/browser/ui/global_error/global_error_service.h"
24 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
25 #include "chrome/common/chrome_notification_types.h"
26 #include "chrome/common/extensions/extension.h"
27 #include "content/public/browser/notification_details.h"
28 #include "content/public/browser/notification_observer.h"
29 #include "content/public/browser/notification_registrar.h"
30 #include "content/public/browser/notification_source.h"
31 #include "grit/chromium_strings.h"
32 #include "grit/generated_resources.h"
33 #include "grit/theme_resources.h"
34 #include "ui/base/l10n/l10n_util.h"
35
36 namespace extensions {
37
38 static const int kMenuCommandId = IDC_EXTERNAL_EXTENSION_ALERT;
39
40 // ExternalInstallDialogDelegate --------------------------------------------
41
42 // TODO(mpcomplete): Get rid of the refcounting on this class, or document
43 // why it's necessary. Will do after refactoring to merge back with
44 // ExtensionDisabledDialogDelegate.
45 class ExternalInstallDialogDelegate
46 : public ExtensionInstallPrompt::Delegate,
47 public base::RefCountedThreadSafe<ExternalInstallDialogDelegate> {
48 public:
49 ExternalInstallDialogDelegate(Browser* browser,
50 ExtensionService* service,
51 const Extension* extension);
52
53 private:
54 friend class base::RefCountedThreadSafe<ExternalInstallDialogDelegate>;
55
56 virtual ~ExternalInstallDialogDelegate();
57
58 // ExtensionInstallPrompt::Delegate:
59 virtual void InstallUIProceed() OVERRIDE;
60 virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
61
62 // The UI for showing the install dialog when enabling.
63 scoped_ptr<ExtensionInstallPrompt> install_ui_;
64
65 ExtensionService* service_;
66 const Extension* extension_;
67 };
68
69 ExternalInstallDialogDelegate::ExternalInstallDialogDelegate(
70 Browser* browser,
71 ExtensionService* service,
72 const Extension* extension)
73 : service_(service), extension_(extension) {
74 AddRef(); // Balanced in Proceed or Abort.
75
76 install_ui_.reset(chrome::CreateExtensionInstallPromptWithBrowser(browser));
77 install_ui_->ConfirmExternalInstall(this, extension_);
78 }
79
80 ExternalInstallDialogDelegate::~ExternalInstallDialogDelegate() {
81 }
82
83 void ExternalInstallDialogDelegate::InstallUIProceed() {
84 service_->GrantPermissionsAndEnableExtension(
85 extension_, install_ui_->record_oauth2_grant());
86 Release();
87 }
88
89 void ExternalInstallDialogDelegate::InstallUIAbort(bool user_initiated) {
90 service_->UninstallExtension(extension_->id(), false, NULL);
91 Release();
92 }
93
94 static void ShowExternalInstallDialog(ExtensionService* service,
95 Browser* browser,
96 const Extension* extension) {
97 // This object manages its own lifetime.
98 new ExternalInstallDialogDelegate(browser, service, extension);
99 }
100
101 // ExternalInstallGlobalError -----------------------------------------------
102
103 class ExternalInstallGlobalError : public GlobalError,
104 public content::NotificationObserver {
105 public:
106 ExternalInstallGlobalError(ExtensionService* service,
107 const Extension* extension);
108 virtual ~ExternalInstallGlobalError();
109
110 const Extension* extension() const { return extension_; }
111
112 // GlobalError implementation.
113 virtual bool HasBadge() OVERRIDE;
114 virtual int GetBadgeResourceID() OVERRIDE;
115 virtual bool HasMenuItem() OVERRIDE;
116 virtual int MenuItemCommandID() OVERRIDE;
117 virtual string16 MenuItemLabel() OVERRIDE;
118 virtual int MenuItemIconResourceID() OVERRIDE;
119 virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
120 virtual bool HasBubbleView() OVERRIDE;
121 virtual string16 GetBubbleViewTitle() OVERRIDE;
122 virtual string16 GetBubbleViewMessage() OVERRIDE;
123 virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
124 virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
125 virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
126 virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
127 virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
128
129 // content::NotificationObserver implementation.
130 virtual void Observe(int type,
131 const content::NotificationSource& source,
132 const content::NotificationDetails& details) OVERRIDE;
133
134 private:
135 ExtensionService* service_;
136 const Extension* extension_;
137
138 // How the user responded to the error; used for metrics.
139 enum UserResponse {
140 IGNORED,
141 REENABLE,
142 UNINSTALL,
143 USER_RESPONSE_BUCKET_BOUNDARY
144 };
145 UserResponse user_response_;
146
147 content::NotificationRegistrar registrar_;
148 };
149
150 ExternalInstallGlobalError::ExternalInstallGlobalError(
151 ExtensionService* service,
152 const Extension* extension)
153 : service_(service),
154 extension_(extension),
155 user_response_(IGNORED) {
156 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
157 content::Source<Profile>(service->profile()));
158 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
159 content::Source<Profile>(service->profile()));
160 }
161
162 ExternalInstallGlobalError::~ExternalInstallGlobalError() {
163 HISTOGRAM_ENUMERATION("Extensions.ExternalInstallUIUserResponse",
164 user_response_, USER_RESPONSE_BUCKET_BOUNDARY);
165 }
166
167 bool ExternalInstallGlobalError::HasBadge() {
168 return true;
169 }
170
171 int ExternalInstallGlobalError::GetBadgeResourceID() {
172 return IDR_UPDATE_BADGE_EXTENSION;
173 }
174
175 bool ExternalInstallGlobalError::HasMenuItem() {
176 return true;
177 }
178
179 int ExternalInstallGlobalError::MenuItemCommandID() {
180 return kMenuCommandId;
181 }
182
183 int ExternalInstallGlobalError::MenuItemIconResourceID() {
184 return IDR_UPDATE_MENU_EXTENSION;
185 }
186
187 string16 ExternalInstallGlobalError::MenuItemLabel() {
188 return l10n_util::GetStringFUTF16(IDS_EXTENSION_EXTERNAL_INSTALL_ALERT,
189 UTF8ToUTF16(extension_->name()));
190 }
191
192 void ExternalInstallGlobalError::ExecuteMenuItem(Browser* browser) {
193 ShowExternalInstallDialog(service_, browser, extension_);
194 }
195
196 bool ExternalInstallGlobalError::HasBubbleView() {
197 return false;
198 }
199
200 string16 ExternalInstallGlobalError::GetBubbleViewTitle() {
201 return string16();
202 }
203
204 string16 ExternalInstallGlobalError::GetBubbleViewMessage() {
205 return string16();
206 }
207
208 string16 ExternalInstallGlobalError::GetBubbleViewAcceptButtonLabel() {
209 return string16();
210 }
211
212 string16 ExternalInstallGlobalError::GetBubbleViewCancelButtonLabel() {
213 return string16();
214 }
215
216 void ExternalInstallGlobalError::OnBubbleViewDidClose(Browser* browser) {
217 NOTREACHED();
218 }
219
220 void ExternalInstallGlobalError::BubbleViewAcceptButtonPressed(
221 Browser* browser) {
222 NOTREACHED();
223 }
224
225 void ExternalInstallGlobalError::BubbleViewCancelButtonPressed(
226 Browser* browser) {
227 NOTREACHED();
228 }
229
230 void ExternalInstallGlobalError::Observe(
231 int type,
232 const content::NotificationSource& source,
233 const content::NotificationDetails& details) {
234 const Extension* extension = NULL;
235 // The error is invalidated if the extension has been reloaded
236 // or unloaded.
237 if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
238 extension = content::Details<const Extension>(details).ptr();
239 } else {
240 DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNLOADED, type);
241 extensions::UnloadedExtensionInfo* info =
242 content::Details<extensions::UnloadedExtensionInfo>(details).ptr();
243 extension = info->extension;
244 }
245 if (extension == extension_) {
246 GlobalErrorService* error_service =
247 GlobalErrorServiceFactory::GetForProfile(service_->profile());
248 error_service->RemoveGlobalError(this);
249
250 // We only check for new external installs on startup, so these
251 // notifications are guaranteed to be user-initiated.
252 if (type == chrome::NOTIFICATION_EXTENSION_LOADED)
253 user_response_ = REENABLE;
254 else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED)
255 user_response_ = UNINSTALL;
256
257 service_->AcknowledgeExternalExtension(extension_->id());
258 delete this;
259 }
260 }
261
262 // Public interface ---------------------------------------------------------
263
264 bool AddExternalInstallError(ExtensionService* service,
265 const Extension* extension) {
266 GlobalErrorService* error_service =
267 GlobalErrorServiceFactory::GetForProfile(service->profile());
268 GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
269 kMenuCommandId);
270 if (error)
271 return false;
272
273 error_service->AddGlobalError(
274 new ExternalInstallGlobalError(service, extension));
275 return true;
276 }
277
278 void RemoveExternalInstallError(ExtensionService* service) {
279 GlobalErrorService* error_service =
280 GlobalErrorServiceFactory::GetForProfile(service->profile());
281 GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
282 kMenuCommandId);
283 if (error) {
284 error_service->RemoveGlobalError(error);
285 delete error;
286 }
287 }
288
289 bool HasExternalInstallError(ExtensionService* service) {
290 GlobalErrorService* error_service =
291 GlobalErrorServiceFactory::GetForProfile(service->profile());
292 GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
293 kMenuCommandId);
294 return !!error;
295 }
296
297 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/external_install_ui.h ('k') | chrome/browser/extensions/pending_extension_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698