blob: 8e9d4e353d8fa9750da9e7e36f4830f7e18893a2 [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
dcheng1fc00f12015-12-26 22:18:037#include <utility>
8
rdevlin.cronin41593052016-01-08 01:40:129#include "base/callback_helpers.h"
skyostilf221b7de2015-06-11 20:36:3210#include "base/location.h"
dchengc963c7142016-04-08 03:55:2211#include "base/memory/ptr_util.h"
fdoray283082bd2016-06-02 20:18:4612#include "base/single_thread_task_runner.h"
[email protected]3ea1b182013-02-08 22:38:4113#include "base/strings/string_number_conversions.h"
[email protected]00e7bef2013-06-10 20:35:1714#include "base/strings/string_util.h"
[email protected]112158af2013-06-07 23:46:1815#include "base/strings/utf_string_conversions.h"
gabb15e19072016-05-11 20:45:4116#include "base/threading/thread_task_runner_handle.h"
pkotwicz2f181782014-10-29 17:33:4517#include "chrome/browser/extensions/extension_install_prompt_show_params.h"
[email protected]7eb20e32014-04-30 08:50:5618#include "chrome/browser/extensions/extension_util.h"
gpdavis.chromium0fbac4d2014-09-19 20:57:5419#include "chrome/browser/extensions/permissions_updater.h"
[email protected]c82da8c42012-06-08 19:49:1120#include "chrome/browser/profiles/profile.h"
pkotwicza57a1f322014-10-21 00:24:3021#include "chrome/browser/ui/extensions/extension_install_ui_factory.h"
[email protected]af39f002014-08-22 10:18:1822#include "chrome/grit/chromium_strings.h"
23#include "chrome/grit/generated_resources.h"
[email protected]91e51d612012-10-21 23:03:0524#include "content/public/browser/web_contents.h"
rdevlin.cronin66209492015-06-10 20:44:0525#include "extensions/browser/extension_dialog_auto_confirm.h"
[email protected]21db9ef2014-05-16 02:06:2726#include "extensions/browser/extension_prefs.h"
[email protected]411f8ae2014-05-22 11:12:2327#include "extensions/browser/extension_util.h"
[email protected]326e6f02014-06-20 04:53:3728#include "extensions/browser/image_loader.h"
pkotwicza57a1f322014-10-21 00:24:3029#include "extensions/browser/install/extension_install_ui.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"
treib7496f63c2015-03-04 12:18:5338#include "extensions/common/manifest_handlers/permissions_parser.h"
treibf9dce312015-08-27 17:33:3539#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"
drogerfaa2e032016-01-07 17:33:5342#include "grit/components_strings.h"
[email protected]2a281332012-07-11 22:20:2343#include "grit/theme_resources.h"
[email protected]c82da8c42012-06-08 19:49:1144#include "ui/base/l10n/l10n_util.h"
45#include "ui/base/resource/resource_bundle.h"
pkotwicz7fd01192014-10-09 04:43:5046#include "ui/base/ui_base_types.h"
rdevlin.cronin3fe4bd32016-01-12 18:45:4047#include "ui/gfx/image/image_skia.h"
[email protected]c82da8c42012-06-08 19:49:1148
[email protected]c82da8c42012-06-08 19:49:1149using extensions::Extension;
[email protected]1d5e58b2013-01-31 08:41:4050using extensions::Manifest;
treibf9dce312015-08-27 17:33:3551using extensions::PermissionMessage;
52using extensions::PermissionMessages;
[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
rdevlin.cronin5f6b69d2014-09-20 01:23:3557bool AllowWebstoreData(ExtensionInstallPrompt::PromptType type) {
58 return type == ExtensionInstallPrompt::INLINE_INSTALL_PROMPT ||
59 type == ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT ||
60 type == ExtensionInstallPrompt::REPAIR_PROMPT;
61}
62
[email protected]c82da8c42012-06-08 19:49:1163static const int kTitleIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
[email protected]21db9ef2014-05-16 02:06:2764 IDS_EXTENSION_INSTALL_PROMPT_TITLE,
treibd35862252015-06-15 12:50:5165 IDS_EXTENSION_INSTALL_PROMPT_TITLE,
treib3d41d9f2016-04-12 08:53:0166 0, // Deprecated.
[email protected]21db9ef2014-05-16 02:06:2767 IDS_EXTENSION_RE_ENABLE_PROMPT_TITLE,
68 IDS_EXTENSION_PERMISSIONS_PROMPT_TITLE,
treibd35862252015-06-15 12:50:5169 0, // External installs use different strings for extensions/apps/themes.
[email protected]21db9ef2014-05-16 02:06:2770 IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_TITLE,
71 IDS_EXTENSION_LAUNCH_APP_PROMPT_TITLE,
treibd35862252015-06-15 12:50:5172 IDS_EXTENSION_REMOTE_INSTALL_PROMPT_TITLE,
73 IDS_EXTENSION_REPAIR_PROMPT_TITLE,
74 IDS_EXTENSION_DELEGATED_INSTALL_PROMPT_TITLE,
treib3d41d9f2016-04-12 08:53:0175 0, // Deprecated.
[email protected]15d267b42013-02-14 23:43:3276};
77static const int kButtons[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
[email protected]21db9ef2014-05-16 02:06:2778 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_OK | ui::DIALOG_BUTTON_CANCEL,
treibd35862252015-06-15 12:50:5184 // The "OK" button in the post install permissions dialog allows revoking
85 // file/device access, and is only shown if such permissions exist; see
86 // ShouldDisplayRevokeButton().
[email protected]21db9ef2014-05-16 02:06:2787 ui::DIALOG_BUTTON_CANCEL,
88 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
89 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
rdevlin.cronin5f6b69d2014-09-20 01:23:3590 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
treib2d2f5372015-03-01 12:20:4991 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
treibe36431582015-06-24 15:59:0592 ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
[email protected]c82da8c42012-06-08 19:49:1193};
94static const int kAcceptButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
treibd35862252015-06-15 12:50:5195 0, // Regular installs use different strings for extensions/apps/themes.
96 0, // Inline installs as well.
[email protected]21db9ef2014-05-16 02:06:2797 IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
98 IDS_EXTENSION_PROMPT_RE_ENABLE_BUTTON,
99 IDS_EXTENSION_PROMPT_PERMISSIONS_BUTTON,
treibd35862252015-06-15 12:50:51100 0, // External installs use different strings for extensions/apps/themes.
reillygc64d3dd2014-09-29 21:10:11101 0, // Different strings depending on the files and devices retained.
[email protected]21db9ef2014-05-16 02:06:27102 IDS_EXTENSION_PROMPT_LAUNCH_BUTTON,
treibd35862252015-06-15 12:50:51103 0, // Remote installs use different strings for extensions/apps.
104 0, // Repairs use different strings for extensions/apps.
mamir5de9de92016-05-12 17:28:02105 IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
treibe36431582015-06-24 15:59:05106 IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
[email protected]c82da8c42012-06-08 19:49:11107};
108static const int kAbortButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
treibd35862252015-06-15 12:50:51109 IDS_CANCEL,
110 IDS_CANCEL,
111 IDS_CANCEL,
112 IDS_CANCEL,
[email protected]21db9ef2014-05-16 02:06:27113 IDS_EXTENSION_PROMPT_PERMISSIONS_ABORT_BUTTON,
114 IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ABORT_BUTTON,
115 IDS_CLOSE,
treibd35862252015-06-15 12:50:51116 IDS_CANCEL,
117 IDS_CANCEL,
118 IDS_CANCEL,
119 IDS_CANCEL,
treibe36431582015-06-24 15:59:05120 IDS_CANCEL,
[email protected]c82da8c42012-06-08 19:49:11121};
[email protected]21db9ef2014-05-16 02:06:27122static const int
123 kPermissionsHeaderIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
124 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
125 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
126 IDS_EXTENSION_PROMPT_THESE_WILL_HAVE_ACCESS_TO,
127 IDS_EXTENSION_PROMPT_WILL_NOW_HAVE_ACCESS_TO,
128 IDS_EXTENSION_PROMPT_WANTS_ACCESS_TO,
129 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
130 IDS_EXTENSION_PROMPT_CAN_ACCESS,
131 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
132 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
rdevlin.cronin5f6b69d2014-09-20 01:23:35133 IDS_EXTENSION_PROMPT_CAN_ACCESS,
treib2d2f5372015-03-01 12:20:49134 IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
treibe36431582015-06-24 15:59:05135 IDS_EXTENSION_PROMPT_THESE_WILL_HAVE_ACCESS_TO,
[email protected]c82da8c42012-06-08 19:49:11136};
137
[email protected]dd46a4ce2012-09-15 10:50:50138// Returns bitmap for the default icon with size equal to the default icon's
139// pixel size under maximal supported scale factor.
140SkBitmap GetDefaultIconBitmapForMaxScaleFactor(bool is_app) {
[email protected]702d8b42013-02-27 20:55:50141 const gfx::ImageSkia& image = is_app ?
[email protected]7eb20e32014-04-30 08:50:56142 extensions::util::GetDefaultAppIcon() :
143 extensions::util::GetDefaultExtensionIcon();
[email protected]50b66262013-09-24 03:25:48144 return image.GetRepresentation(
145 gfx::ImageSkia::GetMaxSupportedScale()).sk_bitmap();
[email protected]dd46a4ce2012-09-15 10:50:50146}
147
[email protected]af6efb22012-10-12 02:23:05148// If auto confirm is enabled then posts a task to proceed with or cancel the
149// install and returns true. Otherwise returns false.
rdevlin.cronin41593052016-01-08 01:40:12150bool AutoConfirmPrompt(ExtensionInstallPrompt::DoneCallback* callback) {
rdevlin.cronin66209492015-06-10 20:44:05151 switch (extensions::ScopedTestDialogAutoConfirm::GetAutoConfirmValue()) {
152 case extensions::ScopedTestDialogAutoConfirm::NONE:
[email protected]2a74d6f62014-07-24 11:53:47153 return false;
rdevlin.cronin41593052016-01-08 01:40:12154 // We use PostTask instead of calling the callback directly here, because in
[email protected]2a74d6f62014-07-24 11:53:47155 // the real implementations it's highly likely the message loop will be
156 // pumping a few times before the user clicks accept or cancel.
rdevlin.cronin66209492015-06-10 20:44:05157 case extensions::ScopedTestDialogAutoConfirm::ACCEPT:
fdoray283082bd2016-06-02 20:18:46158 base::ThreadTaskRunnerHandle::Get()->PostTask(
rdevlin.cronin41593052016-01-08 01:40:12159 FROM_HERE, base::Bind(base::ResetAndReturn(callback),
160 ExtensionInstallPrompt::Result::ACCEPTED));
[email protected]2a74d6f62014-07-24 11:53:47161 return true;
rdevlin.cronin66209492015-06-10 20:44:05162 case extensions::ScopedTestDialogAutoConfirm::CANCEL:
skyostilf221b7de2015-06-11 20:36:32163 base::ThreadTaskRunnerHandle::Get()->PostTask(
rdevlin.cronin41593052016-01-08 01:40:12164 FROM_HERE, base::Bind(base::ResetAndReturn(callback),
165 ExtensionInstallPrompt::Result::USER_CANCELED));
[email protected]2a74d6f62014-07-24 11:53:47166 return true;
[email protected]af6efb22012-10-12 02:23:05167 }
168
169 NOTREACHED();
170 return false;
171}
172
[email protected]91e51d612012-10-21 23:03:05173Profile* ProfileForWebContents(content::WebContents* web_contents) {
174 if (!web_contents)
175 return NULL;
176 return Profile::FromBrowserContext(web_contents->GetBrowserContext());
177}
178
[email protected]c82da8c42012-06-08 19:49:11179} // namespace
180
gpdavis.chromium0fbac4d2014-09-19 20:57:54181ExtensionInstallPrompt::Prompt::InstallPromptPermissions::
182 InstallPromptPermissions() {
183}
184ExtensionInstallPrompt::Prompt::InstallPromptPermissions::
185 ~InstallPromptPermissions() {
186}
187
rdevlin.cronin092c6772014-11-20 23:52:40188ExtensionInstallPrompt::PromptType
189ExtensionInstallPrompt::g_last_prompt_type_for_tests =
190 ExtensionInstallPrompt::UNSET_PROMPT_TYPE;
191
[email protected]eeb0d3e12014-08-15 15:10:44192// This should match the PromptType enum.
193std::string ExtensionInstallPrompt::PromptTypeToString(PromptType type) {
194 switch (type) {
195 case ExtensionInstallPrompt::INSTALL_PROMPT:
196 return "INSTALL_PROMPT";
197 case ExtensionInstallPrompt::INLINE_INSTALL_PROMPT:
198 return "INLINE_INSTALL_PROMPT";
[email protected]eeb0d3e12014-08-15 15:10:44199 case ExtensionInstallPrompt::RE_ENABLE_PROMPT:
200 return "RE_ENABLE_PROMPT";
201 case ExtensionInstallPrompt::PERMISSIONS_PROMPT:
202 return "PERMISSIONS_PROMPT";
203 case ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT:
204 return "EXTERNAL_INSTALL_PROMPT";
205 case ExtensionInstallPrompt::POST_INSTALL_PERMISSIONS_PROMPT:
206 return "POST_INSTALL_PERMISSIONS_PROMPT";
[email protected]eeb0d3e12014-08-15 15:10:44207 case ExtensionInstallPrompt::REMOTE_INSTALL_PROMPT:
208 return "REMOTE_INSTALL_PROMPT";
rdevlin.cronin5f6b69d2014-09-20 01:23:35209 case ExtensionInstallPrompt::REPAIR_PROMPT:
210 return "REPAIR_PROMPT";
treib2d2f5372015-03-01 12:20:49211 case ExtensionInstallPrompt::DELEGATED_PERMISSIONS_PROMPT:
212 return "DELEGATED_PERMISSIONS_PROMPT";
benwells1dd4acd2015-12-09 02:20:24213 case ExtensionInstallPrompt::LAUNCH_PROMPT_DEPRECATED:
treib3d41d9f2016-04-12 08:53:01214 case ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT_DEPRECATED:
215 case ExtensionInstallPrompt::DELEGATED_BUNDLE_PERMISSIONS_PROMPT_DEPRECATED:
benwells1dd4acd2015-12-09 02:20:24216 NOTREACHED();
217 // fall through:
[email protected]eeb0d3e12014-08-15 15:10:44218 case ExtensionInstallPrompt::UNSET_PROMPT_TYPE:
219 case ExtensionInstallPrompt::NUM_PROMPT_TYPES:
220 break;
221 }
222 return "OTHER";
223}
224
[email protected]5db2e882012-12-20 10:17:26225ExtensionInstallPrompt::Prompt::Prompt(PromptType type)
[email protected]c82da8c42012-06-08 19:49:11226 : type_(type),
[email protected]79a6f99a2013-08-29 00:32:58227 is_showing_details_for_retained_files_(false),
reillygc64d3dd2014-09-29 21:10:11228 is_showing_details_for_retained_devices_(false),
[email protected]c82da8c42012-06-08 19:49:11229 extension_(NULL),
[email protected]c82da8c42012-06-08 19:49:11230 average_rating_(0.0),
[email protected]dcde34b32013-07-31 02:28:45231 rating_count_(0),
[email protected]34b5f7f2014-01-29 02:48:11232 show_user_count_(false),
233 has_webstore_data_(false) {
[email protected]c82da8c42012-06-08 19:49:11234}
235
236ExtensionInstallPrompt::Prompt::~Prompt() {
237}
238
239void ExtensionInstallPrompt::Prompt::SetPermissions(
treibf9dce312015-08-27 17:33:35240 const PermissionMessages& permissions,
gpdavis.chromium0fbac4d2014-09-19 20:57:54241 PermissionsType permissions_type) {
242 InstallPromptPermissions& install_permissions =
243 GetPermissionsForType(permissions_type);
sashabeabd5df2014-11-06 02:38:25244
treib7b45a34b2015-04-16 11:48:02245 install_permissions.permissions.clear();
246 install_permissions.details.clear();
247 install_permissions.is_showing_details.clear();
sashabeabd5df2014-11-06 02:38:25248
treibf9dce312015-08-27 17:33:35249 for (const PermissionMessage& msg : permissions) {
treib8d2de482015-08-04 16:36:48250 install_permissions.permissions.push_back(msg.message());
treib7b45a34b2015-04-16 11:48:02251 // Add a dash to the front of each permission detail.
252 base::string16 details;
treib8d2de482015-08-04 16:36:48253 if (!msg.submessages().empty()) {
sashabeabd5df2014-11-06 02:38:25254 std::vector<base::string16> detail_lines_with_bullets;
treib8d2de482015-08-04 16:36:48255 for (const auto& detail_line : msg.submessages()) {
sashabeabd5df2014-11-06 02:38:25256 detail_lines_with_bullets.push_back(base::ASCIIToUTF16("- ") +
257 detail_line);
treib7b45a34b2015-04-16 11:48:02258 }
sashabeabd5df2014-11-06 02:38:25259
brettwd94a22142015-07-15 05:19:26260 details = base::JoinString(detail_lines_with_bullets,
261 base::ASCIIToUTF16("\n"));
sashabeabd5df2014-11-06 02:38:25262 }
treib7b45a34b2015-04-16 11:48:02263 install_permissions.details.push_back(details);
264 install_permissions.is_showing_details.push_back(false);
sashabeabd5df2014-11-06 02:38:25265 }
[email protected]79a6f99a2013-08-29 00:32:58266}
267
268void ExtensionInstallPrompt::Prompt::SetIsShowingDetails(
269 DetailsType type,
270 size_t index,
271 bool is_showing_details) {
272 switch (type) {
273 case PERMISSIONS_DETAILS:
gpdavis.chromium0fbac4d2014-09-19 20:57:54274 prompt_permissions_.is_showing_details[index] = is_showing_details;
275 break;
276 case WITHHELD_PERMISSIONS_DETAILS:
277 withheld_prompt_permissions_.is_showing_details[index] =
278 is_showing_details;
[email protected]79a6f99a2013-08-29 00:32:58279 break;
[email protected]79a6f99a2013-08-29 00:32:58280 case RETAINED_FILES_DETAILS:
281 is_showing_details_for_retained_files_ = is_showing_details;
282 break;
reillygc64d3dd2014-09-29 21:10:11283 case RETAINED_DEVICES_DETAILS:
284 is_showing_details_for_retained_devices_ = is_showing_details;
285 break;
[email protected]79a6f99a2013-08-29 00:32:58286 }
[email protected]8ab7e6c2013-07-11 21:15:03287}
288
[email protected]34b5f7f2014-01-29 02:48:11289void ExtensionInstallPrompt::Prompt::SetWebstoreData(
[email protected]c82da8c42012-06-08 19:49:11290 const std::string& localized_user_count,
[email protected]dcde34b32013-07-31 02:28:45291 bool show_user_count,
[email protected]c82da8c42012-06-08 19:49:11292 double average_rating,
293 int rating_count) {
rdevlin.cronin5f6b69d2014-09-20 01:23:35294 CHECK(AllowWebstoreData(type_));
[email protected]c82da8c42012-06-08 19:49:11295 localized_user_count_ = localized_user_count;
[email protected]dcde34b32013-07-31 02:28:45296 show_user_count_ = show_user_count;
[email protected]c82da8c42012-06-08 19:49:11297 average_rating_ = average_rating;
298 rating_count_ = rating_count;
[email protected]34b5f7f2014-01-29 02:48:11299 has_webstore_data_ = true;
[email protected]c82da8c42012-06-08 19:49:11300}
301
[email protected]6a72a632013-12-12 22:22:00302base::string16 ExtensionInstallPrompt::Prompt::GetDialogTitle() const {
treibd35862252015-06-15 12:50:51303 int id = kTitleIds[type_];
treibd35862252015-06-15 12:50:51304 if (type_ == DELEGATED_PERMISSIONS_PROMPT) {
305 return l10n_util::GetStringFUTF16(id, base::UTF8ToUTF16(extension_->name()),
306 base::UTF8ToUTF16(delegated_username_));
307 }
308 if (type_ == EXTERNAL_INSTALL_PROMPT) {
309 if (extension_->is_app())
310 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_TITLE_APP;
311 else if (extension_->is_theme())
312 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_TITLE_THEME;
313 else
314 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_TITLE_EXTENSION;
315 }
316 return l10n_util::GetStringFUTF16(id, base::UTF8ToUTF16(extension_->name()));
[email protected]c82da8c42012-06-08 19:49:11317}
318
[email protected]15d267b42013-02-14 23:43:32319int ExtensionInstallPrompt::Prompt::GetDialogButtons() const {
reillygc64d3dd2014-09-29 21:10:11320 if (type_ == POST_INSTALL_PERMISSIONS_PROMPT && ShouldDisplayRevokeButton()) {
[email protected]a2886e8b2013-06-08 05:15:02321 return kButtons[type_] | ui::DIALOG_BUTTON_OK;
322 }
323
[email protected]15d267b42013-02-14 23:43:32324 return kButtons[type_];
325}
326
[email protected]6a72a632013-12-12 22:22:00327base::string16 ExtensionInstallPrompt::Prompt::GetAcceptButtonLabel() const {
treibd35862252015-06-15 12:50:51328 int id = kAcceptButtonIds[type_];
329
mamir5de9de92016-05-12 17:28:02330 if (type_ == INSTALL_PROMPT || type_ == INLINE_INSTALL_PROMPT) {
treibd35862252015-06-15 12:50:51331 if (extension_->is_app())
332 id = IDS_EXTENSION_INSTALL_PROMPT_ACCEPT_BUTTON_APP;
333 else if (extension_->is_theme())
334 id = IDS_EXTENSION_INSTALL_PROMPT_ACCEPT_BUTTON_THEME;
335 else
336 id = IDS_EXTENSION_INSTALL_PROMPT_ACCEPT_BUTTON_EXTENSION;
337 } else if (type_ == EXTERNAL_INSTALL_PROMPT) {
[email protected]846606012012-10-19 18:42:25338 if (extension_->is_app())
339 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_APP;
340 else if (extension_->is_theme())
341 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_THEME;
342 else
343 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_EXTENSION;
reillygc64d3dd2014-09-29 21:10:11344 } else if (type_ == POST_INSTALL_PERMISSIONS_PROMPT) {
reillygc64d3dd2014-09-29 21:10:11345 if (GetRetainedFileCount() && GetRetainedDeviceCount()) {
346 id =
347 IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_FILES_AND_DEVICES_BUTTON;
348 } else if (GetRetainedFileCount()) {
349 id = IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_FILES_BUTTON;
treibd35862252015-06-15 12:50:51350 } else if (GetRetainedDeviceCount()) {
reillygc64d3dd2014-09-29 21:10:11351 id = IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_DEVICES_BUTTON;
352 }
treibd35862252015-06-15 12:50:51353 // If there are neither retained files nor devices, leave id 0 so there
354 // will be no "accept" button.
355 } else if (type_ == REMOTE_INSTALL_PROMPT) {
356 if (extension_->is_app())
357 id = IDS_EXTENSION_PROMPT_REMOTE_INSTALL_BUTTON_APP;
358 else
359 id = IDS_EXTENSION_PROMPT_REMOTE_INSTALL_BUTTON_EXTENSION;
360 } else if (type_ == REPAIR_PROMPT) {
361 if (extension_->is_app())
362 id = IDS_EXTENSION_PROMPT_REPAIR_BUTTON_APP;
363 else
364 id = IDS_EXTENSION_PROMPT_REPAIR_BUTTON_EXTENSION;
[email protected]846606012012-10-19 18:42:25365 }
treibd35862252015-06-15 12:50:51366 return id ? l10n_util::GetStringUTF16(id) : base::string16();
[email protected]c82da8c42012-06-08 19:49:11367}
368
[email protected]6a72a632013-12-12 22:22:00369base::string16 ExtensionInstallPrompt::Prompt::GetAbortButtonLabel() const {
[email protected]c82da8c42012-06-08 19:49:11370 return l10n_util::GetStringUTF16(kAbortButtonIds[type_]);
371}
372
gpdavis.chromium0fbac4d2014-09-19 20:57:54373base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsHeading(
374 PermissionsType permissions_type) const {
375 switch (permissions_type) {
376 case REGULAR_PERMISSIONS:
377 return l10n_util::GetStringUTF16(kPermissionsHeaderIds[type_]);
378 case WITHHELD_PERMISSIONS:
379 return l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WITHHELD);
380 case ALL_PERMISSIONS:
381 default:
382 NOTREACHED();
383 return base::string16();
384 }
[email protected]c82da8c42012-06-08 19:49:11385}
386
[email protected]6a72a632013-12-12 22:22:00387base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFilesHeading() const {
jshin3a6c36bb2015-04-09 21:58:08388 return l10n_util::GetPluralStringFUTF16(
389 IDS_EXTENSION_PROMPT_RETAINED_FILES, GetRetainedFileCount());
[email protected]8ab7e6c2013-07-11 21:15:03390}
391
reillygc64d3dd2014-09-29 21:10:11392base::string16 ExtensionInstallPrompt::Prompt::GetRetainedDevicesHeading()
393 const {
jshin3a6c36bb2015-04-09 21:58:08394 return l10n_util::GetPluralStringFUTF16(
395 IDS_EXTENSION_PROMPT_RETAINED_DEVICES, GetRetainedDeviceCount());
reillygc64d3dd2014-09-29 21:10:11396}
397
[email protected]f2cd8992013-06-11 17:30:18398bool ExtensionInstallPrompt::Prompt::ShouldShowPermissions() const {
gpdavis.chromium0fbac4d2014-09-19 20:57:54399 return GetPermissionCount(ALL_PERMISSIONS) > 0 ||
400 type_ == POST_INSTALL_PERMISSIONS_PROMPT;
[email protected]f2cd8992013-06-11 17:30:18401}
402
asargent0a1c15f2015-12-09 02:25:21403bool ExtensionInstallPrompt::Prompt::ShouldUseTabModalDialog() const {
404 // For inline install, we want the install prompt to be tab modal so that the
405 // dialog is always clearly associated with the page that made the inline
406 // install request.
407 return type_ == INLINE_INSTALL_PROMPT;
408}
409
[email protected]c82da8c42012-06-08 19:49:11410void ExtensionInstallPrompt::Prompt::AppendRatingStars(
411 StarAppender appender, void* data) const {
412 CHECK(appender);
rdevlin.cronin5f6b69d2014-09-20 01:23:35413 CHECK(AllowWebstoreData(type_));
[email protected]c82da8c42012-06-08 19:49:11414 int rating_integer = floor(average_rating_);
415 double rating_fractional = average_rating_ - rating_integer;
416
417 if (rating_fractional > 0.66) {
418 rating_integer++;
419 }
420
421 if (rating_fractional < 0.33 || rating_fractional > 0.66) {
422 rating_fractional = 0;
423 }
424
425 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
426 int i;
427 for (i = 0; i < rating_integer; i++) {
428 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_ON), data);
429 }
430 if (rating_fractional) {
431 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_HALF_LEFT), data);
432 i++;
433 }
434 for (; i < kMaxExtensionRating; i++) {
435 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_OFF), data);
436 }
437}
438
[email protected]6a72a632013-12-12 22:22:00439base::string16 ExtensionInstallPrompt::Prompt::GetRatingCount() const {
rdevlin.cronin5f6b69d2014-09-20 01:23:35440 CHECK(AllowWebstoreData(type_));
[email protected]6725048e2013-10-24 21:47:14441 return l10n_util::GetStringFUTF16(IDS_EXTENSION_RATING_COUNT,
442 base::IntToString16(rating_count_));
[email protected]c82da8c42012-06-08 19:49:11443}
444
[email protected]6a72a632013-12-12 22:22:00445base::string16 ExtensionInstallPrompt::Prompt::GetUserCount() const {
rdevlin.cronin5f6b69d2014-09-20 01:23:35446 CHECK(AllowWebstoreData(type_));
[email protected]dcde34b32013-07-31 02:28:45447
448 if (show_user_count_) {
[email protected]6725048e2013-10-24 21:47:14449 return l10n_util::GetStringFUTF16(IDS_EXTENSION_USER_COUNT,
450 base::UTF8ToUTF16(localized_user_count_));
[email protected]dcde34b32013-07-31 02:28:45451 }
[email protected]6725048e2013-10-24 21:47:14452 return base::string16();
[email protected]c82da8c42012-06-08 19:49:11453}
454
gpdavis.chromium0fbac4d2014-09-19 20:57:54455size_t ExtensionInstallPrompt::Prompt::GetPermissionCount(
456 PermissionsType permissions_type) const {
457 switch (permissions_type) {
458 case REGULAR_PERMISSIONS:
459 return prompt_permissions_.permissions.size();
460 case WITHHELD_PERMISSIONS:
461 return withheld_prompt_permissions_.permissions.size();
462 case ALL_PERMISSIONS:
463 return prompt_permissions_.permissions.size() +
464 withheld_prompt_permissions_.permissions.size();
465 default:
466 NOTREACHED();
467 return 0u;
468 }
[email protected]c82da8c42012-06-08 19:49:11469}
470
gpdavis.chromium0fbac4d2014-09-19 20:57:54471size_t ExtensionInstallPrompt::Prompt::GetPermissionsDetailsCount(
472 PermissionsType permissions_type) const {
473 switch (permissions_type) {
474 case REGULAR_PERMISSIONS:
475 return prompt_permissions_.details.size();
476 case WITHHELD_PERMISSIONS:
477 return withheld_prompt_permissions_.details.size();
478 case ALL_PERMISSIONS:
479 return prompt_permissions_.details.size() +
480 withheld_prompt_permissions_.details.size();
481 default:
482 NOTREACHED();
483 return 0u;
484 }
[email protected]8ab7e6c2013-07-11 21:15:03485}
486
gpdavis.chromium0fbac4d2014-09-19 20:57:54487base::string16 ExtensionInstallPrompt::Prompt::GetPermission(
488 size_t index,
489 PermissionsType permissions_type) const {
490 const InstallPromptPermissions& install_permissions =
491 GetPermissionsForType(permissions_type);
492 CHECK_LT(index, install_permissions.permissions.size());
493 return install_permissions.permissions[index];
[email protected]c82da8c42012-06-08 19:49:11494}
495
[email protected]6a72a632013-12-12 22:22:00496base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsDetails(
gpdavis.chromium0fbac4d2014-09-19 20:57:54497 size_t index,
498 PermissionsType permissions_type) const {
499 const InstallPromptPermissions& install_permissions =
500 GetPermissionsForType(permissions_type);
501 CHECK_LT(index, install_permissions.details.size());
502 return install_permissions.details[index];
[email protected]8ab7e6c2013-07-11 21:15:03503}
504
[email protected]79a6f99a2013-08-29 00:32:58505bool ExtensionInstallPrompt::Prompt::GetIsShowingDetails(
506 DetailsType type, size_t index) const {
507 switch (type) {
508 case PERMISSIONS_DETAILS:
gpdavis.chromium0fbac4d2014-09-19 20:57:54509 CHECK_LT(index, prompt_permissions_.is_showing_details.size());
510 return prompt_permissions_.is_showing_details[index];
511 case WITHHELD_PERMISSIONS_DETAILS:
512 CHECK_LT(index, withheld_prompt_permissions_.is_showing_details.size());
513 return withheld_prompt_permissions_.is_showing_details[index];
[email protected]79a6f99a2013-08-29 00:32:58514 case RETAINED_FILES_DETAILS:
515 return is_showing_details_for_retained_files_;
reillygc64d3dd2014-09-29 21:10:11516 case RETAINED_DEVICES_DETAILS:
517 return is_showing_details_for_retained_devices_;
[email protected]79a6f99a2013-08-29 00:32:58518 }
519 return false;
520}
521
[email protected]a2886e8b2013-06-08 05:15:02522size_t ExtensionInstallPrompt::Prompt::GetRetainedFileCount() const {
523 return retained_files_.size();
524}
525
[email protected]6a72a632013-12-12 22:22:00526base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFile(size_t index)
527 const {
[email protected]a2886e8b2013-06-08 05:15:02528 CHECK_LT(index, retained_files_.size());
[email protected]6725048e2013-10-24 21:47:14529 return retained_files_[index].AsUTF16Unsafe();
[email protected]a2886e8b2013-06-08 05:15:02530}
531
reillygc64d3dd2014-09-29 21:10:11532size_t ExtensionInstallPrompt::Prompt::GetRetainedDeviceCount() const {
533 return retained_device_messages_.size();
534}
535
536base::string16 ExtensionInstallPrompt::Prompt::GetRetainedDeviceMessageString(
537 size_t index) const {
538 CHECK_LT(index, retained_device_messages_.size());
539 return retained_device_messages_[index];
540}
541
542bool ExtensionInstallPrompt::Prompt::ShouldDisplayRevokeButton() const {
543 return !retained_files_.empty() || !retained_device_messages_.empty();
544}
545
gpdavis.chromium0fbac4d2014-09-19 20:57:54546ExtensionInstallPrompt::Prompt::InstallPromptPermissions&
547ExtensionInstallPrompt::Prompt::GetPermissionsForType(
548 PermissionsType permissions_type) {
549 DCHECK_NE(ALL_PERMISSIONS, permissions_type);
550 return permissions_type == REGULAR_PERMISSIONS ? prompt_permissions_
551 : withheld_prompt_permissions_;
552}
553
554const ExtensionInstallPrompt::Prompt::InstallPromptPermissions&
555ExtensionInstallPrompt::Prompt::GetPermissionsForType(
556 PermissionsType permissions_type) const {
557 DCHECK_NE(ALL_PERMISSIONS, permissions_type);
558 return permissions_type == REGULAR_PERMISSIONS ? prompt_permissions_
559 : withheld_prompt_permissions_;
560}
561
[email protected]a2886e8b2013-06-08 05:15:02562bool ExtensionInstallPrompt::Prompt::ShouldDisplayRevokeFilesButton() const {
563 return !retained_files_.empty();
564}
565
[email protected]c82da8c42012-06-08 19:49:11566// static
rdevlin.croninf84cab72015-12-12 03:45:23567ExtensionInstallPrompt::PromptType
568ExtensionInstallPrompt::GetReEnablePromptTypeForExtension(
569 content::BrowserContext* context,
570 const extensions::Extension* extension) {
571 bool is_remote_install =
572 context &&
573 extensions::ExtensionPrefs::Get(context)->HasDisableReason(
574 extension->id(), extensions::Extension::DISABLE_REMOTE_INSTALL);
575
576 return is_remote_install ? REMOTE_INSTALL_PROMPT : RE_ENABLE_PROMPT;
577}
578
579// static
[email protected]c82da8c42012-06-08 19:49:11580scoped_refptr<Extension>
581 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay(
[email protected]023b3d12013-12-23 18:46:49582 const base::DictionaryValue* manifest,
[email protected]c422a862012-07-31 15:46:13583 int flags,
[email protected]c82da8c42012-06-08 19:49:11584 const std::string& id,
585 const std::string& localized_name,
586 const std::string& localized_description,
587 std::string* error) {
dchengc963c7142016-04-08 03:55:22588 std::unique_ptr<base::DictionaryValue> localized_manifest;
[email protected]c82da8c42012-06-08 19:49:11589 if (!localized_name.empty() || !localized_description.empty()) {
590 localized_manifest.reset(manifest->DeepCopy());
591 if (!localized_name.empty()) {
[email protected]6bf90612013-08-15 00:36:27592 localized_manifest->SetString(extensions::manifest_keys::kName,
[email protected]c82da8c42012-06-08 19:49:11593 localized_name);
594 }
595 if (!localized_description.empty()) {
[email protected]6bf90612013-08-15 00:36:27596 localized_manifest->SetString(extensions::manifest_keys::kDescription,
[email protected]c82da8c42012-06-08 19:49:11597 localized_description);
598 }
599 }
600
601 return Extension::Create(
rdevlin.cronin165732a42016-07-18 22:25:08602 base::FilePath(), Manifest::INTERNAL,
603 localized_manifest.get() ? *localized_manifest : *manifest, flags, id,
[email protected]c82da8c42012-06-08 19:49:11604 error);
605}
606
[email protected]7f165342014-02-12 09:22:22607ExtensionInstallPrompt::ExtensionInstallPrompt(content::WebContents* contents)
pkotwicza57a1f322014-10-21 00:24:30608 : profile_(ProfileForWebContents(contents)),
[email protected]c82da8c42012-06-08 19:49:11609 extension_(NULL),
pkotwicza57a1f322014-10-21 00:24:30610 install_ui_(extensions::CreateExtensionInstallUI(
611 ProfileForWebContents(contents))),
pkotwicz2f181782014-10-29 17:33:45612 show_params_(new ExtensionInstallPromptShowParams(contents)),
rdevlin.cronin3fe4bd32016-01-12 18:45:40613 did_call_show_dialog_(false),
614 weak_factory_(this) {
[email protected]d382baa2014-06-17 18:50:01615}
[email protected]5db2e882012-12-20 10:17:26616
pkotwicz2175c622014-10-22 19:56:28617ExtensionInstallPrompt::ExtensionInstallPrompt(Profile* profile,
618 gfx::NativeWindow native_window)
pkotwicza57a1f322014-10-21 00:24:30619 : profile_(profile),
[email protected]5db2e882012-12-20 10:17:26620 extension_(NULL),
pkotwicza57a1f322014-10-21 00:24:30621 install_ui_(extensions::CreateExtensionInstallUI(profile)),
pkotwicz2f181782014-10-29 17:33:45622 show_params_(
623 new ExtensionInstallPromptShowParams(profile, native_window)),
rdevlin.cronin3fe4bd32016-01-12 18:45:40624 did_call_show_dialog_(false),
625 weak_factory_(this) {
[email protected]d382baa2014-06-17 18:50:01626}
[email protected]c82da8c42012-06-08 19:49:11627
628ExtensionInstallPrompt::~ExtensionInstallPrompt() {
629}
630
rdevlin.croninf84cab72015-12-12 03:45:23631void ExtensionInstallPrompt::ShowDialog(
rdevlin.cronin41593052016-01-08 01:40:12632 const DoneCallback& done_callback,
[email protected]c82da8c42012-06-08 19:49:11633 const Extension* extension,
rdevlin.croninf84cab72015-12-12 03:45:23634 const SkBitmap* icon,
635 const ShowDialogCallback& show_dialog_callback) {
rdevlin.cronin41593052016-01-08 01:40:12636 ShowDialog(done_callback, extension, icon,
dchengc963c7142016-04-08 03:55:22637 base::WrapUnique(new Prompt(INSTALL_PROMPT)),
638 show_dialog_callback);
rdevlin.cronin2e252692015-12-15 21:47:02639}
640
641void ExtensionInstallPrompt::ShowDialog(
rdevlin.cronin41593052016-01-08 01:40:12642 const DoneCallback& done_callback,
rdevlin.cronin2e252692015-12-15 21:47:02643 const Extension* extension,
644 const SkBitmap* icon,
dchengc963c7142016-04-08 03:55:22645 std::unique_ptr<Prompt> prompt,
rdevlin.cronin2e252692015-12-15 21:47:02646 const ShowDialogCallback& show_dialog_callback) {
rdevlin.cronin41593052016-01-08 01:40:12647 ShowDialog(done_callback, extension, icon, std::move(prompt), nullptr,
rdevlin.croninf84cab72015-12-12 03:45:23648 show_dialog_callback);
649}
650
651void ExtensionInstallPrompt::ShowDialog(
rdevlin.cronin41593052016-01-08 01:40:12652 const DoneCallback& done_callback,
rdevlin.croninf84cab72015-12-12 03:45:23653 const Extension* extension,
654 const SkBitmap* icon,
dchengc963c7142016-04-08 03:55:22655 std::unique_ptr<Prompt> prompt,
656 std::unique_ptr<const PermissionSet> custom_permissions,
rdevlin.croninf84cab72015-12-12 03:45:23657 const ShowDialogCallback& show_dialog_callback) {
fdorayc16c6f82016-06-29 15:27:32658 DCHECK(ui_thread_checker_.CalledOnValidThread());
rdevlin.cronin2e252692015-12-15 21:47:02659 DCHECK(prompt);
[email protected]c82da8c42012-06-08 19:49:11660 extension_ = extension;
rdevlin.cronin41593052016-01-08 01:40:12661 done_callback_ = done_callback;
rdevlin.croninfc1499f2015-12-21 18:22:00662 if (icon && !icon->empty())
663 SetIcon(icon);
dcheng1fc00f12015-12-26 22:18:03664 prompt_ = std::move(prompt);
665 custom_permissions_ = std::move(custom_permissions);
[email protected]af6efb22012-10-12 02:23:05666 show_dialog_callback_ = show_dialog_callback;
[email protected]c82da8c42012-06-08 19:49:11667
668 // We special-case themes to not show any confirm UI. Instead they are
669 // immediately installed, and then we show an infobar (see OnInstallSuccess)
670 // to allow the user to revert if they don't like it.
671 //
672 // We don't do this in the case where off-store extension installs are
673 // disabled because in that case, we don't show the dangerous download UI, so
674 // we need the UI confirmation.
675 if (extension->is_theme()) {
676 if (extension->from_webstore() ||
[email protected]544471a2012-10-13 05:27:09677 extensions::FeatureSwitch::easy_off_store_install()->IsEnabled()) {
rdevlin.cronin41593052016-01-08 01:40:12678 base::ResetAndReturn(&done_callback_).Run(Result::ACCEPTED);
[email protected]c82da8c42012-06-08 19:49:11679 return;
680 }
681 }
682
683 LoadImageIfNeeded();
684}
685
[email protected]c82da8c42012-06-08 19:49:11686void ExtensionInstallPrompt::OnInstallSuccess(const Extension* extension,
687 SkBitmap* icon) {
688 extension_ = extension;
689 SetIcon(icon);
690
691 install_ui_->OnInstallSuccess(extension, &icon_);
692}
693
[email protected]bf3d9df2012-07-24 23:20:27694void ExtensionInstallPrompt::OnInstallFailure(
ginkage47e603e2015-02-27 08:42:41695 const extensions::CrxInstallError& error) {
[email protected]c82da8c42012-06-08 19:49:11696 install_ui_->OnInstallFailure(error);
697}
698
699void ExtensionInstallPrompt::SetIcon(const SkBitmap* image) {
700 if (image)
701 icon_ = *image;
702 else
703 icon_ = SkBitmap();
[email protected]dd46a4ce2012-09-15 10:50:50704 if (icon_.empty()) {
705 // Let's set default icon bitmap whose size is equal to the default icon's
706 // pixel size under maximal supported scale factor. If the bitmap is larger
707 // than the one we need, it will be scaled down by the ui code.
treibd9e1d9d2015-04-24 11:17:04708 icon_ = GetDefaultIconBitmapForMaxScaleFactor(
709 extension_ ? extension_->is_app() : false);
[email protected]dd46a4ce2012-09-15 10:50:50710 }
[email protected]c82da8c42012-06-08 19:49:11711}
712
[email protected]ec7de0c5a2012-11-16 07:40:47713void ExtensionInstallPrompt::OnImageLoaded(const gfx::Image& image) {
[email protected]c82da8c42012-06-08 19:49:11714 SetIcon(image.IsEmpty() ? NULL : image.ToSkBitmap());
[email protected]4e494872013-09-06 09:13:54715 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11716}
717
718void ExtensionInstallPrompt::LoadImageIfNeeded() {
treib3d41d9f2016-04-12 08:53:01719 // Don't override an icon that was passed in. Also, |profile_| can be null in
720 // unit tests.
721 if (!icon_.empty() || !profile_) {
[email protected]4e494872013-09-06 09:13:54722 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11723 return;
724 }
725
[email protected]993da5e2013-03-23 21:25:16726 extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
[email protected]702d8b42013-02-27 20:55:50727 extension_,
728 extension_misc::EXTENSION_ICON_LARGE,
729 ExtensionIconSet::MATCH_BIGGER);
[email protected]0d0ba182014-06-03 12:40:43730
731 // Load the image asynchronously. The response will be sent to OnImageLoaded.
pkotwicza57a1f322014-10-21 00:24:30732 extensions::ImageLoader* loader = extensions::ImageLoader::Get(profile_);
[email protected]0d0ba182014-06-03 12:40:43733
734 std::vector<extensions::ImageLoader::ImageRepresentation> images_list;
735 images_list.push_back(extensions::ImageLoader::ImageRepresentation(
736 image,
737 extensions::ImageLoader::ImageRepresentation::NEVER_RESIZE,
738 gfx::Size(),
739 ui::SCALE_FACTOR_100P));
740 loader->LoadImagesAsync(
741 extension_,
742 images_list,
rdevlin.cronin3fe4bd32016-01-12 18:45:40743 base::Bind(&ExtensionInstallPrompt::OnImageLoaded,
744 weak_factory_.GetWeakPtr()));
[email protected]c82da8c42012-06-08 19:49:11745}
746
747void ExtensionInstallPrompt::ShowConfirmation() {
dchengc963c7142016-04-08 03:55:22748 std::unique_ptr<const PermissionSet> permissions_wrapper;
rdevlin.cronine2d0fd02015-09-24 22:35:49749 const PermissionSet* permissions_to_display = nullptr;
gpdavis.chromium0fbac4d2014-09-19 20:57:54750 if (custom_permissions_.get()) {
rdevlin.cronine2d0fd02015-09-24 22:35:49751 permissions_to_display = custom_permissions_.get();
gpdavis.chromium0fbac4d2014-09-19 20:57:54752 } else if (extension_) {
753 // Initialize permissions if they have not already been set so that
754 // withheld permissions are displayed properly in the install prompt.
755 extensions::PermissionsUpdater(
pkotwicza57a1f322014-10-21 00:24:30756 profile_, extensions::PermissionsUpdater::INIT_FLAG_TRANSIENT)
gpdavis.chromium0fbac4d2014-09-19 20:57:54757 .InitializePermissions(extension_);
758 permissions_to_display =
rdevlin.cronind630c302015-09-30 20:19:33759 &extension_->permissions_data()->active_permissions();
treib7496f63c2015-03-04 12:18:53760 // For delegated installs, all optional permissions are pre-approved by the
761 // person who triggers the install, so add them to the list.
treib3d41d9f2016-04-12 08:53:01762 if (prompt_->type() == DELEGATED_PERMISSIONS_PROMPT) {
rdevlin.cronind630c302015-09-30 20:19:33763 const PermissionSet& optional_permissions =
treib7496f63c2015-03-04 12:18:53764 extensions::PermissionsParser::GetOptionalPermissions(extension_);
rdevlin.cronine2d0fd02015-09-24 22:35:49765 permissions_wrapper = PermissionSet::CreateUnion(*permissions_to_display,
rdevlin.cronind630c302015-09-30 20:19:33766 optional_permissions);
rdevlin.cronine2d0fd02015-09-24 22:35:49767 permissions_to_display = permissions_wrapper.get();
treib7496f63c2015-03-04 12:18:53768 }
gpdavis.chromium0fbac4d2014-09-19 20:57:54769 }
770
rdevlin.cronine2d0fd02015-09-24 22:35:49771 if (permissions_to_display &&
[email protected]a397ec02014-08-08 15:48:13772 (!extension_ ||
773 !extensions::PermissionsData::ShouldSkipPermissionWarnings(
774 extension_->id()))) {
775 Manifest::Type type =
776 extension_ ? extension_->GetType() : Manifest::TYPE_UNKNOWN;
777 const extensions::PermissionMessageProvider* message_provider =
778 extensions::PermissionMessageProvider::Get();
treib7b45a34b2015-04-16 11:48:02779
treib8d2de482015-08-04 16:36:48780 prompt_->SetPermissions(message_provider->GetPermissionMessages(
781 message_provider->GetAllPermissionIDs(
rdevlin.cronind630c302015-09-30 20:19:33782 *permissions_to_display, type)),
gpdavis.chromium0fbac4d2014-09-19 20:57:54783 REGULAR_PERMISSIONS);
gpdavis.chromium0fbac4d2014-09-19 20:57:54784
rdevlin.cronine2d0fd02015-09-24 22:35:49785 const PermissionSet* withheld =
rdevlin.cronind630c302015-09-30 20:19:33786 extension_ ? &extension_->permissions_data()->withheld_permissions()
treiba21dcd92015-04-03 05:26:41787 : nullptr;
788 if (withheld && !withheld->IsEmpty()) {
gpdavis.chromium0fbac4d2014-09-19 20:57:54789 prompt_->SetPermissions(
treib8d2de482015-08-04 16:36:48790 message_provider->GetPermissionMessages(
rdevlin.cronind630c302015-09-30 20:19:33791 message_provider->GetAllPermissionIDs(*withheld, type)),
treib8d2de482015-08-04 16:36:48792 WITHHELD_PERMISSIONS);
gpdavis.chromium0fbac4d2014-09-19 20:57:54793 }
[email protected]bebe1d02012-08-02 20:17:09794 }
[email protected]c82da8c42012-06-08 19:49:11795
[email protected]d382baa2014-06-17 18:50:01796 switch (prompt_->type()) {
[email protected]c82da8c42012-06-08 19:49:11797 case PERMISSIONS_PROMPT:
798 case RE_ENABLE_PROMPT:
799 case INLINE_INSTALL_PROMPT:
[email protected]612a1cb12012-10-17 13:18:03800 case EXTERNAL_INSTALL_PROMPT:
[email protected]15d267b42013-02-14 23:43:32801 case INSTALL_PROMPT:
[email protected]21db9ef2014-05-16 02:06:27802 case POST_INSTALL_PERMISSIONS_PROMPT:
rdevlin.cronin5f6b69d2014-09-20 01:23:35803 case REMOTE_INSTALL_PROMPT:
treib2d2f5372015-03-01 12:20:49804 case REPAIR_PROMPT:
805 case DELEGATED_PERMISSIONS_PROMPT: {
[email protected]d382baa2014-06-17 18:50:01806 prompt_->set_extension(extension_);
[email protected]c82da8c42012-06-08 19:49:11807 break;
808 }
benwells1dd4acd2015-12-09 02:20:24809 case LAUNCH_PROMPT_DEPRECATED:
[email protected]c82da8c42012-06-08 19:49:11810 default:
811 NOTREACHED() << "Unknown message";
[email protected]af6efb22012-10-12 02:23:05812 return;
[email protected]c82da8c42012-06-08 19:49:11813 }
treibd9e1d9d2015-04-24 11:17:04814 prompt_->set_icon(gfx::Image::CreateFrom1xBitmap(icon_));
[email protected]af6efb22012-10-12 02:23:05815
pkotwicz2f181782014-10-29 17:33:45816 if (show_params_->WasParentDestroyed()) {
rdevlin.cronin41593052016-01-08 01:40:12817 base::ResetAndReturn(&done_callback_).Run(Result::ABORTED);
pkotwicz2f181782014-10-29 17:33:45818 return;
819 }
820
rdevlin.croninca5bf2da2015-12-17 21:21:08821 g_last_prompt_type_for_tests = prompt_->type();
822 did_call_show_dialog_ = true;
823
rdevlin.cronin41593052016-01-08 01:40:12824 if (AutoConfirmPrompt(&done_callback_))
rdevlin.croninca5bf2da2015-12-17 21:21:08825 return;
826
[email protected]5db2e882012-12-20 10:17:26827 if (show_dialog_callback_.is_null())
rdevlin.cronin41593052016-01-08 01:40:12828 show_dialog_callback_ = GetDefaultShowDialogCallback();
829 base::ResetAndReturn(&show_dialog_callback_)
830 .Run(show_params_.get(), base::ResetAndReturn(&done_callback_),
831 std::move(prompt_));
[email protected]c82da8c42012-06-08 19:49:11832}