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

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

Issue 300853008: Refactor external_install_ui (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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 2014 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_error.h"
6
7 #include "base/bind.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/extensions/extension_install_ui.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/external_install_manager.h"
13 #include "chrome/browser/extensions/webstore_data_fetcher.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_finder.h"
17 #include "chrome/browser/ui/global_error/global_error.h"
18 #include "chrome/browser/ui/global_error/global_error_service.h"
19 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
20 #include "extensions/browser/extension_registry.h"
21 #include "extensions/browser/extension_system.h"
22 #include "extensions/common/extension.h"
23 #include "grit/generated_resources.h"
24 #include "ui/base/l10n/l10n_util.h"
25 #include "ui/gfx/image/image.h"
26 #include "ui/gfx/image/image_skia_operations.h"
27
28 namespace extensions {
29
30 namespace {
31
32 // Return the menu label for a global error.
33 base::string16 GetMenuItemLabel(const Extension* extension) {
34 if (!extension)
35 return base::string16();
36
37 int id = -1;
38 if (extension->is_app())
39 id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_APP;
40 else if (extension->is_theme())
41 id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_THEME;
42 else
43 id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_EXTENSION;
44
45 return l10n_util::GetStringFUTF16(id, base::UTF8ToUTF16(extension->name()));
46 }
47
48 // A global error that spawns a dialog when the menu item is clicked.
49 class ExternalInstallMenuAlert : public GlobalError {
50 public:
51 explicit ExternalInstallMenuAlert(ExternalInstallError* error);
52 virtual ~ExternalInstallMenuAlert();
53
54 private:
55 // GlobalError implementation.
56 virtual Severity GetSeverity() OVERRIDE;
57 virtual bool HasMenuItem() OVERRIDE;
58 virtual int MenuItemCommandID() OVERRIDE;
59 virtual base::string16 MenuItemLabel() OVERRIDE;
60 virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
61 virtual bool HasBubbleView() OVERRIDE;
62 virtual bool HasShownBubbleView() OVERRIDE;
63 virtual void ShowBubbleView(Browser* browser) OVERRIDE;
64 virtual GlobalErrorBubbleViewBase* GetBubbleView() OVERRIDE;
65
66 // The owning ExternalInstallError.
67 ExternalInstallError* error_;
68
69 DISALLOW_COPY_AND_ASSIGN(ExternalInstallMenuAlert);
70 };
71
72 // A global error that spawns a bubble when the menu item is clicked.
73 class ExternalInstallBubbleAlert : public GlobalErrorWithStandardBubble {
74 public:
75 explicit ExternalInstallBubbleAlert(ExternalInstallError* error,
76 ExtensionInstallPrompt::Prompt* prompt);
77 virtual ~ExternalInstallBubbleAlert();
78
79 private:
80 // GlobalError implementation.
81 virtual Severity GetSeverity() OVERRIDE;
82 virtual bool HasMenuItem() OVERRIDE;
83 virtual int MenuItemCommandID() OVERRIDE;
84 virtual base::string16 MenuItemLabel() OVERRIDE;
85 virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
86
87 // GlobalErrorWithStandardBubble implementation.
88 virtual gfx::Image GetBubbleViewIcon() OVERRIDE;
89 virtual base::string16 GetBubbleViewTitle() OVERRIDE;
90 virtual std::vector<base::string16> GetBubbleViewMessages() OVERRIDE;
91 virtual base::string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
92 virtual base::string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
93 virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
94 virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
95 virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
96
97 // The owning ExternalInstallError.
98 ExternalInstallError* error_;
99
100 // The Prompt with all information, which we then use to populate the bubble.
101 ExtensionInstallPrompt::Prompt* prompt_;
102
103 DISALLOW_COPY_AND_ASSIGN(ExternalInstallBubbleAlert);
104 };
105
106 ////////////////////////////////////////////////////////////////////////////////
107 // ExternalInstallMenuAlert
108
109 ExternalInstallMenuAlert::ExternalInstallMenuAlert(ExternalInstallError* error)
110 : error_(error) {
111 }
112
113 ExternalInstallMenuAlert::~ExternalInstallMenuAlert() {
114 }
115
116 GlobalError::Severity ExternalInstallMenuAlert::GetSeverity() {
117 return SEVERITY_LOW;
118 }
119
120 bool ExternalInstallMenuAlert::HasMenuItem() {
121 return true;
122 }
123
124 int ExternalInstallMenuAlert::MenuItemCommandID() {
125 return IDC_EXTERNAL_EXTENSION_ALERT;
126 }
127
128 base::string16 ExternalInstallMenuAlert::MenuItemLabel() {
129 return GetMenuItemLabel(error_->GetExtension());
130 }
131
132 void ExternalInstallMenuAlert::ExecuteMenuItem(Browser* browser) {
133 error_->ShowDialog();
134 }
135
136 bool ExternalInstallMenuAlert::HasBubbleView() {
137 return false;
138 }
139
140 bool ExternalInstallMenuAlert::HasShownBubbleView() {
141 NOTREACHED();
142 return true;
143 }
144
145 void ExternalInstallMenuAlert::ShowBubbleView(Browser* browser) {
146 NOTREACHED();
147 }
148
149 GlobalErrorBubbleViewBase* ExternalInstallMenuAlert::GetBubbleView() {
150 return NULL;
151 }
152
153 ////////////////////////////////////////////////////////////////////////////////
154 // ExternalInstallBubbleAlert
155
156 ExternalInstallBubbleAlert::ExternalInstallBubbleAlert(
157 ExternalInstallError* error,
158 ExtensionInstallPrompt::Prompt* prompt)
159 : error_(error),
160 prompt_(prompt) {
161 DCHECK(error_);
162 DCHECK(prompt_);
163 }
164
165 ExternalInstallBubbleAlert::~ExternalInstallBubbleAlert() {
166 }
167
168 GlobalError::Severity ExternalInstallBubbleAlert::GetSeverity() {
169 return SEVERITY_LOW;
170 }
171
172 bool ExternalInstallBubbleAlert::HasMenuItem() {
173 return true;
174 }
175
176 int ExternalInstallBubbleAlert::MenuItemCommandID() {
177 return IDC_EXTERNAL_EXTENSION_ALERT;
178 }
179
180 base::string16 ExternalInstallBubbleAlert::MenuItemLabel() {
181 return GetMenuItemLabel(error_->GetExtension());
182 }
183
184 void ExternalInstallBubbleAlert::ExecuteMenuItem(Browser* browser) {
185 ShowBubbleView(browser);
186 }
187
188 gfx::Image ExternalInstallBubbleAlert::GetBubbleViewIcon() {
189 if (prompt_->icon().IsEmpty())
190 return GlobalErrorWithStandardBubble::GetBubbleViewIcon();
191 // Scale icon to a reasonable size.
192 return gfx::Image(gfx::ImageSkiaOperations::CreateResizedImage(
193 *prompt_->icon().ToImageSkia(),
194 skia::ImageOperations::RESIZE_BEST,
195 gfx::Size(extension_misc::EXTENSION_ICON_SMALL,
196 extension_misc::EXTENSION_ICON_SMALL)));
197 }
198
199 base::string16 ExternalInstallBubbleAlert::GetBubbleViewTitle() {
200 return prompt_->GetDialogTitle();
201 }
202
203 std::vector<base::string16>
204 ExternalInstallBubbleAlert::GetBubbleViewMessages() {
205 std::vector<base::string16> messages;
206 messages.push_back(prompt_->GetHeading());
207 if (prompt_->GetPermissionCount()) {
208 messages.push_back(prompt_->GetPermissionsHeading());
209 for (size_t i = 0; i < prompt_->GetPermissionCount(); ++i) {
210 messages.push_back(l10n_util::GetStringFUTF16(
211 IDS_EXTENSION_PERMISSION_LINE, prompt_->GetPermission(i)));
212 }
213 }
214 // TODO(yoz): OAuth issue advice?
215 return messages;
216 }
217
218 base::string16 ExternalInstallBubbleAlert::GetBubbleViewAcceptButtonLabel() {
219 return prompt_->GetAcceptButtonLabel();
220 }
221
222 base::string16 ExternalInstallBubbleAlert::GetBubbleViewCancelButtonLabel() {
223 return prompt_->GetAbortButtonLabel();
224 }
225
226 void ExternalInstallBubbleAlert::OnBubbleViewDidClose(Browser* browser) {
227 }
228
229 void ExternalInstallBubbleAlert::BubbleViewAcceptButtonPressed(
230 Browser* browser) {
231 error_->InstallUIProceed();
232 }
233
234 void ExternalInstallBubbleAlert::BubbleViewCancelButtonPressed(
235 Browser* browser) {
236 error_->InstallUIAbort(true);
237 }
238
239 } // namespace
240
241 ////////////////////////////////////////////////////////////////////////////////
242 // ExternalInstallError
243
244 ExternalInstallError::ExternalInstallError(
245 content::BrowserContext* browser_context,
246 const std::string& extension_id,
247 AlertType alert_type,
248 ExternalInstallManager* manager)
249 : browser_context_(browser_context),
250 extension_id_(extension_id),
251 alert_type_(alert_type),
252 manager_(manager),
253 error_service_(GlobalErrorServiceFactory::GetForProfile(
254 Profile::FromBrowserContext(browser_context_))),
255 browser_(NULL),
256 weak_factory_(this) {
257 #if !defined(OS_ANDROID)
258 browser_ =
259 chrome::FindTabbedBrowser(Profile::FromBrowserContext(browser_context_),
260 true,
261 chrome::GetActiveDesktop());
262 #endif
263
264 prompt_.reset(new ExtensionInstallPrompt::Prompt(
265 ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT));
266
267 webstore_data_fetcher_.reset(new WebstoreDataFetcher(
268 this, browser_context_->GetRequestContext(), GURL(), extension_id_));
269 webstore_data_fetcher_->Start();
270 }
271
272 ExternalInstallError::~ExternalInstallError() {
273 if (global_error_.get())
274 error_service_->RemoveGlobalError(global_error_.get());
275 }
276
277 void ExternalInstallError::InstallUIProceed() {
278 const Extension* extension = GetExtension();
279 if (extension) {
280 ExtensionSystem::Get(browser_context_)
281 ->extension_service()
282 ->GrantPermissionsAndEnableExtension(extension);
283 }
284 manager_->RemoveExternalInstallError();
285 }
286
287 void ExternalInstallError::InstallUIAbort(bool user_initiated) {
288 if (user_initiated && GetExtension()) {
289 ExtensionSystem::Get(browser_context_)
290 ->extension_service()
291 ->UninstallExtension(extension_id_,
292 false, // Not externally uninstalled.
293 NULL); // Ignore error.
294 }
295 manager_->RemoveExternalInstallError();
296 }
297
298 void ExternalInstallError::AcknowledgeExtension() {
299 const Extension* extension = GetExtension();
300 if (extension) {
301 ExtensionSystem::Get(browser_context_)
302 ->extension_service()
303 ->AcknowledgeExternalExtension(extension->id());
304 }
305 }
306
307 void ExternalInstallError::ShowDialog() {
308 DCHECK(install_ui_.get());
309 DCHECK(prompt_.get());
310 DCHECK(show_params_.get());
311 ExtensionInstallPrompt::GetDefaultShowDialogCallback().Run(
312 *show_params_, this, *prompt_);
313 }
314
315 const Extension* ExternalInstallError::GetExtension() const {
316 return ExtensionRegistry::Get(browser_context_)
317 ->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING);
318 }
319
320 void ExternalInstallError::OnWebstoreRequestFailure() {
321 OnFetchComplete();
322 }
323
324 void ExternalInstallError::OnWebstoreResponseParseSuccess(
325 scoped_ptr<base::DictionaryValue> webstore_data) {
326 std::string localized_user_count;
327 double average_rating;
328 int rating_count;
329 if (!webstore_data->GetString(kUsersKey, &localized_user_count) ||
330 !webstore_data->GetDouble(kAverageRatingKey, &average_rating) ||
331 !webstore_data->GetInteger(kRatingCountKey, &rating_count)) {
332 // If we don't get a valid webstore response, short circuit, and continue
333 // to show a prompt without webstore data.
334 OnFetchComplete();
335 return;
336 }
337
338 bool show_user_count = true;
339 webstore_data->GetBoolean(kShowUserCountKey, &show_user_count);
340
341 prompt_->SetWebstoreData(
342 localized_user_count, show_user_count, average_rating, rating_count);
343 OnFetchComplete();
344 }
345
346 void ExternalInstallError::OnWebstoreResponseParseFailure(
347 const std::string& error) {
348 OnFetchComplete();
349 }
350
351 void ExternalInstallError::OnFetchComplete() {
352 install_ui_.reset(
353 ExtensionInstallUI::CreateInstallPromptWithBrowser(browser_));
354
355 install_ui_->ConfirmExternalInstall(
356 this,
357 GetExtension(),
358 base::Bind(&ExternalInstallError::OnDialogReady,
359 weak_factory_.GetWeakPtr()),
360 *prompt_);
361 }
362
363 void ExternalInstallError::OnDialogReady(
364 const ExtensionInstallPrompt::ShowParams& show_params,
365 ExtensionInstallPrompt::Delegate* prompt_delegate,
366 const ExtensionInstallPrompt::Prompt& prompt) {
367 DCHECK_EQ(this, prompt_delegate);
368 show_params_.reset(new ExtensionInstallPrompt::ShowParams(show_params));
369 prompt_.reset(new ExtensionInstallPrompt::Prompt(prompt));
370
371 if (alert_type_ == BUBBLE_ALERT) {
372 global_error_.reset(new ExternalInstallBubbleAlert(this, prompt_.get()));
373 error_service_->AddGlobalError(global_error_.get());
374 if (browser_)
375 global_error_->ShowBubbleView(browser_);
376 } else {
377 DCHECK(alert_type_ == MENU_ALERT);
378 global_error_.reset(new ExternalInstallMenuAlert(this));
379 error_service_->AddGlobalError(global_error_.get());
380 }
381 }
382
383 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698