blob: b79e904511e7839c9aad55ebe7d6d1aa68e2467f [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]21db9ef2014-05-16 02:06:2729#include "extensions/browser/extension_prefs.h"
[email protected]411f8ae2014-05-22 11:12:2330#include "extensions/browser/extension_util.h"
[email protected]cda103d2014-04-04 16:22:3931#include "extensions/common/constants.h"
[email protected]e4452d32013-11-15 23:07:4132#include "extensions/common/extension.h"
[email protected]4b7908842014-04-07 23:50:2233#include "extensions/common/extension_icon_set.h"
[email protected]993da5e2013-03-23 21:25:1634#include "extensions/common/extension_resource.h"
[email protected]5ef835a2013-11-08 20:42:5735#include "extensions/common/feature_switch.h"
[email protected]d42c11152013-08-22 19:36:3236#include "extensions/common/manifest.h"
[email protected]6bf90612013-08-15 00:36:2737#include "extensions/common/manifest_constants.h"
[email protected]0db486f2014-04-09 19:32:2238#include "extensions/common/manifest_handlers/icons_handler.h"
[email protected]c41003472013-10-19 15:37:2539#include "extensions/common/permissions/permission_message_provider.h"
[email protected]5a55f3f2013-10-29 01:08:2940#include "extensions/common/permissions/permission_set.h"
[email protected]e4452d32013-11-15 23:07:4141#include "extensions/common/permissions/permissions_data.h"
[email protected]885c0e92012-11-13 20:27:4242#include "extensions/common/url_pattern.h"
[email protected]c82da8c42012-06-08 19:49:1143#include "grit/chromium_strings.h"
44#include "grit/generated_resources.h"
[email protected]2a281332012-07-11 22:20:2345#include "grit/theme_resources.h"
[email protected]c82da8c42012-06-08 19:49:1146#include "ui/base/l10n/l10n_util.h"
47#include "ui/base/resource/resource_bundle.h"
48#include "ui/gfx/image/image.h"
49
[email protected]c82da8c42012-06-08 19:49:1150using extensions::BundleInstaller;
51using extensions::Extension;
[email protected]1d5e58b2013-01-31 08:41:4052using extensions::Manifest;
[email protected]c2e66e12012-06-27 06:27:0653using extensions::PermissionSet;
[email protected]c82da8c42012-06-08 19:49:1154
[email protected]612a1cb12012-10-17 13:18:0355namespace {
56
[email protected]c82da8c42012-06-08 19:49:1157static const int kTitleIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
[email protected]21db9ef2014-05-16 02:06:2758 0, // The regular install prompt depends on what's being installed.
59 IDS_EXTENSION_INLINE_INSTALL_PROMPT_TITLE,
60 IDS_EXTENSION_INSTALL_PROMPT_TITLE,
61 IDS_EXTENSION_RE_ENABLE_PROMPT_TITLE,
62 IDS_EXTENSION_PERMISSIONS_PROMPT_TITLE,
63 IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_TITLE,
64 IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_TITLE,
65 IDS_EXTENSION_LAUNCH_APP_PROMPT_TITLE,
66 0, // The remote install prompt depends on what's being installed.
[email protected]c82da8c42012-06-08 19:49:1167};
68static const int kHeadingIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
[email protected]21db9ef2014-05-16 02:06:2769 IDS_EXTENSION_INSTALL_PROMPT_HEADING,
70 0, // Inline installs use the extension name.
71 0, // Heading for bundle installs depends on the bundle contents.
72 IDS_EXTENSION_RE_ENABLE_PROMPT_HEADING,
73 IDS_EXTENSION_PERMISSIONS_PROMPT_HEADING,
74 0, // External installs use different strings for extensions/apps.
75 IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_HEADING,
76 IDS_EXTENSION_LAUNCH_APP_PROMPT_HEADING,
77 IDS_EXTENSION_REMOTE_INSTALL_PROMPT_HEADING,
[email protected]15d267b42013-02-14 23:43:3278};
79static const int kButtons[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
[email protected]21db9ef2014-05-16 02:06:2780 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_OK | ui::DIALOG_BUTTON_CANCEL,
84 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
85 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
86 ui::DIALOG_BUTTON_CANCEL,
87 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
88 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
[email protected]c82da8c42012-06-08 19:49:1189};
90static const int kAcceptButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
[email protected]21db9ef2014-05-16 02:06:2791 IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
92 IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
93 IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
94 IDS_EXTENSION_PROMPT_RE_ENABLE_BUTTON,
95 IDS_EXTENSION_PROMPT_PERMISSIONS_BUTTON,
96 0, // External installs use different strings for extensions/apps.
97 IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_FILES_BUTTON,
98 IDS_EXTENSION_PROMPT_LAUNCH_BUTTON,
99 IDS_EXTENSION_PROMPT_REMOTE_INSTALL_BUTTON,
[email protected]c82da8c42012-06-08 19:49:11100};
101static const int kAbortButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
[email protected]21db9ef2014-05-16 02:06:27102 0, // These all use the platform's default cancel label.
103 0,
104 0,
105 0,
106 IDS_EXTENSION_PROMPT_PERMISSIONS_ABORT_BUTTON,
107 IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ABORT_BUTTON,
108 IDS_CLOSE,
109 0, // Platform dependent cancel button.
110 0,
[email protected]c82da8c42012-06-08 19:49:11111};
[email protected]21db9ef2014-05-16 02:06:27112static const int
113 kPermissionsHeaderIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
114 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
115 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
116 IDS_EXTENSION_PROMPT_THESE_WILL_HAVE_ACCESS_TO,
117 IDS_EXTENSION_PROMPT_WILL_NOW_HAVE_ACCESS_TO,
118 IDS_EXTENSION_PROMPT_WANTS_ACCESS_TO,
119 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
120 IDS_EXTENSION_PROMPT_CAN_ACCESS,
121 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
122 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
[email protected]c82da8c42012-06-08 19:49:11123};
[email protected]612a1cb12012-10-17 13:18:03124static const int kOAuthHeaderIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
[email protected]21db9ef2014-05-16 02:06:27125 IDS_EXTENSION_PROMPT_OAUTH_HEADER,
126 0, // Inline installs don't show OAuth permissions.
127 0, // Bundle installs don't show OAuth permissions.
128 IDS_EXTENSION_PROMPT_OAUTH_REENABLE_HEADER,
129 IDS_EXTENSION_PROMPT_OAUTH_PERMISSIONS_HEADER,
130 0,
131 0,
132 IDS_EXTENSION_PROMPT_OAUTH_HEADER,
133 IDS_EXTENSION_PROMPT_OAUTH_HEADER,
[email protected]fc5077942012-08-15 21:37:59134};
[email protected]c82da8c42012-06-08 19:49:11135
[email protected]c82da8c42012-06-08 19:49:11136// Size of extension icon in top left of dialog.
137const int kIconSize = 69;
138
[email protected]dd46a4ce2012-09-15 10:50:50139// Returns pixel size under maximal scale factor for the icon whose device
140// independent size is |size_in_dip|
141int GetSizeForMaxScaleFactor(int size_in_dip) {
[email protected]50b66262013-09-24 03:25:48142 return static_cast<int>(size_in_dip * gfx::ImageSkia::GetMaxSupportedScale());
[email protected]dd46a4ce2012-09-15 10:50:50143}
144
145// Returns bitmap for the default icon with size equal to the default icon's
146// pixel size under maximal supported scale factor.
147SkBitmap GetDefaultIconBitmapForMaxScaleFactor(bool is_app) {
[email protected]702d8b42013-02-27 20:55:50148 const gfx::ImageSkia& image = is_app ?
[email protected]7eb20e32014-04-30 08:50:56149 extensions::util::GetDefaultAppIcon() :
150 extensions::util::GetDefaultExtensionIcon();
[email protected]50b66262013-09-24 03:25:48151 return image.GetRepresentation(
152 gfx::ImageSkia::GetMaxSupportedScale()).sk_bitmap();
[email protected]dd46a4ce2012-09-15 10:50:50153}
154
[email protected]af6efb22012-10-12 02:23:05155// If auto confirm is enabled then posts a task to proceed with or cancel the
156// install and returns true. Otherwise returns false.
157bool AutoConfirmPrompt(ExtensionInstallPrompt::Delegate* delegate) {
158 const CommandLine* cmdline = CommandLine::ForCurrentProcess();
159 if (!cmdline->HasSwitch(switches::kAppsGalleryInstallAutoConfirmForTests))
160 return false;
161 std::string value = cmdline->GetSwitchValueASCII(
162 switches::kAppsGalleryInstallAutoConfirmForTests);
163
164 // We use PostTask instead of calling the delegate directly here, because in
165 // the real implementations it's highly likely the message loop will be
166 // pumping a few times before the user clicks accept or cancel.
167 if (value == "accept") {
[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::InstallUIProceed,
171 base::Unretained(delegate)));
172 return true;
173 }
174
175 if (value == "cancel") {
[email protected]b3a25092013-05-28 22:08:16176 base::MessageLoop::current()->PostTask(
[email protected]af6efb22012-10-12 02:23:05177 FROM_HERE,
178 base::Bind(&ExtensionInstallPrompt::Delegate::InstallUIAbort,
179 base::Unretained(delegate),
180 true));
181 return true;
182 }
183
184 NOTREACHED();
185 return false;
186}
187
[email protected]91e51d612012-10-21 23:03:05188Profile* ProfileForWebContents(content::WebContents* web_contents) {
189 if (!web_contents)
190 return NULL;
191 return Profile::FromBrowserContext(web_contents->GetBrowserContext());
192}
193
[email protected]5db2e882012-12-20 10:17:26194gfx::NativeWindow NativeWindowForWebContents(content::WebContents* contents) {
195 if (!contents)
196 return NULL;
197
[email protected]fc2b46b2014-05-03 16:33:45198 return contents->GetTopLevelNativeWindow();
[email protected]5db2e882012-12-20 10:17:26199}
200
[email protected]c82da8c42012-06-08 19:49:11201} // namespace
202
[email protected]5db2e882012-12-20 10:17:26203ExtensionInstallPrompt::Prompt::Prompt(PromptType type)
[email protected]c82da8c42012-06-08 19:49:11204 : type_(type),
[email protected]79a6f99a2013-08-29 00:32:58205 is_showing_details_for_retained_files_(false),
[email protected]c82da8c42012-06-08 19:49:11206 extension_(NULL),
207 bundle_(NULL),
208 average_rating_(0.0),
[email protected]dcde34b32013-07-31 02:28:45209 rating_count_(0),
[email protected]34b5f7f2014-01-29 02:48:11210 show_user_count_(false),
211 has_webstore_data_(false) {
[email protected]c82da8c42012-06-08 19:49:11212}
213
214ExtensionInstallPrompt::Prompt::~Prompt() {
215}
216
217void ExtensionInstallPrompt::Prompt::SetPermissions(
[email protected]d2065e062013-12-12 23:49:52218 const std::vector<base::string16>& permissions) {
[email protected]c82da8c42012-06-08 19:49:11219 permissions_ = permissions;
220}
221
[email protected]8ab7e6c2013-07-11 21:15:03222void ExtensionInstallPrompt::Prompt::SetPermissionsDetails(
[email protected]d2065e062013-12-12 23:49:52223 const std::vector<base::string16>& details) {
[email protected]8ab7e6c2013-07-11 21:15:03224 details_ = details;
[email protected]79a6f99a2013-08-29 00:32:58225 is_showing_details_for_permissions_.clear();
226 for (size_t i = 0; i < details.size(); ++i)
227 is_showing_details_for_permissions_.push_back(false);
228}
229
230void ExtensionInstallPrompt::Prompt::SetIsShowingDetails(
231 DetailsType type,
232 size_t index,
233 bool is_showing_details) {
234 switch (type) {
235 case PERMISSIONS_DETAILS:
236 is_showing_details_for_permissions_[index] = is_showing_details;
237 break;
238 case OAUTH_DETAILS:
239 is_showing_details_for_oauth_[index] = is_showing_details;
240 break;
241 case RETAINED_FILES_DETAILS:
242 is_showing_details_for_retained_files_ = is_showing_details;
243 break;
244 }
[email protected]8ab7e6c2013-07-11 21:15:03245}
246
[email protected]b70a2d92012-06-28 19:51:21247void ExtensionInstallPrompt::Prompt::SetOAuthIssueAdvice(
248 const IssueAdviceInfo& issue_advice) {
[email protected]79a6f99a2013-08-29 00:32:58249 is_showing_details_for_oauth_.clear();
250 for (size_t i = 0; i < issue_advice.size(); ++i)
251 is_showing_details_for_oauth_.push_back(false);
252
[email protected]b70a2d92012-06-28 19:51:21253 oauth_issue_advice_ = issue_advice;
254}
255
[email protected]5db2e882012-12-20 10:17:26256void ExtensionInstallPrompt::Prompt::SetUserNameFromProfile(Profile* profile) {
257 // |profile| can be NULL in unit tests.
258 if (profile) {
[email protected]04338722013-12-24 23:18:05259 oauth_user_name_ = base::UTF8ToUTF16(profile->GetPrefs()->GetString(
[email protected]5db2e882012-12-20 10:17:26260 prefs::kGoogleServicesUsername));
261 } else {
262 oauth_user_name_.clear();
263 }
264}
265
[email protected]34b5f7f2014-01-29 02:48:11266void ExtensionInstallPrompt::Prompt::SetWebstoreData(
[email protected]c82da8c42012-06-08 19:49:11267 const std::string& localized_user_count,
[email protected]dcde34b32013-07-31 02:28:45268 bool show_user_count,
[email protected]c82da8c42012-06-08 19:49:11269 double average_rating,
270 int rating_count) {
[email protected]34b5f7f2014-01-29 02:48:11271 CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
[email protected]c82da8c42012-06-08 19:49:11272 localized_user_count_ = localized_user_count;
[email protected]dcde34b32013-07-31 02:28:45273 show_user_count_ = show_user_count;
[email protected]c82da8c42012-06-08 19:49:11274 average_rating_ = average_rating;
275 rating_count_ = rating_count;
[email protected]34b5f7f2014-01-29 02:48:11276 has_webstore_data_ = true;
[email protected]c82da8c42012-06-08 19:49:11277}
278
[email protected]6a72a632013-12-12 22:22:00279base::string16 ExtensionInstallPrompt::Prompt::GetDialogTitle() const {
[email protected]c82da8c42012-06-08 19:49:11280 int resource_id = kTitleIds[type_];
281
282 if (type_ == INSTALL_PROMPT) {
283 if (extension_->is_app())
284 resource_id = IDS_EXTENSION_INSTALL_APP_PROMPT_TITLE;
285 else if (extension_->is_theme())
286 resource_id = IDS_EXTENSION_INSTALL_THEME_PROMPT_TITLE;
287 else
288 resource_id = IDS_EXTENSION_INSTALL_EXTENSION_PROMPT_TITLE;
[email protected]612a1cb12012-10-17 13:18:03289 } else if (type_ == EXTERNAL_INSTALL_PROMPT) {
290 return l10n_util::GetStringFUTF16(
[email protected]04338722013-12-24 23:18:05291 resource_id, base::UTF8ToUTF16(extension_->name()));
[email protected]21db9ef2014-05-16 02:06:27292 } else if (type_ == REMOTE_INSTALL_PROMPT) {
293 if (extension_->is_app())
294 resource_id = IDS_EXTENSION_REMOTE_INSTALL_APP_PROMPT_TITLE;
295 else
296 resource_id = IDS_EXTENSION_REMOTE_INSTALL_EXTENSION_PROMPT_TITLE;
[email protected]c82da8c42012-06-08 19:49:11297 }
298
299 return l10n_util::GetStringUTF16(resource_id);
300}
301
[email protected]6a72a632013-12-12 22:22:00302base::string16 ExtensionInstallPrompt::Prompt::GetHeading() const {
[email protected]c82da8c42012-06-08 19:49:11303 if (type_ == INLINE_INSTALL_PROMPT) {
[email protected]04338722013-12-24 23:18:05304 return base::UTF8ToUTF16(extension_->name());
[email protected]c82da8c42012-06-08 19:49:11305 } else if (type_ == BUNDLE_INSTALL_PROMPT) {
306 return bundle_->GetHeadingTextFor(BundleInstaller::Item::STATE_PENDING);
[email protected]612a1cb12012-10-17 13:18:03307 } else if (type_ == EXTERNAL_INSTALL_PROMPT) {
[email protected]846606012012-10-19 18:42:25308 int resource_id = -1;
309 if (extension_->is_app())
310 resource_id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_HEADING_APP;
311 else if (extension_->is_theme())
312 resource_id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_HEADING_THEME;
313 else
314 resource_id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_HEADING_EXTENSION;
315 return l10n_util::GetStringUTF16(resource_id);
[email protected]c82da8c42012-06-08 19:49:11316 } else {
317 return l10n_util::GetStringFUTF16(
[email protected]04338722013-12-24 23:18:05318 kHeadingIds[type_], base::UTF8ToUTF16(extension_->name()));
[email protected]c82da8c42012-06-08 19:49:11319 }
320}
321
[email protected]15d267b42013-02-14 23:43:32322int ExtensionInstallPrompt::Prompt::GetDialogButtons() const {
[email protected]a2886e8b2013-06-08 05:15:02323 if (type_ == POST_INSTALL_PERMISSIONS_PROMPT &&
324 ShouldDisplayRevokeFilesButton()) {
325 return kButtons[type_] | ui::DIALOG_BUTTON_OK;
326 }
327
[email protected]15d267b42013-02-14 23:43:32328 return kButtons[type_];
329}
330
[email protected]62a28d7c2013-12-28 01:34:49331bool ExtensionInstallPrompt::Prompt::ShouldShowExplanationText() const {
332 return type_ == INSTALL_PROMPT &&
333 extension_->is_extension() && experiment_ && experiment_->text_only();
334}
335
[email protected]15d267b42013-02-14 23:43:32336bool ExtensionInstallPrompt::Prompt::HasAcceptButtonLabel() const {
[email protected]a2886e8b2013-06-08 05:15:02337 if (kAcceptButtonIds[type_] == 0)
338 return false;
339
340 if (type_ == POST_INSTALL_PERMISSIONS_PROMPT)
341 return ShouldDisplayRevokeFilesButton();
342
343 return true;
[email protected]15d267b42013-02-14 23:43:32344}
345
[email protected]6a72a632013-12-12 22:22:00346base::string16 ExtensionInstallPrompt::Prompt::GetAcceptButtonLabel() const {
[email protected]846606012012-10-19 18:42:25347 if (type_ == EXTERNAL_INSTALL_PROMPT) {
348 int id = -1;
349 if (extension_->is_app())
350 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_APP;
351 else if (extension_->is_theme())
352 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_THEME;
353 else
354 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_EXTENSION;
355 return l10n_util::GetStringUTF16(id);
356 }
[email protected]62a28d7c2013-12-28 01:34:49357 if (ShouldShowExplanationText())
358 return experiment_->GetOkButtonText();
[email protected]c82da8c42012-06-08 19:49:11359 return l10n_util::GetStringUTF16(kAcceptButtonIds[type_]);
360}
361
362bool ExtensionInstallPrompt::Prompt::HasAbortButtonLabel() const {
[email protected]62a28d7c2013-12-28 01:34:49363 if (ShouldShowExplanationText())
364 return true;
[email protected]c82da8c42012-06-08 19:49:11365 return kAbortButtonIds[type_] > 0;
366}
367
[email protected]6a72a632013-12-12 22:22:00368base::string16 ExtensionInstallPrompt::Prompt::GetAbortButtonLabel() const {
[email protected]c82da8c42012-06-08 19:49:11369 CHECK(HasAbortButtonLabel());
[email protected]62a28d7c2013-12-28 01:34:49370 if (ShouldShowExplanationText())
371 return experiment_->GetCancelButtonText();
[email protected]c82da8c42012-06-08 19:49:11372 return l10n_util::GetStringUTF16(kAbortButtonIds[type_]);
373}
374
[email protected]6a72a632013-12-12 22:22:00375base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsHeading() const {
[email protected]c82da8c42012-06-08 19:49:11376 return l10n_util::GetStringUTF16(kPermissionsHeaderIds[type_]);
377}
378
[email protected]6a72a632013-12-12 22:22:00379base::string16 ExtensionInstallPrompt::Prompt::GetOAuthHeading() const {
[email protected]5db2e882012-12-20 10:17:26380 return l10n_util::GetStringFUTF16(kOAuthHeaderIds[type_], oauth_user_name_);
[email protected]813475e2012-07-02 23:54:18381}
382
[email protected]6a72a632013-12-12 22:22:00383base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFilesHeading() const {
[email protected]4f1e1082013-09-23 10:30:53384 const int kRetainedFilesMessageIDs[6] = {
385 IDS_EXTENSION_PROMPT_RETAINED_FILES_DEFAULT,
386 IDS_EXTENSION_PROMPT_RETAINED_FILE_SINGULAR,
387 IDS_EXTENSION_PROMPT_RETAINED_FILES_ZERO,
388 IDS_EXTENSION_PROMPT_RETAINED_FILES_TWO,
389 IDS_EXTENSION_PROMPT_RETAINED_FILES_FEW,
390 IDS_EXTENSION_PROMPT_RETAINED_FILES_MANY,
391 };
392 std::vector<int> message_ids;
393 for (size_t i = 0; i < arraysize(kRetainedFilesMessageIDs); i++) {
394 message_ids.push_back(kRetainedFilesMessageIDs[i]);
395 }
396 return l10n_util::GetPluralStringFUTF16(message_ids, GetRetainedFileCount());
[email protected]8ab7e6c2013-07-11 21:15:03397}
398
[email protected]f2cd8992013-06-11 17:30:18399bool ExtensionInstallPrompt::Prompt::ShouldShowPermissions() const {
400 return GetPermissionCount() > 0 || type_ == POST_INSTALL_PERMISSIONS_PROMPT;
401}
402
[email protected]c82da8c42012-06-08 19:49:11403void ExtensionInstallPrompt::Prompt::AppendRatingStars(
404 StarAppender appender, void* data) const {
405 CHECK(appender);
[email protected]34b5f7f2014-01-29 02:48:11406 CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
[email protected]c82da8c42012-06-08 19:49:11407 int rating_integer = floor(average_rating_);
408 double rating_fractional = average_rating_ - rating_integer;
409
410 if (rating_fractional > 0.66) {
411 rating_integer++;
412 }
413
414 if (rating_fractional < 0.33 || rating_fractional > 0.66) {
415 rating_fractional = 0;
416 }
417
418 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
419 int i;
420 for (i = 0; i < rating_integer; i++) {
421 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_ON), data);
422 }
423 if (rating_fractional) {
424 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_HALF_LEFT), data);
425 i++;
426 }
427 for (; i < kMaxExtensionRating; i++) {
428 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_OFF), data);
429 }
430}
431
[email protected]6a72a632013-12-12 22:22:00432base::string16 ExtensionInstallPrompt::Prompt::GetRatingCount() const {
[email protected]34b5f7f2014-01-29 02:48:11433 CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
[email protected]6725048e2013-10-24 21:47:14434 return l10n_util::GetStringFUTF16(IDS_EXTENSION_RATING_COUNT,
435 base::IntToString16(rating_count_));
[email protected]c82da8c42012-06-08 19:49:11436}
437
[email protected]6a72a632013-12-12 22:22:00438base::string16 ExtensionInstallPrompt::Prompt::GetUserCount() const {
[email protected]34b5f7f2014-01-29 02:48:11439 CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
[email protected]dcde34b32013-07-31 02:28:45440
441 if (show_user_count_) {
[email protected]6725048e2013-10-24 21:47:14442 return l10n_util::GetStringFUTF16(IDS_EXTENSION_USER_COUNT,
443 base::UTF8ToUTF16(localized_user_count_));
[email protected]dcde34b32013-07-31 02:28:45444 }
[email protected]6725048e2013-10-24 21:47:14445 return base::string16();
[email protected]c82da8c42012-06-08 19:49:11446}
447
448size_t ExtensionInstallPrompt::Prompt::GetPermissionCount() const {
449 return permissions_.size();
450}
451
[email protected]8ab7e6c2013-07-11 21:15:03452size_t ExtensionInstallPrompt::Prompt::GetPermissionsDetailsCount() const {
453 return details_.size();
454}
455
[email protected]6a72a632013-12-12 22:22:00456base::string16 ExtensionInstallPrompt::Prompt::GetPermission(size_t index)
457 const {
[email protected]c82da8c42012-06-08 19:49:11458 CHECK_LT(index, permissions_.size());
[email protected]ef2654e42012-08-11 03:57:56459 return permissions_[index];
[email protected]c82da8c42012-06-08 19:49:11460}
461
[email protected]6a72a632013-12-12 22:22:00462base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsDetails(
[email protected]8ab7e6c2013-07-11 21:15:03463 size_t index) const {
464 CHECK_LT(index, details_.size());
465 return details_[index];
466}
467
[email protected]79a6f99a2013-08-29 00:32:58468bool ExtensionInstallPrompt::Prompt::GetIsShowingDetails(
469 DetailsType type, size_t index) const {
470 switch (type) {
471 case PERMISSIONS_DETAILS:
472 CHECK_LT(index, is_showing_details_for_permissions_.size());
473 return is_showing_details_for_permissions_[index];
474 case OAUTH_DETAILS:
475 CHECK_LT(index, is_showing_details_for_oauth_.size());
476 return is_showing_details_for_oauth_[index];
477 case RETAINED_FILES_DETAILS:
478 return is_showing_details_for_retained_files_;
479 }
480 return false;
481}
482
[email protected]b70a2d92012-06-28 19:51:21483size_t ExtensionInstallPrompt::Prompt::GetOAuthIssueCount() const {
484 return oauth_issue_advice_.size();
485}
486
487const IssueAdviceInfoEntry& ExtensionInstallPrompt::Prompt::GetOAuthIssue(
488 size_t index) const {
489 CHECK_LT(index, oauth_issue_advice_.size());
490 return oauth_issue_advice_[index];
491}
492
[email protected]a2886e8b2013-06-08 05:15:02493size_t ExtensionInstallPrompt::Prompt::GetRetainedFileCount() const {
494 return retained_files_.size();
495}
496
[email protected]6a72a632013-12-12 22:22:00497base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFile(size_t index)
498 const {
[email protected]a2886e8b2013-06-08 05:15:02499 CHECK_LT(index, retained_files_.size());
[email protected]6725048e2013-10-24 21:47:14500 return retained_files_[index].AsUTF16Unsafe();
[email protected]a2886e8b2013-06-08 05:15:02501}
502
503bool ExtensionInstallPrompt::Prompt::ShouldDisplayRevokeFilesButton() const {
504 return !retained_files_.empty();
505}
506
[email protected]5db2e882012-12-20 10:17:26507ExtensionInstallPrompt::ShowParams::ShowParams(content::WebContents* contents)
508 : parent_web_contents(contents),
509 parent_window(NativeWindowForWebContents(contents)),
510 navigator(contents) {
511}
512
513ExtensionInstallPrompt::ShowParams::ShowParams(
514 gfx::NativeWindow window,
515 content::PageNavigator* navigator)
516 : parent_web_contents(NULL),
517 parent_window(window),
518 navigator(navigator) {
519}
520
[email protected]c82da8c42012-06-08 19:49:11521// static
522scoped_refptr<Extension>
523 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay(
[email protected]023b3d12013-12-23 18:46:49524 const base::DictionaryValue* manifest,
[email protected]c422a862012-07-31 15:46:13525 int flags,
[email protected]c82da8c42012-06-08 19:49:11526 const std::string& id,
527 const std::string& localized_name,
528 const std::string& localized_description,
529 std::string* error) {
[email protected]023b3d12013-12-23 18:46:49530 scoped_ptr<base::DictionaryValue> localized_manifest;
[email protected]c82da8c42012-06-08 19:49:11531 if (!localized_name.empty() || !localized_description.empty()) {
532 localized_manifest.reset(manifest->DeepCopy());
533 if (!localized_name.empty()) {
[email protected]6bf90612013-08-15 00:36:27534 localized_manifest->SetString(extensions::manifest_keys::kName,
[email protected]c82da8c42012-06-08 19:49:11535 localized_name);
536 }
537 if (!localized_description.empty()) {
[email protected]6bf90612013-08-15 00:36:27538 localized_manifest->SetString(extensions::manifest_keys::kDescription,
[email protected]c82da8c42012-06-08 19:49:11539 localized_description);
540 }
541 }
542
543 return Extension::Create(
[email protected]650b2d52013-02-10 03:41:45544 base::FilePath(),
[email protected]1d5e58b2013-01-31 08:41:40545 Manifest::INTERNAL,
[email protected]c82da8c42012-06-08 19:49:11546 localized_manifest.get() ? *localized_manifest.get() : *manifest,
[email protected]c422a862012-07-31 15:46:13547 flags,
[email protected]c82da8c42012-06-08 19:49:11548 id,
549 error);
550}
551
[email protected]7f165342014-02-12 09:22:22552ExtensionInstallPrompt::ExtensionInstallPrompt(content::WebContents* contents)
[email protected]f1e98482013-12-27 00:45:59553 : OAuth2TokenService::Consumer("extensions_install"),
554 record_oauth2_grant_(false),
[email protected]b3a25092013-05-28 22:08:16555 ui_loop_(base::MessageLoop::current()),
[email protected]c82da8c42012-06-08 19:49:11556 extension_(NULL),
[email protected]7f165342014-02-12 09:22:22557 bundle_(NULL),
[email protected]91e51d612012-10-21 23:03:05558 install_ui_(ExtensionInstallUI::Create(ProfileForWebContents(contents))),
[email protected]5db2e882012-12-20 10:17:26559 show_params_(contents),
[email protected]c82da8c42012-06-08 19:49:11560 delegate_(NULL),
[email protected]5db2e882012-12-20 10:17:26561 prompt_(UNSET_PROMPT_TYPE) {
562 prompt_.SetUserNameFromProfile(install_ui_->profile());
563}
564
565ExtensionInstallPrompt::ExtensionInstallPrompt(
566 Profile* profile,
567 gfx::NativeWindow native_window,
568 content::PageNavigator* navigator)
[email protected]f1e98482013-12-27 00:45:59569 : OAuth2TokenService::Consumer("extensions_install"),
570 record_oauth2_grant_(false),
[email protected]b3a25092013-05-28 22:08:16571 ui_loop_(base::MessageLoop::current()),
[email protected]5db2e882012-12-20 10:17:26572 extension_(NULL),
[email protected]7f165342014-02-12 09:22:22573 bundle_(NULL),
[email protected]5db2e882012-12-20 10:17:26574 install_ui_(ExtensionInstallUI::Create(profile)),
575 show_params_(native_window, navigator),
576 delegate_(NULL),
577 prompt_(UNSET_PROMPT_TYPE) {
578 prompt_.SetUserNameFromProfile(install_ui_->profile());
[email protected]c82da8c42012-06-08 19:49:11579}
580
581ExtensionInstallPrompt::~ExtensionInstallPrompt() {
582}
583
584void ExtensionInstallPrompt::ConfirmBundleInstall(
585 extensions::BundleInstaller* bundle,
[email protected]c2e66e12012-06-27 06:27:06586 const PermissionSet* permissions) {
[email protected]b3a25092013-05-28 22:08:16587 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]c82da8c42012-06-08 19:49:11588 bundle_ = bundle;
589 permissions_ = permissions;
590 delegate_ = bundle;
[email protected]5db2e882012-12-20 10:17:26591 prompt_.set_type(BUNDLE_INSTALL_PROMPT);
[email protected]c82da8c42012-06-08 19:49:11592
[email protected]4e494872013-09-06 09:13:54593 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11594}
595
[email protected]734bcec2012-10-08 20:29:05596void ExtensionInstallPrompt::ConfirmStandaloneInstall(
[email protected]c82da8c42012-06-08 19:49:11597 Delegate* delegate,
598 const Extension* extension,
599 SkBitmap* icon,
600 const ExtensionInstallPrompt::Prompt& prompt) {
[email protected]b3a25092013-05-28 22:08:16601 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]c82da8c42012-06-08 19:49:11602 extension_ = extension;
603 permissions_ = extension->GetActivePermissions();
604 delegate_ = delegate;
605 prompt_ = prompt;
[email protected]c82da8c42012-06-08 19:49:11606
607 SetIcon(icon);
[email protected]4e494872013-09-06 09:13:54608 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11609}
610
[email protected]af6efb22012-10-12 02:23:05611void ExtensionInstallPrompt::ConfirmWebstoreInstall(
612 Delegate* delegate,
613 const Extension* extension,
614 const SkBitmap* icon,
615 const ShowDialogCallback& show_dialog_callback) {
[email protected]c82da8c42012-06-08 19:49:11616 // SetIcon requires |extension_| to be set. ConfirmInstall will setup the
617 // remaining fields.
618 extension_ = extension;
619 SetIcon(icon);
[email protected]af6efb22012-10-12 02:23:05620 ConfirmInstall(delegate, extension, show_dialog_callback);
[email protected]c82da8c42012-06-08 19:49:11621}
622
[email protected]af6efb22012-10-12 02:23:05623void ExtensionInstallPrompt::ConfirmInstall(
624 Delegate* delegate,
625 const Extension* extension,
626 const ShowDialogCallback& show_dialog_callback) {
[email protected]b3a25092013-05-28 22:08:16627 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]c82da8c42012-06-08 19:49:11628 extension_ = extension;
629 permissions_ = extension->GetActivePermissions();
630 delegate_ = delegate;
[email protected]5db2e882012-12-20 10:17:26631 prompt_.set_type(INSTALL_PROMPT);
[email protected]af6efb22012-10-12 02:23:05632 show_dialog_callback_ = show_dialog_callback;
[email protected]c82da8c42012-06-08 19:49:11633
634 // We special-case themes to not show any confirm UI. Instead they are
635 // immediately installed, and then we show an infobar (see OnInstallSuccess)
636 // to allow the user to revert if they don't like it.
637 //
638 // We don't do this in the case where off-store extension installs are
639 // disabled because in that case, we don't show the dangerous download UI, so
640 // we need the UI confirmation.
641 if (extension->is_theme()) {
642 if (extension->from_webstore() ||
[email protected]544471a2012-10-13 05:27:09643 extensions::FeatureSwitch::easy_off_store_install()->IsEnabled()) {
[email protected]c82da8c42012-06-08 19:49:11644 delegate->InstallUIProceed();
645 return;
646 }
647 }
648
649 LoadImageIfNeeded();
650}
651
652void ExtensionInstallPrompt::ConfirmReEnable(Delegate* delegate,
653 const Extension* extension) {
[email protected]b3a25092013-05-28 22:08:16654 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]c82da8c42012-06-08 19:49:11655 extension_ = extension;
656 permissions_ = extension->GetActivePermissions();
657 delegate_ = delegate;
[email protected]21db9ef2014-05-16 02:06:27658 bool is_remote_install =
659 install_ui_->profile() &&
660 extensions::ExtensionPrefs::Get(install_ui_->profile())->HasDisableReason(
661 extension->id(), extensions::Extension::DISABLE_REMOTE_INSTALL);
[email protected]411f8ae2014-05-22 11:12:23662 bool is_ephemeral =
663 extensions::util::IsEphemeralApp(extension->id(), install_ui_->profile());
664 if (is_ephemeral)
[email protected]21db9ef2014-05-16 02:06:27665 prompt_.set_type(LAUNCH_PROMPT);
666 else if (is_remote_install)
667 prompt_.set_type(REMOTE_INSTALL_PROMPT);
668 else
669 prompt_.set_type(RE_ENABLE_PROMPT);
[email protected]c82da8c42012-06-08 19:49:11670 LoadImageIfNeeded();
671}
672
[email protected]612a1cb12012-10-17 13:18:03673void ExtensionInstallPrompt::ConfirmExternalInstall(
[email protected]c8ff7c9e2013-04-20 12:36:27674 Delegate* delegate,
675 const Extension* extension,
[email protected]34b5f7f2014-01-29 02:48:11676 const ShowDialogCallback& show_dialog_callback,
677 const Prompt& prompt) {
[email protected]b3a25092013-05-28 22:08:16678 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]612a1cb12012-10-17 13:18:03679 extension_ = extension;
680 permissions_ = extension->GetActivePermissions();
681 delegate_ = delegate;
[email protected]34b5f7f2014-01-29 02:48:11682 prompt_ = prompt;
[email protected]c8ff7c9e2013-04-20 12:36:27683 show_dialog_callback_ = show_dialog_callback;
[email protected]612a1cb12012-10-17 13:18:03684
685 LoadImageIfNeeded();
686}
687
[email protected]c82da8c42012-06-08 19:49:11688void ExtensionInstallPrompt::ConfirmPermissions(
689 Delegate* delegate,
690 const Extension* extension,
[email protected]c2e66e12012-06-27 06:27:06691 const PermissionSet* permissions) {
[email protected]b3a25092013-05-28 22:08:16692 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]c82da8c42012-06-08 19:49:11693 extension_ = extension;
694 permissions_ = permissions;
695 delegate_ = delegate;
[email protected]5db2e882012-12-20 10:17:26696 prompt_.set_type(PERMISSIONS_PROMPT);
[email protected]c82da8c42012-06-08 19:49:11697
698 LoadImageIfNeeded();
699}
700
[email protected]f746b3f2012-07-03 17:53:37701void ExtensionInstallPrompt::ConfirmIssueAdvice(
702 Delegate* delegate,
703 const Extension* extension,
704 const IssueAdviceInfo& issue_advice) {
[email protected]b3a25092013-05-28 22:08:16705 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]f746b3f2012-07-03 17:53:37706 extension_ = extension;
707 delegate_ = delegate;
[email protected]5db2e882012-12-20 10:17:26708 prompt_.set_type(PERMISSIONS_PROMPT);
[email protected]f746b3f2012-07-03 17:53:37709
710 record_oauth2_grant_ = true;
711 prompt_.SetOAuthIssueAdvice(issue_advice);
712
713 LoadImageIfNeeded();
714}
715
[email protected]a2886e8b2013-06-08 05:15:02716void ExtensionInstallPrompt::ReviewPermissions(
717 Delegate* delegate,
718 const Extension* extension,
719 const std::vector<base::FilePath>& retained_file_paths) {
[email protected]b3a25092013-05-28 22:08:16720 DCHECK(ui_loop_ == base::MessageLoop::current());
[email protected]15d267b42013-02-14 23:43:32721 extension_ = extension;
722 permissions_ = extension->GetActivePermissions();
[email protected]a2886e8b2013-06-08 05:15:02723 prompt_.set_retained_files(retained_file_paths);
[email protected]15d267b42013-02-14 23:43:32724 delegate_ = delegate;
725 prompt_.set_type(POST_INSTALL_PERMISSIONS_PROMPT);
726
727 LoadImageIfNeeded();
728}
729
[email protected]c82da8c42012-06-08 19:49:11730void ExtensionInstallPrompt::OnInstallSuccess(const Extension* extension,
731 SkBitmap* icon) {
732 extension_ = extension;
733 SetIcon(icon);
734
735 install_ui_->OnInstallSuccess(extension, &icon_);
736}
737
[email protected]bf3d9df2012-07-24 23:20:27738void ExtensionInstallPrompt::OnInstallFailure(
739 const extensions::CrxInstallerError& error) {
[email protected]c82da8c42012-06-08 19:49:11740 install_ui_->OnInstallFailure(error);
741}
742
743void ExtensionInstallPrompt::SetIcon(const SkBitmap* image) {
744 if (image)
745 icon_ = *image;
746 else
747 icon_ = SkBitmap();
[email protected]dd46a4ce2012-09-15 10:50:50748 if (icon_.empty()) {
749 // Let's set default icon bitmap whose size is equal to the default icon's
750 // pixel size under maximal supported scale factor. If the bitmap is larger
751 // than the one we need, it will be scaled down by the ui code.
752 icon_ = GetDefaultIconBitmapForMaxScaleFactor(extension_->is_app());
753 }
[email protected]c82da8c42012-06-08 19:49:11754}
755
[email protected]ec7de0c5a2012-11-16 07:40:47756void ExtensionInstallPrompt::OnImageLoaded(const gfx::Image& image) {
[email protected]c82da8c42012-06-08 19:49:11757 SetIcon(image.IsEmpty() ? NULL : image.ToSkBitmap());
[email protected]4e494872013-09-06 09:13:54758 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11759}
760
761void ExtensionInstallPrompt::LoadImageIfNeeded() {
762 // Bundle install prompts do not have an icon.
[email protected]5db2e882012-12-20 10:17:26763 // Also |install_ui_.profile()| can be NULL in unit tests.
764 if (!icon_.empty() || !install_ui_->profile()) {
[email protected]4e494872013-09-06 09:13:54765 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11766 return;
767 }
768
769 // Load the image asynchronously. For the response, check OnImageLoaded.
[email protected]993da5e2013-03-23 21:25:16770 extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
[email protected]702d8b42013-02-27 20:55:50771 extension_,
772 extension_misc::EXTENSION_ICON_LARGE,
773 ExtensionIconSet::MATCH_BIGGER);
[email protected]dd46a4ce2012-09-15 10:50:50774 // Load the icon whose pixel size is large enough to be displayed under
775 // maximal supported scale factor. UI code will scale the icon down if needed.
776 // TODO(tbarzic): We should use IconImage here and load the required bitmap
777 // lazily.
778 int pixel_size = GetSizeForMaxScaleFactor(kIconSize);
[email protected]5db2e882012-12-20 10:17:26779 extensions::ImageLoader::Get(install_ui_->profile())->LoadImageAsync(
[email protected]ec7de0c5a2012-11-16 07:40:47780 extension_, image, gfx::Size(pixel_size, pixel_size),
781 base::Bind(&ExtensionInstallPrompt::OnImageLoaded, AsWeakPtr()));
[email protected]c82da8c42012-06-08 19:49:11782}
783
[email protected]4f3fb352013-07-17 04:07:01784void ExtensionInstallPrompt::OnGetTokenSuccess(
785 const OAuth2TokenService::Request* request,
786 const std::string& access_token,
787 const base::Time& expiration_time) {
788 DCHECK_EQ(login_token_request_.get(), request);
789 login_token_request_.reset();
790
791 const extensions::OAuth2Info& oauth2_info =
792 extensions::OAuth2Info::GetOAuth2Info(extension_);
793
[email protected]b70a2d92012-06-28 19:51:21794 token_flow_.reset(new OAuth2MintTokenFlow(
[email protected]4f3fb352013-07-17 04:07:01795 install_ui_->profile()->GetRequestContext(),
[email protected]b70a2d92012-06-28 19:51:21796 this,
797 OAuth2MintTokenFlow::Parameters(
[email protected]4f3fb352013-07-17 04:07:01798 access_token,
[email protected]b70a2d92012-06-28 19:51:21799 extension_->id(),
800 oauth2_info.client_id,
[email protected]d4a37f1c2012-07-09 21:36:13801 oauth2_info.scopes,
[email protected]b70a2d92012-06-28 19:51:21802 OAuth2MintTokenFlow::MODE_ISSUE_ADVICE)));
803 token_flow_->Start();
804}
805
[email protected]4f3fb352013-07-17 04:07:01806void ExtensionInstallPrompt::OnGetTokenFailure(
807 const OAuth2TokenService::Request* request,
808 const GoogleServiceAuthError& error) {
809 DCHECK_EQ(login_token_request_.get(), request);
810 login_token_request_.reset();
811 ShowConfirmation();
812}
813
[email protected]b70a2d92012-06-28 19:51:21814void ExtensionInstallPrompt::OnIssueAdviceSuccess(
815 const IssueAdviceInfo& advice_info) {
816 prompt_.SetOAuthIssueAdvice(advice_info);
817 record_oauth2_grant_ = true;
818 ShowConfirmation();
819}
820
821void ExtensionInstallPrompt::OnMintTokenFailure(
822 const GoogleServiceAuthError& error) {
823 ShowConfirmation();
824}
825
[email protected]c82da8c42012-06-08 19:49:11826void ExtensionInstallPrompt::ShowConfirmation() {
[email protected]62a28d7c2013-12-28 01:34:49827 if (prompt_.type() == INSTALL_PROMPT)
828 prompt_.set_experiment(ExtensionInstallPromptExperiment::Find());
829 else
830 prompt_.set_experiment(ExtensionInstallPromptExperiment::ControlGroup());
831
[email protected]dc24976f2013-06-02 21:15:09832 if (permissions_.get() &&
[email protected]13c68b62013-05-17 11:29:05833 (!extension_ ||
834 !extensions::PermissionsData::ShouldSkipPermissionWarnings(
835 extension_))) {
[email protected]1d5e58b2013-01-31 08:41:40836 Manifest::Type extension_type = extension_ ?
837 extension_->GetType() : Manifest::TYPE_UNKNOWN;
[email protected]8ab7e6c2013-07-11 21:15:03838 prompt_.SetPermissions(
[email protected]c41003472013-10-19 15:37:25839 extensions::PermissionMessageProvider::Get()->
840 GetWarningMessages(permissions_, extension_type));
[email protected]8ab7e6c2013-07-11 21:15:03841 prompt_.SetPermissionsDetails(
[email protected]c41003472013-10-19 15:37:25842 extensions::PermissionMessageProvider::Get()->
843 GetWarningMessagesDetails(permissions_, extension_type));
[email protected]bebe1d02012-08-02 20:17:09844 }
[email protected]c82da8c42012-06-08 19:49:11845
[email protected]5db2e882012-12-20 10:17:26846 switch (prompt_.type()) {
[email protected]c82da8c42012-06-08 19:49:11847 case PERMISSIONS_PROMPT:
848 case RE_ENABLE_PROMPT:
849 case INLINE_INSTALL_PROMPT:
[email protected]612a1cb12012-10-17 13:18:03850 case EXTERNAL_INSTALL_PROMPT:
[email protected]15d267b42013-02-14 23:43:32851 case INSTALL_PROMPT:
[email protected]1a93d8d2013-10-27 23:09:20852 case LAUNCH_PROMPT:
[email protected]21db9ef2014-05-16 02:06:27853 case POST_INSTALL_PERMISSIONS_PROMPT:
854 case REMOTE_INSTALL_PROMPT: {
[email protected]c82da8c42012-06-08 19:49:11855 prompt_.set_extension(extension_);
[email protected]32e7a9b2013-01-23 23:00:19856 prompt_.set_icon(gfx::Image::CreateFrom1xBitmap(icon_));
[email protected]c82da8c42012-06-08 19:49:11857 break;
858 }
859 case BUNDLE_INSTALL_PROMPT: {
860 prompt_.set_bundle(bundle_);
[email protected]c82da8c42012-06-08 19:49:11861 break;
862 }
863 default:
864 NOTREACHED() << "Unknown message";
[email protected]af6efb22012-10-12 02:23:05865 return;
[email protected]c82da8c42012-06-08 19:49:11866 }
[email protected]af6efb22012-10-12 02:23:05867
868 if (AutoConfirmPrompt(delegate_))
869 return;
870
[email protected]5db2e882012-12-20 10:17:26871 if (show_dialog_callback_.is_null())
872 GetDefaultShowDialogCallback().Run(show_params_, delegate_, prompt_);
873 else
874 show_dialog_callback_.Run(show_params_, delegate_, prompt_);
[email protected]c82da8c42012-06-08 19:49:11875}