blob: 569124f3735ee21047e3408435fb4f115d9fb516 [file] [log] [blame]
[email protected]c82da8c42012-06-08 19:49:111// 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_install_prompt.h"
6
7#include <map>
8
9#include "base/command_line.h"
[email protected]b19fe572013-07-18 04:54:2610#include "base/message_loop/message_loop.h"
[email protected]3853a4c2013-02-11 17:15:5711#include "base/prefs/pref_service.h"
[email protected]3ea1b182013-02-08 22:38:4112#include "base/strings/string_number_conversions.h"
[email protected]00e7bef2013-06-10 20:35:1713#include "base/strings/string_util.h"
14#include "base/strings/stringprintf.h"
[email protected]112158af2013-06-07 23:46:1815#include "base/strings/utf_string_conversions.h"
[email protected]c82da8c42012-06-08 19:49:1116#include "chrome/browser/extensions/bundle_installer.h"
[email protected]c82da8c42012-06-08 19:49:1117#include "chrome/browser/extensions/extension_install_ui.h"
[email protected]7eb20e32014-04-30 08:50:5618#include "chrome/browser/extensions/extension_util.h"
[email protected]ec7de0c5a2012-11-16 07:40:4719#include "chrome/browser/extensions/image_loader.h"
[email protected]c82da8c42012-06-08 19:49:1120#include "chrome/browser/profiles/profile.h"
[email protected]4f3fb352013-07-17 04:07:0121#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
[email protected]32fc4ff72012-06-15 21:50:0122#include "chrome/browser/ui/browser.h"
[email protected]619f86182012-07-03 21:30:1823#include "chrome/browser/ui/browser_window.h"
[email protected]c82da8c42012-06-08 19:49:1124#include "chrome/common/chrome_switches.h"
[email protected]29e0c4e72013-02-01 04:42:5625#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
[email protected]fc5077942012-08-15 21:37:5926#include "chrome/common/pref_names.h"
[email protected]7274ef02014-03-24 22:43:4027#include "components/signin/core/browser/profile_oauth2_token_service.h"
[email protected]91e51d612012-10-21 23:03:0528#include "content/public/browser/web_contents.h"
[email protected]5db2e882012-12-20 10:17:2629#include "content/public/browser/web_contents_view.h"
[email protected]cda103d2014-04-04 16:22:3930#include "extensions/common/constants.h"
[email protected]e4452d32013-11-15 23:07:4131#include "extensions/common/extension.h"
[email protected]4b7908842014-04-07 23:50:2232#include "extensions/common/extension_icon_set.h"
[email protected]993da5e2013-03-23 21:25:1633#include "extensions/common/extension_resource.h"
[email protected]5ef835a2013-11-08 20:42:5734#include "extensions/common/feature_switch.h"
[email protected]d42c11152013-08-22 19:36:3235#include "extensions/common/manifest.h"
[email protected]6bf90612013-08-15 00:36:2736#include "extensions/common/manifest_constants.h"
[email protected]0db486f2014-04-09 19:32:2237#include "extensions/common/manifest_handlers/icons_handler.h"
[email protected]c41003472013-10-19 15:37:2538#include "extensions/common/permissions/permission_message_provider.h"
[email protected]5a55f3f2013-10-29 01:08:2939#include "extensions/common/permissions/permission_set.h"
[email protected]e4452d32013-11-15 23:07:4140#include "extensions/common/permissions/permissions_data.h"
[email protected]885c0e92012-11-13 20:27:4241#include "extensions/common/url_pattern.h"
[email protected]c82da8c42012-06-08 19:49:1142#include "grit/chromium_strings.h"
43#include "grit/generated_resources.h"
[email protected]2a281332012-07-11 22:20:2344#include "grit/theme_resources.h"
[email protected]c82da8c42012-06-08 19:49:1145#include "ui/base/l10n/l10n_util.h"
46#include "ui/base/resource/resource_bundle.h"
47#include "ui/gfx/image/image.h"
48
[email protected]c82da8c42012-06-08 19:49:1149using extensions::BundleInstaller;
50using extensions::Extension;
[email protected]1d5e58b2013-01-31 08:41:4051using extensions::Manifest;
[email protected]c2e66e12012-06-27 06:27:0652using extensions::PermissionSet;
[email protected]c82da8c42012-06-08 19:49:1153
[email protected]612a1cb12012-10-17 13:18:0354namespace {
55
[email protected]c82da8c42012-06-08 19:49:1156static const int kTitleIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
57 0, // The regular install prompt depends on what's being installed.
58 IDS_EXTENSION_INLINE_INSTALL_PROMPT_TITLE,
59 IDS_EXTENSION_INSTALL_PROMPT_TITLE,
60 IDS_EXTENSION_RE_ENABLE_PROMPT_TITLE,
[email protected]612a1cb12012-10-17 13:18:0361 IDS_EXTENSION_PERMISSIONS_PROMPT_TITLE,
62 IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_TITLE,
[email protected]15d267b42013-02-14 23:43:3263 IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_TITLE,
[email protected]1a93d8d2013-10-27 23:09:2064 IDS_EXTENSION_LAUNCH_APP_PROMPT_TITLE,
[email protected]c82da8c42012-06-08 19:49:1165};
66static const int kHeadingIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
67 IDS_EXTENSION_INSTALL_PROMPT_HEADING,
68 0, // Inline installs use the extension name.
69 0, // Heading for bundle installs depends on the bundle contents.
70 IDS_EXTENSION_RE_ENABLE_PROMPT_HEADING,
[email protected]612a1cb12012-10-17 13:18:0371 IDS_EXTENSION_PERMISSIONS_PROMPT_HEADING,
[email protected]846606012012-10-19 18:42:2572 0, // External installs use different strings for extensions/apps.
[email protected]15d267b42013-02-14 23:43:3273 IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_HEADING,
[email protected]1a93d8d2013-10-27 23:09:2074 IDS_EXTENSION_LAUNCH_APP_PROMPT_HEADING,
[email protected]15d267b42013-02-14 23:43:3275};
76static const int kButtons[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
77 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
78 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
79 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
80 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
81 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
82 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
83 ui::DIALOG_BUTTON_CANCEL,
[email protected]aa5a5472013-10-04 03:41:0484 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
[email protected]c82da8c42012-06-08 19:49:1185};
86static const int kAcceptButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
87 IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
88 IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
89 IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
90 IDS_EXTENSION_PROMPT_RE_ENABLE_BUTTON,
[email protected]612a1cb12012-10-17 13:18:0391 IDS_EXTENSION_PROMPT_PERMISSIONS_BUTTON,
[email protected]846606012012-10-19 18:42:2592 0, // External installs use different strings for extensions/apps.
[email protected]a2886e8b2013-06-08 05:15:0293 IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_FILES_BUTTON,
[email protected]1a93d8d2013-10-27 23:09:2094 IDS_EXTENSION_PROMPT_LAUNCH_BUTTON,
[email protected]c82da8c42012-06-08 19:49:1195};
96static const int kAbortButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
97 0, // These all use the platform's default cancel label.
98 0,
99 0,
100 0,
[email protected]612a1cb12012-10-17 13:18:03101 IDS_EXTENSION_PROMPT_PERMISSIONS_ABORT_BUTTON,
102 IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ABORT_BUTTON,
[email protected]15d267b42013-02-14 23:43:32103 IDS_CLOSE,
[email protected]bc123c02013-10-15 06:41:13104 0, // Platform dependent cancel button.
[email protected]c82da8c42012-06-08 19:49:11105};
106static const int kPermissionsHeaderIds[
107 ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
108 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
109 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
110 IDS_EXTENSION_PROMPT_THESE_WILL_HAVE_ACCESS_TO,
111 IDS_EXTENSION_PROMPT_WILL_NOW_HAVE_ACCESS_TO,
112 IDS_EXTENSION_PROMPT_WANTS_ACCESS_TO,
[email protected]612a1cb12012-10-17 13:18:03113 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
[email protected]15d267b42013-02-14 23:43:32114 IDS_EXTENSION_PROMPT_CAN_ACCESS,
[email protected]1a93d8d2013-10-27 23:09:20115 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
[email protected]c82da8c42012-06-08 19:49:11116};
[email protected]612a1cb12012-10-17 13:18:03117static const int kOAuthHeaderIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
[email protected]fc5077942012-08-15 21:37:59118 IDS_EXTENSION_PROMPT_OAUTH_HEADER,
119 0, // Inline installs don't show OAuth permissions.
120 0, // Bundle installs don't show OAuth permissions.
121 IDS_EXTENSION_PROMPT_OAUTH_REENABLE_HEADER,
122 IDS_EXTENSION_PROMPT_OAUTH_PERMISSIONS_HEADER,
[email protected]612a1cb12012-10-17 13:18:03123 0,
[email protected]15d267b42013-02-14 23:43:32124 0,
[email protected]aa5a5472013-10-04 03:41:04125 IDS_EXTENSION_PROMPT_OAUTH_HEADER,
[email protected]fc5077942012-08-15 21:37:59126};
[email protected]c82da8c42012-06-08 19:49:11127
[email protected]c82da8c42012-06-08 19:49:11128// Size of extension icon in top left of dialog.
129const int kIconSize = 69;
130
[email protected]dd46a4ce2012-09-15 10:50:50131// Returns pixel size under maximal scale factor for the icon whose device
132// independent size is |size_in_dip|
133int GetSizeForMaxScaleFactor(int size_in_dip) {
[email protected]50b66262013-09-24 03:25:48134 return static_cast<int>(size_in_dip * gfx::ImageSkia::GetMaxSupportedScale());
[email protected]dd46a4ce2012-09-15 10:50:50135}
136
137// Returns bitmap for the default icon with size equal to the default icon's
138// pixel size under maximal supported scale factor.
139SkBitmap GetDefaultIconBitmapForMaxScaleFactor(bool is_app) {
[email protected]702d8b42013-02-27 20:55:50140 const gfx::ImageSkia& image = is_app ?
[email protected]7eb20e32014-04-30 08:50:56141 extensions::util::GetDefaultAppIcon() :
142 extensions::util::GetDefaultExtensionIcon();
[email protected]50b66262013-09-24 03:25:48143 return image.GetRepresentation(
144 gfx::ImageSkia::GetMaxSupportedScale()).sk_bitmap();
[email protected]dd46a4ce2012-09-15 10:50:50145}
146
[email protected]af6efb22012-10-12 02:23:05147// If auto confirm is enabled then posts a task to proceed with or cancel the
148// install and returns true. Otherwise returns false.
149bool AutoConfirmPrompt(ExtensionInstallPrompt::Delegate* delegate) {
150 const CommandLine* cmdline = CommandLine::ForCurrentProcess();
151 if (!cmdline->HasSwitch(switches::kAppsGalleryInstallAutoConfirmForTests))
152 return false;
153 std::string value = cmdline->GetSwitchValueASCII(
154 switches::kAppsGalleryInstallAutoConfirmForTests);
155
156 // We use PostTask instead of calling the delegate directly here, because in
157 // the real implementations it's highly likely the message loop will be
158 // pumping a few times before the user clicks accept or cancel.
159 if (value == "accept") {
[email protected]b3a25092013-05-28 22:08:16160 base::MessageLoop::current()->PostTask(
[email protected]af6efb22012-10-12 02:23:05161 FROM_HERE,
162 base::Bind(&ExtensionInstallPrompt::Delegate::InstallUIProceed,
163 base::Unretained(delegate)));
164 return true;
165 }
166
167 if (value == "cancel") {
[email protected]b3a25092013-05-28 22:08:16168 base::MessageLoop::current()->PostTask(
[email protected]af6efb22012-10-12 02:23:05169 FROM_HERE,
170 base::Bind(&ExtensionInstallPrompt::Delegate::InstallUIAbort,
171 base::Unretained(delegate),
172 true));
173 return true;
174 }
175
176 NOTREACHED();
177 return false;
178}
179
[email protected]91e51d612012-10-21 23:03:05180Profile* ProfileForWebContents(content::WebContents* web_contents) {
181 if (!web_contents)
182 return NULL;
183 return Profile::FromBrowserContext(web_contents->GetBrowserContext());
184}
185
[email protected]5db2e882012-12-20 10:17:26186gfx::NativeWindow NativeWindowForWebContents(content::WebContents* contents) {
187 if (!contents)
188 return NULL;
189
190 return contents->GetView()->GetTopLevelNativeWindow();
191}
192
[email protected]c82da8c42012-06-08 19:49:11193} // namespace
194
[email protected]5db2e882012-12-20 10:17:26195ExtensionInstallPrompt::Prompt::Prompt(PromptType type)
[email protected]c82da8c42012-06-08 19:49:11196 : type_(type),
[email protected]79a6f99a2013-08-29 00:32:58197 is_showing_details_for_retained_files_(false),
[email protected]c82da8c42012-06-08 19:49:11198 extension_(NULL),
199 bundle_(NULL),
200 average_rating_(0.0),
[email protected]dcde34b32013-07-31 02:28:45201 rating_count_(0),
[email protected]34b5f7f2014-01-29 02:48:11202 show_user_count_(false),
203 has_webstore_data_(false) {
[email protected]c82da8c42012-06-08 19:49:11204}
205
206ExtensionInstallPrompt::Prompt::~Prompt() {
207}
208
209void ExtensionInstallPrompt::Prompt::SetPermissions(
[email protected]d2065e062013-12-12 23:49:52210 const std::vector<base::string16>& permissions) {
[email protected]c82da8c42012-06-08 19:49:11211 permissions_ = permissions;
212}
213
[email protected]8ab7e6c2013-07-11 21:15:03214void ExtensionInstallPrompt::Prompt::SetPermissionsDetails(
[email protected]d2065e062013-12-12 23:49:52215 const std::vector<base::string16>& details) {
[email protected]8ab7e6c2013-07-11 21:15:03216 details_ = details;
[email protected]79a6f99a2013-08-29 00:32:58217 is_showing_details_for_permissions_.clear();
218 for (size_t i = 0; i < details.size(); ++i)
219 is_showing_details_for_permissions_.push_back(false);
220}
221
222void ExtensionInstallPrompt::Prompt::SetIsShowingDetails(
223 DetailsType type,
224 size_t index,
225 bool is_showing_details) {
226 switch (type) {
227 case PERMISSIONS_DETAILS:
228 is_showing_details_for_permissions_[index] = is_showing_details;
229 break;
230 case OAUTH_DETAILS:
231 is_showing_details_for_oauth_[index] = is_showing_details;
232 break;
233 case RETAINED_FILES_DETAILS:
234 is_showing_details_for_retained_files_ = is_showing_details;
235 break;
236 }
[email protected]8ab7e6c2013-07-11 21:15:03237}
238
[email protected]b70a2d92012-06-28 19:51:21239void ExtensionInstallPrompt::Prompt::SetOAuthIssueAdvice(
240 const IssueAdviceInfo& issue_advice) {
[email protected]79a6f99a2013-08-29 00:32:58241 is_showing_details_for_oauth_.clear();
242 for (size_t i = 0; i < issue_advice.size(); ++i)
243 is_showing_details_for_oauth_.push_back(false);
244
[email protected]b70a2d92012-06-28 19:51:21245 oauth_issue_advice_ = issue_advice;
246}
247
[email protected]5db2e882012-12-20 10:17:26248void ExtensionInstallPrompt::Prompt::SetUserNameFromProfile(Profile* profile) {
249 // |profile| can be NULL in unit tests.
250 if (profile) {
[email protected]04338722013-12-24 23:18:05251 oauth_user_name_ = base::UTF8ToUTF16(profile->GetPrefs()->GetString(
[email protected]5db2e882012-12-20 10:17:26252 prefs::kGoogleServicesUsername));
253 } else {
254 oauth_user_name_.clear();
255 }
256}
257
[email protected]34b5f7f2014-01-29 02:48:11258void ExtensionInstallPrompt::Prompt::SetWebstoreData(
[email protected]c82da8c42012-06-08 19:49:11259 const std::string& localized_user_count,
[email protected]dcde34b32013-07-31 02:28:45260 bool show_user_count,
[email protected]c82da8c42012-06-08 19:49:11261 double average_rating,
262 int rating_count) {
[email protected]34b5f7f2014-01-29 02:48:11263 CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
[email protected]c82da8c42012-06-08 19:49:11264 localized_user_count_ = localized_user_count;
[email protected]dcde34b32013-07-31 02:28:45265 show_user_count_ = show_user_count;
[email protected]c82da8c42012-06-08 19:49:11266 average_rating_ = average_rating;
267 rating_count_ = rating_count;
[email protected]34b5f7f2014-01-29 02:48:11268 has_webstore_data_ = true;
[email protected]c82da8c42012-06-08 19:49:11269}
270
[email protected]6a72a632013-12-12 22:22:00271base::string16 ExtensionInstallPrompt::Prompt::GetDialogTitle() const {
[email protected]c82da8c42012-06-08 19:49:11272 int resource_id = kTitleIds[type_];
273
274 if (type_ == INSTALL_PROMPT) {
275 if (extension_->is_app())
276 resource_id = IDS_EXTENSION_INSTALL_APP_PROMPT_TITLE;
277 else if (extension_->is_theme())
278 resource_id = IDS_EXTENSION_INSTALL_THEME_PROMPT_TITLE;
279 else
280 resource_id = IDS_EXTENSION_INSTALL_EXTENSION_PROMPT_TITLE;
[email protected]612a1cb12012-10-17 13:18:03281 } else if (type_ == EXTERNAL_INSTALL_PROMPT) {
282 return l10n_util::GetStringFUTF16(
[email protected]04338722013-12-24 23:18:05283 resource_id, base::UTF8ToUTF16(extension_->name()));
[email protected]c82da8c42012-06-08 19:49:11284 }
285
286 return l10n_util::GetStringUTF16(resource_id);
287}
288
[email protected]6a72a632013-12-12 22:22:00289base::string16 ExtensionInstallPrompt::Prompt::GetHeading() const {
[email protected]c82da8c42012-06-08 19:49:11290 if (type_ == INLINE_INSTALL_PROMPT) {
[email protected]04338722013-12-24 23:18:05291 return base::UTF8ToUTF16(extension_->name());
[email protected]c82da8c42012-06-08 19:49:11292 } else if (type_ == BUNDLE_INSTALL_PROMPT) {
293 return bundle_->GetHeadingTextFor(BundleInstaller::Item::STATE_PENDING);
[email protected]612a1cb12012-10-17 13:18:03294 } else if (type_ == EXTERNAL_INSTALL_PROMPT) {
[email protected]846606012012-10-19 18:42:25295 int resource_id = -1;
296 if (extension_->is_app())
297 resource_id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_HEADING_APP;
298 else if (extension_->is_theme())
299 resource_id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_HEADING_THEME;
300 else
301 resource_id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_HEADING_EXTENSION;
302 return l10n_util::GetStringUTF16(resource_id);
[email protected]c82da8c42012-06-08 19:49:11303 } else {
304 return l10n_util::GetStringFUTF16(
[email protected]04338722013-12-24 23:18:05305 kHeadingIds[type_], base::UTF8ToUTF16(extension_->name()));
[email protected]c82da8c42012-06-08 19:49:11306 }
307}
308
[email protected]15d267b42013-02-14 23:43:32309int ExtensionInstallPrompt::Prompt::GetDialogButtons() const {
[email protected]a2886e8b2013-06-08 05:15:02310 if (type_ == POST_INSTALL_PERMISSIONS_PROMPT &&
311 ShouldDisplayRevokeFilesButton()) {
312 return kButtons[type_] | ui::DIALOG_BUTTON_OK;
313 }
314
[email protected]15d267b42013-02-14 23:43:32315 return kButtons[type_];
316}
317
[email protected]62a28d7c2013-12-28 01:34:49318bool ExtensionInstallPrompt::Prompt::ShouldShowExplanationText() const {
319 return type_ == INSTALL_PROMPT &&
320 extension_->is_extension() && experiment_ && experiment_->text_only();
321}
322
[email protected]15d267b42013-02-14 23:43:32323bool ExtensionInstallPrompt::Prompt::HasAcceptButtonLabel() const {
[email protected]a2886e8b2013-06-08 05:15:02324 if (kAcceptButtonIds[type_] == 0)
325 return false;
326
327 if (type_ == POST_INSTALL_PERMISSIONS_PROMPT)
328 return ShouldDisplayRevokeFilesButton();
329
330 return true;
[email protected]15d267b42013-02-14 23:43:32331}
332
[email protected]6a72a632013-12-12 22:22:00333base::string16 ExtensionInstallPrompt::Prompt::GetAcceptButtonLabel() const {
[email protected]846606012012-10-19 18:42:25334 if (type_ == EXTERNAL_INSTALL_PROMPT) {
335 int id = -1;
336 if (extension_->is_app())
337 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_APP;
338 else if (extension_->is_theme())
339 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_THEME;
340 else
341 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_EXTENSION;
342 return l10n_util::GetStringUTF16(id);
343 }
[email protected]62a28d7c2013-12-28 01:34:49344 if (ShouldShowExplanationText())
345 return experiment_->GetOkButtonText();
[email protected]c82da8c42012-06-08 19:49:11346 return l10n_util::GetStringUTF16(kAcceptButtonIds[type_]);
347}
348
349bool ExtensionInstallPrompt::Prompt::HasAbortButtonLabel() const {
[email protected]62a28d7c2013-12-28 01:34:49350 if (ShouldShowExplanationText())
351 return true;
[email protected]c82da8c42012-06-08 19:49:11352 return kAbortButtonIds[type_] > 0;
353}
354
[email protected]6a72a632013-12-12 22:22:00355base::string16 ExtensionInstallPrompt::Prompt::GetAbortButtonLabel() const {
[email protected]c82da8c42012-06-08 19:49:11356 CHECK(HasAbortButtonLabel());
[email protected]62a28d7c2013-12-28 01:34:49357 if (ShouldShowExplanationText())
358 return experiment_->GetCancelButtonText();
[email protected]c82da8c42012-06-08 19:49:11359 return l10n_util::GetStringUTF16(kAbortButtonIds[type_]);
360}
361
[email protected]6a72a632013-12-12 22:22:00362base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsHeading() const {
[email protected]c82da8c42012-06-08 19:49:11363 return l10n_util::GetStringUTF16(kPermissionsHeaderIds[type_]);
364}
365
[email protected]6a72a632013-12-12 22:22:00366base::string16 ExtensionInstallPrompt::Prompt::GetOAuthHeading() const {
[email protected]5db2e882012-12-20 10:17:26367 return l10n_util::GetStringFUTF16(kOAuthHeaderIds[type_], oauth_user_name_);
[email protected]813475e2012-07-02 23:54:18368}
369
[email protected]6a72a632013-12-12 22:22:00370base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFilesHeading() const {
[email protected]4f1e1082013-09-23 10:30:53371 const int kRetainedFilesMessageIDs[6] = {
372 IDS_EXTENSION_PROMPT_RETAINED_FILES_DEFAULT,
373 IDS_EXTENSION_PROMPT_RETAINED_FILE_SINGULAR,
374 IDS_EXTENSION_PROMPT_RETAINED_FILES_ZERO,
375 IDS_EXTENSION_PROMPT_RETAINED_FILES_TWO,
376 IDS_EXTENSION_PROMPT_RETAINED_FILES_FEW,
377 IDS_EXTENSION_PROMPT_RETAINED_FILES_MANY,
378 };
379 std::vector<int> message_ids;
380 for (size_t i = 0; i < arraysize(kRetainedFilesMessageIDs); i++) {
381 message_ids.push_back(kRetainedFilesMessageIDs[i]);
382 }
383 return l10n_util::GetPluralStringFUTF16(message_ids, GetRetainedFileCount());
[email protected]8ab7e6c2013-07-11 21:15:03384}
385
[email protected]f2cd8992013-06-11 17:30:18386bool ExtensionInstallPrompt::Prompt::ShouldShowPermissions() const {
387 return GetPermissionCount() > 0 || type_ == POST_INSTALL_PERMISSIONS_PROMPT;
388}
389
[email protected]c82da8c42012-06-08 19:49:11390void ExtensionInstallPrompt::Prompt::AppendRatingStars(
391 StarAppender appender, void* data) const {
392 CHECK(appender);
[email protected]34b5f7f2014-01-29 02:48:11393 CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
[email protected]c82da8c42012-06-08 19:49:11394 int rating_integer = floor(average_rating_);
395 double rating_fractional = average_rating_ - rating_integer;
396
397 if (rating_fractional > 0.66) {
398 rating_integer++;
399 }
400
401 if (rating_fractional < 0.33 || rating_fractional > 0.66) {
402 rating_fractional = 0;
403 }
404
405 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
406 int i;
407 for (i = 0; i < rating_integer; i++) {
408 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_ON), data);
409 }
410 if (rating_fractional) {
411 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_HALF_LEFT), data);
412 i++;
413 }
414 for (; i < kMaxExtensionRating; i++) {
415 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_OFF), data);
416 }
417}
418
[email protected]6a72a632013-12-12 22:22:00419base::string16 ExtensionInstallPrompt::Prompt::GetRatingCount() const {
[email protected]34b5f7f2014-01-29 02:48:11420 CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
[email protected]6725048e2013-10-24 21:47:14421 return l10n_util::GetStringFUTF16(IDS_EXTENSION_RATING_COUNT,
422 base::IntToString16(rating_count_));
[email protected]c82da8c42012-06-08 19:49:11423}
424
[email protected]6a72a632013-12-12 22:22:00425base::string16 ExtensionInstallPrompt::Prompt::GetUserCount() const {
[email protected]34b5f7f2014-01-29 02:48:11426 CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
[email protected]dcde34b32013-07-31 02:28:45427
428 if (show_user_count_) {
[email protected]6725048e2013-10-24 21:47:14429 return l10n_util::GetStringFUTF16(IDS_EXTENSION_USER_COUNT,
430 base::UTF8ToUTF16(localized_user_count_));
[email protected]dcde34b32013-07-31 02:28:45431 }
[email protected]6725048e2013-10-24 21:47:14432 return base::string16();
[email protected]c82da8c42012-06-08 19:49:11433}
434
435size_t ExtensionInstallPrompt::Prompt::GetPermissionCount() const {
436 return permissions_.size();
437}
438
[email protected]8ab7e6c2013-07-11 21:15:03439size_t ExtensionInstallPrompt::Prompt::GetPermissionsDetailsCount() const {
440 return details_.size();
441}
442
[email protected]6a72a632013-12-12 22:22:00443base::string16 ExtensionInstallPrompt::Prompt::GetPermission(size_t index)
444 const {
[email protected]c82da8c42012-06-08 19:49:11445 CHECK_LT(index, permissions_.size());
[email protected]ef2654e42012-08-11 03:57:56446 return permissions_[index];
[email protected]c82da8c42012-06-08 19:49:11447}
448
[email protected]6a72a632013-12-12 22:22:00449base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsDetails(
[email protected]8ab7e6c2013-07-11 21:15:03450 size_t index) const {
451 CHECK_LT(index, details_.size());
452 return details_[index];
453}
454
[email protected]79a6f99a2013-08-29 00:32:58455bool ExtensionInstallPrompt::Prompt::GetIsShowingDetails(
456 DetailsType type, size_t index) const {
457 switch (type) {
458 case PERMISSIONS_DETAILS:
459 CHECK_LT(index, is_showing_details_for_permissions_.size());
460 return is_showing_details_for_permissions_[index];
461 case OAUTH_DETAILS:
462 CHECK_LT(index, is_showing_details_for_oauth_.size());
463 return is_showing_details_for_oauth_[index];
464 case RETAINED_FILES_DETAILS:
465 return is_showing_details_for_retained_files_;
466 }
467 return false;
468}
469
[email protected]b70a2d92012-06-28 19:51:21470size_t ExtensionInstallPrompt::Prompt::GetOAuthIssueCount() const {
471 return oauth_issue_advice_.size();
472}
473
474const IssueAdviceInfoEntry& ExtensionInstallPrompt::Prompt::GetOAuthIssue(
475 size_t index) const {
476 CHECK_LT(index, oauth_issue_advice_.size());
477 return oauth_issue_advice_[index];
478}
479
[email protected]a2886e8b2013-06-08 05:15:02480size_t ExtensionInstallPrompt::Prompt::GetRetainedFileCount() const {
481 return retained_files_.size();
482}
483
[email protected]6a72a632013-12-12 22:22:00484base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFile(size_t index)
485 const {
[email protected]a2886e8b2013-06-08 05:15:02486 CHECK_LT(index, retained_files_.size());
[email protected]6725048e2013-10-24 21:47:14487 return retained_files_[index].AsUTF16Unsafe();
[email protected]a2886e8b2013-06-08 05:15:02488}
489
490bool ExtensionInstallPrompt::Prompt::ShouldDisplayRevokeFilesButton() const {
491 return !retained_files_.empty();
492}
493
[email protected]5db2e882012-12-20 10:17:26494ExtensionInstallPrompt::ShowParams::ShowParams(content::WebContents* contents)
495 : parent_web_contents(contents),
496 parent_window(NativeWindowForWebContents(contents)),
497 navigator(contents) {
498}
499
500ExtensionInstallPrompt::ShowParams::ShowParams(
501 gfx::NativeWindow window,
502 content::PageNavigator* navigator)
503 : parent_web_contents(NULL),
504 parent_window(window),
505 navigator(navigator) {
506}
507
[email protected]c82da8c42012-06-08 19:49:11508// static
509scoped_refptr<Extension>
510 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay(
[email protected]023b3d12013-12-23 18:46:49511 const base::DictionaryValue* manifest,
[email protected]c422a862012-07-31 15:46:13512 int flags,
[email protected]c82da8c42012-06-08 19:49:11513 const std::string& id,
514 const std::string& localized_name,
515 const std::string& localized_description,
516 std::string* error) {
[email protected]023b3d12013-12-23 18:46:49517 scoped_ptr<base::DictionaryValue> localized_manifest;
[email protected]c82da8c42012-06-08 19:49:11518 if (!localized_name.empty() || !localized_description.empty()) {
519 localized_manifest.reset(manifest->DeepCopy());
520 if (!localized_name.empty()) {
[email protected]6bf90612013-08-15 00:36:27521 localized_manifest->SetString(extensions::manifest_keys::kName,
[email protected]c82da8c42012-06-08 19:49:11522 localized_name);
523 }
524 if (!localized_description.empty()) {
[email protected]6bf90612013-08-15 00:36:27525 localized_manifest->SetString(extensions::manifest_keys::kDescription,
[email protected]c82da8c42012-06-08 19:49:11526 localized_description);
527 }
528 }
529
530 return Extension::Create(
[email protected]650b2d52013-02-10 03:41:45531 base::FilePath(),
[email protected]1d5e58b2013-01-31 08:41:40532 Manifest::INTERNAL,
[email protected]c82da8c42012-06-08 19:49:11533 localized_manifest.get() ? *localized_manifest.get() : *manifest,
[email protected]c422a862012-07-31 15:46:13534 flags,
[email protected]c82da8c42012-06-08 19:49:11535 id,
536 error);
537}
538
[email protected]7f165342014-02-12 09:22:22539ExtensionInstallPrompt::ExtensionInstallPrompt(content::WebContents* contents)
[email protected]f1e98482013-12-27 00:45:59540 : OAuth2TokenService::Consumer("extensions_install"),
541 record_oauth2_grant_(false),
[email protected]b3a25092013-05-28 22:08:16542 ui_loop_(base::MessageLoop::current()),
[email protected]c82da8c42012-06-08 19:49:11543 extension_(NULL),
[email protected]7f165342014-02-12 09:22:22544 bundle_(NULL),
[email protected]91e51d612012-10-21 23:03:05545 install_ui_(ExtensionInstallUI::Create(ProfileForWebContents(contents))),
[email protected]5db2e882012-12-20 10:17:26546 show_params_(contents),
[email protected]c82da8c42012-06-08 19:49:11547 delegate_(NULL),
[email protected]5db2e882012-12-20 10:17:26548 prompt_(UNSET_PROMPT_TYPE) {
549 prompt_.SetUserNameFromProfile(install_ui_->profile());
550}
551
552ExtensionInstallPrompt::ExtensionInstallPrompt(
553 Profile* profile,
554 gfx::NativeWindow native_window,
555 content::PageNavigator* navigator)
[email protected]f1e98482013-12-27 00:45:59556 : OAuth2TokenService::Consumer("extensions_install"),
557 record_oauth2_grant_(false),
[email protected]b3a25092013-05-28 22:08:16558 ui_loop_(base::MessageLoop::current()),
[email protected]5db2e882012-12-20 10:17:26559 extension_(NULL),
[email protected]7f165342014-02-12 09:22:22560 bundle_(NULL),
[email protected]5db2e882012-12-20 10:17:26561 install_ui_(ExtensionInstallUI::Create(profile)),
562 show_params_(native_window, navigator),
563 delegate_(NULL),
564 prompt_(UNSET_PROMPT_TYPE) {
565 prompt_.SetUserNameFromProfile(install_ui_->profile());
[email protected]c82da8c42012-06-08 19:49:11566}
567
568ExtensionInstallPrompt::~ExtensionInstallPrompt() {
569}
570
571void ExtensionInstallPrompt::ConfirmBundleInstall(
572 extensions::BundleInstaller* bundle,
[email protected]c2e66e12012-06-27 06:27:06573 const PermissionSet* permissions) {
[email protected]b3a25092013-05-28 22:08:16574 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]c82da8c42012-06-08 19:49:11575 bundle_ = bundle;
576 permissions_ = permissions;
577 delegate_ = bundle;
[email protected]5db2e882012-12-20 10:17:26578 prompt_.set_type(BUNDLE_INSTALL_PROMPT);
[email protected]c82da8c42012-06-08 19:49:11579
[email protected]4e494872013-09-06 09:13:54580 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11581}
582
[email protected]734bcec2012-10-08 20:29:05583void ExtensionInstallPrompt::ConfirmStandaloneInstall(
[email protected]c82da8c42012-06-08 19:49:11584 Delegate* delegate,
585 const Extension* extension,
586 SkBitmap* icon,
587 const ExtensionInstallPrompt::Prompt& prompt) {
[email protected]b3a25092013-05-28 22:08:16588 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]c82da8c42012-06-08 19:49:11589 extension_ = extension;
590 permissions_ = extension->GetActivePermissions();
591 delegate_ = delegate;
592 prompt_ = prompt;
[email protected]c82da8c42012-06-08 19:49:11593
594 SetIcon(icon);
[email protected]4e494872013-09-06 09:13:54595 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11596}
597
[email protected]af6efb22012-10-12 02:23:05598void ExtensionInstallPrompt::ConfirmWebstoreInstall(
599 Delegate* delegate,
600 const Extension* extension,
601 const SkBitmap* icon,
602 const ShowDialogCallback& show_dialog_callback) {
[email protected]c82da8c42012-06-08 19:49:11603 // SetIcon requires |extension_| to be set. ConfirmInstall will setup the
604 // remaining fields.
605 extension_ = extension;
606 SetIcon(icon);
[email protected]af6efb22012-10-12 02:23:05607 ConfirmInstall(delegate, extension, show_dialog_callback);
[email protected]c82da8c42012-06-08 19:49:11608}
609
[email protected]af6efb22012-10-12 02:23:05610void ExtensionInstallPrompt::ConfirmInstall(
611 Delegate* delegate,
612 const Extension* extension,
613 const ShowDialogCallback& show_dialog_callback) {
[email protected]b3a25092013-05-28 22:08:16614 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]c82da8c42012-06-08 19:49:11615 extension_ = extension;
616 permissions_ = extension->GetActivePermissions();
617 delegate_ = delegate;
[email protected]5db2e882012-12-20 10:17:26618 prompt_.set_type(INSTALL_PROMPT);
[email protected]af6efb22012-10-12 02:23:05619 show_dialog_callback_ = show_dialog_callback;
[email protected]c82da8c42012-06-08 19:49:11620
621 // We special-case themes to not show any confirm UI. Instead they are
622 // immediately installed, and then we show an infobar (see OnInstallSuccess)
623 // to allow the user to revert if they don't like it.
624 //
625 // We don't do this in the case where off-store extension installs are
626 // disabled because in that case, we don't show the dangerous download UI, so
627 // we need the UI confirmation.
628 if (extension->is_theme()) {
629 if (extension->from_webstore() ||
[email protected]544471a2012-10-13 05:27:09630 extensions::FeatureSwitch::easy_off_store_install()->IsEnabled()) {
[email protected]c82da8c42012-06-08 19:49:11631 delegate->InstallUIProceed();
632 return;
633 }
634 }
635
636 LoadImageIfNeeded();
637}
638
639void ExtensionInstallPrompt::ConfirmReEnable(Delegate* delegate,
640 const Extension* extension) {
[email protected]b3a25092013-05-28 22:08:16641 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]c82da8c42012-06-08 19:49:11642 extension_ = extension;
643 permissions_ = extension->GetActivePermissions();
644 delegate_ = delegate;
[email protected]ab6c7be42014-01-16 02:05:54645 prompt_.set_type(extension->is_ephemeral() ? LAUNCH_PROMPT :
646 RE_ENABLE_PROMPT);
[email protected]c82da8c42012-06-08 19:49:11647
648 LoadImageIfNeeded();
649}
650
[email protected]612a1cb12012-10-17 13:18:03651void ExtensionInstallPrompt::ConfirmExternalInstall(
[email protected]c8ff7c9e2013-04-20 12:36:27652 Delegate* delegate,
653 const Extension* extension,
[email protected]34b5f7f2014-01-29 02:48:11654 const ShowDialogCallback& show_dialog_callback,
655 const Prompt& prompt) {
[email protected]b3a25092013-05-28 22:08:16656 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]612a1cb12012-10-17 13:18:03657 extension_ = extension;
658 permissions_ = extension->GetActivePermissions();
659 delegate_ = delegate;
[email protected]34b5f7f2014-01-29 02:48:11660 prompt_ = prompt;
[email protected]c8ff7c9e2013-04-20 12:36:27661 show_dialog_callback_ = show_dialog_callback;
[email protected]612a1cb12012-10-17 13:18:03662
663 LoadImageIfNeeded();
664}
665
[email protected]c82da8c42012-06-08 19:49:11666void ExtensionInstallPrompt::ConfirmPermissions(
667 Delegate* delegate,
668 const Extension* extension,
[email protected]c2e66e12012-06-27 06:27:06669 const PermissionSet* permissions) {
[email protected]b3a25092013-05-28 22:08:16670 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]c82da8c42012-06-08 19:49:11671 extension_ = extension;
672 permissions_ = permissions;
673 delegate_ = delegate;
[email protected]5db2e882012-12-20 10:17:26674 prompt_.set_type(PERMISSIONS_PROMPT);
[email protected]c82da8c42012-06-08 19:49:11675
676 LoadImageIfNeeded();
677}
678
[email protected]f746b3f2012-07-03 17:53:37679void ExtensionInstallPrompt::ConfirmIssueAdvice(
680 Delegate* delegate,
681 const Extension* extension,
682 const IssueAdviceInfo& issue_advice) {
[email protected]b3a25092013-05-28 22:08:16683 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]f746b3f2012-07-03 17:53:37684 extension_ = extension;
685 delegate_ = delegate;
[email protected]5db2e882012-12-20 10:17:26686 prompt_.set_type(PERMISSIONS_PROMPT);
[email protected]f746b3f2012-07-03 17:53:37687
688 record_oauth2_grant_ = true;
689 prompt_.SetOAuthIssueAdvice(issue_advice);
690
691 LoadImageIfNeeded();
692}
693
[email protected]a2886e8b2013-06-08 05:15:02694void ExtensionInstallPrompt::ReviewPermissions(
695 Delegate* delegate,
696 const Extension* extension,
697 const std::vector<base::FilePath>& retained_file_paths) {
[email protected]b3a25092013-05-28 22:08:16698 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]15d267b42013-02-14 23:43:32699 extension_ = extension;
700 permissions_ = extension->GetActivePermissions();
[email protected]a2886e8b2013-06-08 05:15:02701 prompt_.set_retained_files(retained_file_paths);
[email protected]15d267b42013-02-14 23:43:32702 delegate_ = delegate;
703 prompt_.set_type(POST_INSTALL_PERMISSIONS_PROMPT);
704
705 LoadImageIfNeeded();
706}
707
[email protected]c82da8c42012-06-08 19:49:11708void ExtensionInstallPrompt::OnInstallSuccess(const Extension* extension,
709 SkBitmap* icon) {
710 extension_ = extension;
711 SetIcon(icon);
712
713 install_ui_->OnInstallSuccess(extension, &icon_);
714}
715
[email protected]bf3d9df2012-07-24 23:20:27716void ExtensionInstallPrompt::OnInstallFailure(
717 const extensions::CrxInstallerError& error) {
[email protected]c82da8c42012-06-08 19:49:11718 install_ui_->OnInstallFailure(error);
719}
720
721void ExtensionInstallPrompt::SetIcon(const SkBitmap* image) {
722 if (image)
723 icon_ = *image;
724 else
725 icon_ = SkBitmap();
[email protected]dd46a4ce2012-09-15 10:50:50726 if (icon_.empty()) {
727 // Let's set default icon bitmap whose size is equal to the default icon's
728 // pixel size under maximal supported scale factor. If the bitmap is larger
729 // than the one we need, it will be scaled down by the ui code.
730 icon_ = GetDefaultIconBitmapForMaxScaleFactor(extension_->is_app());
731 }
[email protected]c82da8c42012-06-08 19:49:11732}
733
[email protected]ec7de0c5a2012-11-16 07:40:47734void ExtensionInstallPrompt::OnImageLoaded(const gfx::Image& image) {
[email protected]c82da8c42012-06-08 19:49:11735 SetIcon(image.IsEmpty() ? NULL : image.ToSkBitmap());
[email protected]4e494872013-09-06 09:13:54736 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11737}
738
739void ExtensionInstallPrompt::LoadImageIfNeeded() {
740 // Bundle install prompts do not have an icon.
[email protected]5db2e882012-12-20 10:17:26741 // Also |install_ui_.profile()| can be NULL in unit tests.
742 if (!icon_.empty() || !install_ui_->profile()) {
[email protected]4e494872013-09-06 09:13:54743 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11744 return;
745 }
746
747 // Load the image asynchronously. For the response, check OnImageLoaded.
[email protected]993da5e2013-03-23 21:25:16748 extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
[email protected]702d8b42013-02-27 20:55:50749 extension_,
750 extension_misc::EXTENSION_ICON_LARGE,
751 ExtensionIconSet::MATCH_BIGGER);
[email protected]dd46a4ce2012-09-15 10:50:50752 // Load the icon whose pixel size is large enough to be displayed under
753 // maximal supported scale factor. UI code will scale the icon down if needed.
754 // TODO(tbarzic): We should use IconImage here and load the required bitmap
755 // lazily.
756 int pixel_size = GetSizeForMaxScaleFactor(kIconSize);
[email protected]5db2e882012-12-20 10:17:26757 extensions::ImageLoader::Get(install_ui_->profile())->LoadImageAsync(
[email protected]ec7de0c5a2012-11-16 07:40:47758 extension_, image, gfx::Size(pixel_size, pixel_size),
759 base::Bind(&ExtensionInstallPrompt::OnImageLoaded, AsWeakPtr()));
[email protected]c82da8c42012-06-08 19:49:11760}
761
[email protected]4f3fb352013-07-17 04:07:01762void ExtensionInstallPrompt::OnGetTokenSuccess(
763 const OAuth2TokenService::Request* request,
764 const std::string& access_token,
765 const base::Time& expiration_time) {
766 DCHECK_EQ(login_token_request_.get(), request);
767 login_token_request_.reset();
768
769 const extensions::OAuth2Info& oauth2_info =
770 extensions::OAuth2Info::GetOAuth2Info(extension_);
771
[email protected]b70a2d92012-06-28 19:51:21772 token_flow_.reset(new OAuth2MintTokenFlow(
[email protected]4f3fb352013-07-17 04:07:01773 install_ui_->profile()->GetRequestContext(),
[email protected]b70a2d92012-06-28 19:51:21774 this,
775 OAuth2MintTokenFlow::Parameters(
[email protected]4f3fb352013-07-17 04:07:01776 access_token,
[email protected]b70a2d92012-06-28 19:51:21777 extension_->id(),
778 oauth2_info.client_id,
[email protected]d4a37f1c2012-07-09 21:36:13779 oauth2_info.scopes,
[email protected]b70a2d92012-06-28 19:51:21780 OAuth2MintTokenFlow::MODE_ISSUE_ADVICE)));
781 token_flow_->Start();
782}
783
[email protected]4f3fb352013-07-17 04:07:01784void ExtensionInstallPrompt::OnGetTokenFailure(
785 const OAuth2TokenService::Request* request,
786 const GoogleServiceAuthError& error) {
787 DCHECK_EQ(login_token_request_.get(), request);
788 login_token_request_.reset();
789 ShowConfirmation();
790}
791
[email protected]b70a2d92012-06-28 19:51:21792void ExtensionInstallPrompt::OnIssueAdviceSuccess(
793 const IssueAdviceInfo& advice_info) {
794 prompt_.SetOAuthIssueAdvice(advice_info);
795 record_oauth2_grant_ = true;
796 ShowConfirmation();
797}
798
799void ExtensionInstallPrompt::OnMintTokenFailure(
800 const GoogleServiceAuthError& error) {
801 ShowConfirmation();
802}
803
[email protected]c82da8c42012-06-08 19:49:11804void ExtensionInstallPrompt::ShowConfirmation() {
[email protected]62a28d7c2013-12-28 01:34:49805 if (prompt_.type() == INSTALL_PROMPT)
806 prompt_.set_experiment(ExtensionInstallPromptExperiment::Find());
807 else
808 prompt_.set_experiment(ExtensionInstallPromptExperiment::ControlGroup());
809
[email protected]dc24976f2013-06-02 21:15:09810 if (permissions_.get() &&
[email protected]13c68b62013-05-17 11:29:05811 (!extension_ ||
812 !extensions::PermissionsData::ShouldSkipPermissionWarnings(
813 extension_))) {
[email protected]1d5e58b2013-01-31 08:41:40814 Manifest::Type extension_type = extension_ ?
815 extension_->GetType() : Manifest::TYPE_UNKNOWN;
[email protected]8ab7e6c2013-07-11 21:15:03816 prompt_.SetPermissions(
[email protected]c41003472013-10-19 15:37:25817 extensions::PermissionMessageProvider::Get()->
818 GetWarningMessages(permissions_, extension_type));
[email protected]8ab7e6c2013-07-11 21:15:03819 prompt_.SetPermissionsDetails(
[email protected]c41003472013-10-19 15:37:25820 extensions::PermissionMessageProvider::Get()->
821 GetWarningMessagesDetails(permissions_, extension_type));
[email protected]bebe1d02012-08-02 20:17:09822 }
[email protected]c82da8c42012-06-08 19:49:11823
[email protected]5db2e882012-12-20 10:17:26824 switch (prompt_.type()) {
[email protected]c82da8c42012-06-08 19:49:11825 case PERMISSIONS_PROMPT:
826 case RE_ENABLE_PROMPT:
827 case INLINE_INSTALL_PROMPT:
[email protected]612a1cb12012-10-17 13:18:03828 case EXTERNAL_INSTALL_PROMPT:
[email protected]15d267b42013-02-14 23:43:32829 case INSTALL_PROMPT:
[email protected]1a93d8d2013-10-27 23:09:20830 case LAUNCH_PROMPT:
[email protected]15d267b42013-02-14 23:43:32831 case POST_INSTALL_PERMISSIONS_PROMPT: {
[email protected]c82da8c42012-06-08 19:49:11832 prompt_.set_extension(extension_);
[email protected]32e7a9b2013-01-23 23:00:19833 prompt_.set_icon(gfx::Image::CreateFrom1xBitmap(icon_));
[email protected]c82da8c42012-06-08 19:49:11834 break;
835 }
836 case BUNDLE_INSTALL_PROMPT: {
837 prompt_.set_bundle(bundle_);
[email protected]c82da8c42012-06-08 19:49:11838 break;
839 }
840 default:
841 NOTREACHED() << "Unknown message";
[email protected]af6efb22012-10-12 02:23:05842 return;
[email protected]c82da8c42012-06-08 19:49:11843 }
[email protected]af6efb22012-10-12 02:23:05844
845 if (AutoConfirmPrompt(delegate_))
846 return;
847
[email protected]5db2e882012-12-20 10:17:26848 if (show_dialog_callback_.is_null())
849 GetDefaultShowDialogCallback().Run(show_params_, delegate_, prompt_);
850 else
851 show_dialog_callback_.Run(show_params_, delegate_, prompt_);
[email protected]c82da8c42012-06-08 19:49:11852}