blob: d691a713a57c40fbdb097d1eddc5fe7bbf9790a5 [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"
thestig4a2e88e2016-08-27 23:23:5124#include "chrome/grit/theme_resources.h"
25#include "components/strings/grit/components_strings.h"
[email protected]91e51d612012-10-21 23:03:0526#include "content/public/browser/web_contents.h"
rdevlin.cronin66209492015-06-10 20:44:0527#include "extensions/browser/extension_dialog_auto_confirm.h"
[email protected]21db9ef2014-05-16 02:06:2728#include "extensions/browser/extension_prefs.h"
[email protected]411f8ae2014-05-22 11:12:2329#include "extensions/browser/extension_util.h"
[email protected]326e6f02014-06-20 04:53:3730#include "extensions/browser/image_loader.h"
pkotwicza57a1f322014-10-21 00:24:3031#include "extensions/browser/install/extension_install_ui.h"
[email protected]cda103d2014-04-04 16:22:3932#include "extensions/common/constants.h"
[email protected]e4452d32013-11-15 23:07:4133#include "extensions/common/extension.h"
[email protected]4b7908842014-04-07 23:50:2234#include "extensions/common/extension_icon_set.h"
[email protected]993da5e2013-03-23 21:25:1635#include "extensions/common/extension_resource.h"
[email protected]5ef835a2013-11-08 20:42:5736#include "extensions/common/feature_switch.h"
[email protected]d42c11152013-08-22 19:36:3237#include "extensions/common/manifest.h"
[email protected]6bf90612013-08-15 00:36:2738#include "extensions/common/manifest_constants.h"
[email protected]0db486f2014-04-09 19:32:2239#include "extensions/common/manifest_handlers/icons_handler.h"
treib7496f63c2015-03-04 12:18:5340#include "extensions/common/manifest_handlers/permissions_parser.h"
treibf9dce312015-08-27 17:33:3541#include "extensions/common/permissions/permission_message_provider.h"
[email protected]5a55f3f2013-10-29 01:08:2942#include "extensions/common/permissions/permission_set.h"
[email protected]e4452d32013-11-15 23:07:4143#include "extensions/common/permissions/permissions_data.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]dd46a4ce2012-09-15 10:50:5063// Returns bitmap for the default icon with size equal to the default icon's
64// pixel size under maximal supported scale factor.
65SkBitmap GetDefaultIconBitmapForMaxScaleFactor(bool is_app) {
[email protected]702d8b42013-02-27 20:55:5066 const gfx::ImageSkia& image = is_app ?
[email protected]7eb20e32014-04-30 08:50:5667 extensions::util::GetDefaultAppIcon() :
68 extensions::util::GetDefaultExtensionIcon();
[email protected]50b66262013-09-24 03:25:4869 return image.GetRepresentation(
70 gfx::ImageSkia::GetMaxSupportedScale()).sk_bitmap();
[email protected]dd46a4ce2012-09-15 10:50:5071}
72
[email protected]af6efb22012-10-12 02:23:0573// If auto confirm is enabled then posts a task to proceed with or cancel the
74// install and returns true. Otherwise returns false.
rdevlin.cronin41593052016-01-08 01:40:1275bool AutoConfirmPrompt(ExtensionInstallPrompt::DoneCallback* callback) {
rdevlin.cronin66209492015-06-10 20:44:0576 switch (extensions::ScopedTestDialogAutoConfirm::GetAutoConfirmValue()) {
77 case extensions::ScopedTestDialogAutoConfirm::NONE:
[email protected]2a74d6f62014-07-24 11:53:4778 return false;
rdevlin.cronin41593052016-01-08 01:40:1279 // We use PostTask instead of calling the callback directly here, because in
[email protected]2a74d6f62014-07-24 11:53:4780 // the real implementations it's highly likely the message loop will be
81 // pumping a few times before the user clicks accept or cancel.
rdevlin.cronin66209492015-06-10 20:44:0582 case extensions::ScopedTestDialogAutoConfirm::ACCEPT:
catmullingsff559d92017-05-20 01:43:3683 case extensions::ScopedTestDialogAutoConfirm::ACCEPT_AND_OPTION:
fdoray283082bd2016-06-02 20:18:4684 base::ThreadTaskRunnerHandle::Get()->PostTask(
tzik8d880ee2017-04-20 19:46:2485 FROM_HERE, base::BindOnce(base::ResetAndReturn(callback),
86 ExtensionInstallPrompt::Result::ACCEPTED));
[email protected]2a74d6f62014-07-24 11:53:4787 return true;
rdevlin.cronin66209492015-06-10 20:44:0588 case extensions::ScopedTestDialogAutoConfirm::CANCEL:
skyostilf221b7de2015-06-11 20:36:3289 base::ThreadTaskRunnerHandle::Get()->PostTask(
tzik8d880ee2017-04-20 19:46:2490 FROM_HERE,
91 base::BindOnce(base::ResetAndReturn(callback),
92 ExtensionInstallPrompt::Result::USER_CANCELED));
[email protected]2a74d6f62014-07-24 11:53:4793 return true;
[email protected]af6efb22012-10-12 02:23:0594 }
95
96 NOTREACHED();
97 return false;
98}
99
[email protected]91e51d612012-10-21 23:03:05100Profile* ProfileForWebContents(content::WebContents* web_contents) {
101 if (!web_contents)
102 return NULL;
103 return Profile::FromBrowserContext(web_contents->GetBrowserContext());
104}
105
[email protected]c82da8c42012-06-08 19:49:11106} // namespace
107
gpdavis.chromium0fbac4d2014-09-19 20:57:54108ExtensionInstallPrompt::Prompt::InstallPromptPermissions::
109 InstallPromptPermissions() {
110}
111ExtensionInstallPrompt::Prompt::InstallPromptPermissions::
112 ~InstallPromptPermissions() {
113}
114
rdevlin.cronin092c6772014-11-20 23:52:40115ExtensionInstallPrompt::PromptType
116ExtensionInstallPrompt::g_last_prompt_type_for_tests =
117 ExtensionInstallPrompt::UNSET_PROMPT_TYPE;
118
[email protected]eeb0d3e12014-08-15 15:10:44119// This should match the PromptType enum.
120std::string ExtensionInstallPrompt::PromptTypeToString(PromptType type) {
121 switch (type) {
rdevlin.croninc7f8d132017-02-22 14:29:02122 case INSTALL_PROMPT:
[email protected]eeb0d3e12014-08-15 15:10:44123 return "INSTALL_PROMPT";
rdevlin.croninc7f8d132017-02-22 14:29:02124 case INLINE_INSTALL_PROMPT:
[email protected]eeb0d3e12014-08-15 15:10:44125 return "INLINE_INSTALL_PROMPT";
rdevlin.croninc7f8d132017-02-22 14:29:02126 case RE_ENABLE_PROMPT:
[email protected]eeb0d3e12014-08-15 15:10:44127 return "RE_ENABLE_PROMPT";
rdevlin.croninc7f8d132017-02-22 14:29:02128 case PERMISSIONS_PROMPT:
[email protected]eeb0d3e12014-08-15 15:10:44129 return "PERMISSIONS_PROMPT";
rdevlin.croninc7f8d132017-02-22 14:29:02130 case EXTERNAL_INSTALL_PROMPT:
[email protected]eeb0d3e12014-08-15 15:10:44131 return "EXTERNAL_INSTALL_PROMPT";
rdevlin.croninc7f8d132017-02-22 14:29:02132 case POST_INSTALL_PERMISSIONS_PROMPT:
[email protected]eeb0d3e12014-08-15 15:10:44133 return "POST_INSTALL_PERMISSIONS_PROMPT";
rdevlin.croninc7f8d132017-02-22 14:29:02134 case REMOTE_INSTALL_PROMPT:
[email protected]eeb0d3e12014-08-15 15:10:44135 return "REMOTE_INSTALL_PROMPT";
rdevlin.croninc7f8d132017-02-22 14:29:02136 case REPAIR_PROMPT:
rdevlin.cronin5f6b69d2014-09-20 01:23:35137 return "REPAIR_PROMPT";
rdevlin.croninc7f8d132017-02-22 14:29:02138 case DELEGATED_PERMISSIONS_PROMPT:
treib2d2f5372015-03-01 12:20:49139 return "DELEGATED_PERMISSIONS_PROMPT";
rdevlin.croninc7f8d132017-02-22 14:29:02140 case UNSET_PROMPT_TYPE:
141 case NUM_PROMPT_TYPES:
benwells1dd4acd2015-12-09 02:20:24142 NOTREACHED();
[email protected]eeb0d3e12014-08-15 15:10:44143 break;
144 }
145 return "OTHER";
146}
147
[email protected]5db2e882012-12-20 10:17:26148ExtensionInstallPrompt::Prompt::Prompt(PromptType type)
[email protected]c82da8c42012-06-08 19:49:11149 : type_(type),
[email protected]79a6f99a2013-08-29 00:32:58150 is_showing_details_for_retained_files_(false),
reillygc64d3dd2014-09-29 21:10:11151 is_showing_details_for_retained_devices_(false),
[email protected]c82da8c42012-06-08 19:49:11152 extension_(NULL),
[email protected]c82da8c42012-06-08 19:49:11153 average_rating_(0.0),
[email protected]dcde34b32013-07-31 02:28:45154 rating_count_(0),
[email protected]34b5f7f2014-01-29 02:48:11155 show_user_count_(false),
156 has_webstore_data_(false) {
rdevlin.croninc7f8d132017-02-22 14:29:02157 DCHECK_NE(type_, UNSET_PROMPT_TYPE);
158 DCHECK_NE(type_, NUM_PROMPT_TYPES);
[email protected]c82da8c42012-06-08 19:49:11159}
160
161ExtensionInstallPrompt::Prompt::~Prompt() {
162}
163
164void ExtensionInstallPrompt::Prompt::SetPermissions(
treibf9dce312015-08-27 17:33:35165 const PermissionMessages& permissions,
gpdavis.chromium0fbac4d2014-09-19 20:57:54166 PermissionsType permissions_type) {
167 InstallPromptPermissions& install_permissions =
168 GetPermissionsForType(permissions_type);
sashabeabd5df2014-11-06 02:38:25169
treib7b45a34b2015-04-16 11:48:02170 install_permissions.permissions.clear();
171 install_permissions.details.clear();
172 install_permissions.is_showing_details.clear();
sashabeabd5df2014-11-06 02:38:25173
treibf9dce312015-08-27 17:33:35174 for (const PermissionMessage& msg : permissions) {
treib8d2de482015-08-04 16:36:48175 install_permissions.permissions.push_back(msg.message());
treib7b45a34b2015-04-16 11:48:02176 // Add a dash to the front of each permission detail.
177 base::string16 details;
treib8d2de482015-08-04 16:36:48178 if (!msg.submessages().empty()) {
sashabeabd5df2014-11-06 02:38:25179 std::vector<base::string16> detail_lines_with_bullets;
treib8d2de482015-08-04 16:36:48180 for (const auto& detail_line : msg.submessages()) {
sashabeabd5df2014-11-06 02:38:25181 detail_lines_with_bullets.push_back(base::ASCIIToUTF16("- ") +
182 detail_line);
treib7b45a34b2015-04-16 11:48:02183 }
sashabeabd5df2014-11-06 02:38:25184
brettwd94a22142015-07-15 05:19:26185 details = base::JoinString(detail_lines_with_bullets,
186 base::ASCIIToUTF16("\n"));
sashabeabd5df2014-11-06 02:38:25187 }
treib7b45a34b2015-04-16 11:48:02188 install_permissions.details.push_back(details);
189 install_permissions.is_showing_details.push_back(false);
sashabeabd5df2014-11-06 02:38:25190 }
[email protected]79a6f99a2013-08-29 00:32:58191}
192
193void ExtensionInstallPrompt::Prompt::SetIsShowingDetails(
194 DetailsType type,
195 size_t index,
196 bool is_showing_details) {
197 switch (type) {
198 case PERMISSIONS_DETAILS:
gpdavis.chromium0fbac4d2014-09-19 20:57:54199 prompt_permissions_.is_showing_details[index] = is_showing_details;
200 break;
201 case WITHHELD_PERMISSIONS_DETAILS:
202 withheld_prompt_permissions_.is_showing_details[index] =
203 is_showing_details;
[email protected]79a6f99a2013-08-29 00:32:58204 break;
[email protected]79a6f99a2013-08-29 00:32:58205 case RETAINED_FILES_DETAILS:
206 is_showing_details_for_retained_files_ = is_showing_details;
207 break;
reillygc64d3dd2014-09-29 21:10:11208 case RETAINED_DEVICES_DETAILS:
209 is_showing_details_for_retained_devices_ = is_showing_details;
210 break;
[email protected]79a6f99a2013-08-29 00:32:58211 }
[email protected]8ab7e6c2013-07-11 21:15:03212}
213
[email protected]34b5f7f2014-01-29 02:48:11214void ExtensionInstallPrompt::Prompt::SetWebstoreData(
[email protected]c82da8c42012-06-08 19:49:11215 const std::string& localized_user_count,
[email protected]dcde34b32013-07-31 02:28:45216 bool show_user_count,
[email protected]c82da8c42012-06-08 19:49:11217 double average_rating,
218 int rating_count) {
rdevlin.cronin5f6b69d2014-09-20 01:23:35219 CHECK(AllowWebstoreData(type_));
[email protected]c82da8c42012-06-08 19:49:11220 localized_user_count_ = localized_user_count;
[email protected]dcde34b32013-07-31 02:28:45221 show_user_count_ = show_user_count;
[email protected]c82da8c42012-06-08 19:49:11222 average_rating_ = average_rating;
223 rating_count_ = rating_count;
[email protected]34b5f7f2014-01-29 02:48:11224 has_webstore_data_ = true;
[email protected]c82da8c42012-06-08 19:49:11225}
226
[email protected]6a72a632013-12-12 22:22:00227base::string16 ExtensionInstallPrompt::Prompt::GetDialogTitle() const {
rdevlin.croninc7f8d132017-02-22 14:29:02228 int id = -1;
229 switch (type_) {
230 case INSTALL_PROMPT:
231 case INLINE_INSTALL_PROMPT:
232 id = IDS_EXTENSION_INSTALL_PROMPT_TITLE;
233 break;
234 case RE_ENABLE_PROMPT:
235 id = IDS_EXTENSION_RE_ENABLE_PROMPT_TITLE;
236 break;
237 case PERMISSIONS_PROMPT:
238 id = IDS_EXTENSION_PERMISSIONS_PROMPT_TITLE;
239 break;
240 case EXTERNAL_INSTALL_PROMPT:
241 if (extension_->is_app())
242 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_TITLE_APP;
243 else if (extension_->is_theme())
244 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_TITLE_THEME;
245 else
246 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_TITLE_EXTENSION;
247 break;
248 case POST_INSTALL_PERMISSIONS_PROMPT:
249 id = IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_TITLE;
250 break;
251 case REMOTE_INSTALL_PROMPT:
252 id = IDS_EXTENSION_REMOTE_INSTALL_PROMPT_TITLE;
253 break;
254 case REPAIR_PROMPT:
255 id = IDS_EXTENSION_REPAIR_PROMPT_TITLE;
256 break;
257 case DELEGATED_PERMISSIONS_PROMPT:
258 // Special case: need to include the delegated username.
259 return l10n_util::GetStringFUTF16(
260 IDS_EXTENSION_DELEGATED_INSTALL_PROMPT_TITLE,
261 base::UTF8ToUTF16(extension_->name()),
262 base::UTF8ToUTF16(delegated_username_));
263 case UNSET_PROMPT_TYPE:
264 case NUM_PROMPT_TYPES:
265 NOTREACHED();
treibd35862252015-06-15 12:50:51266 }
rdevlin.croninc7f8d132017-02-22 14:29:02267
treibd35862252015-06-15 12:50:51268 return l10n_util::GetStringFUTF16(id, base::UTF8ToUTF16(extension_->name()));
[email protected]c82da8c42012-06-08 19:49:11269}
270
[email protected]15d267b42013-02-14 23:43:32271int ExtensionInstallPrompt::Prompt::GetDialogButtons() const {
rdevlin.croninc7f8d132017-02-22 14:29:02272 // The "OK" button in the post install permissions dialog allows revoking
273 // file/device access, and is only shown if such permissions exist; see
274 // ShouldDisplayRevokeButton().
275 if (type_ == POST_INSTALL_PERMISSIONS_PROMPT &&
276 !ShouldDisplayRevokeButton()) {
277 return ui::DIALOG_BUTTON_CANCEL;
[email protected]a2886e8b2013-06-08 05:15:02278 }
rdevlin.croninc7f8d132017-02-22 14:29:02279 return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
[email protected]15d267b42013-02-14 23:43:32280}
281
[email protected]6a72a632013-12-12 22:22:00282base::string16 ExtensionInstallPrompt::Prompt::GetAcceptButtonLabel() const {
rdevlin.croninc7f8d132017-02-22 14:29:02283 int id = -1;
284 switch (type_) {
285 case INSTALL_PROMPT:
286 case INLINE_INSTALL_PROMPT:
287 if (extension_->is_app())
288 id = IDS_EXTENSION_INSTALL_PROMPT_ACCEPT_BUTTON_APP;
289 else if (extension_->is_theme())
290 id = IDS_EXTENSION_INSTALL_PROMPT_ACCEPT_BUTTON_THEME;
291 else
292 id = IDS_EXTENSION_INSTALL_PROMPT_ACCEPT_BUTTON_EXTENSION;
293 break;
294 case RE_ENABLE_PROMPT:
295 id = IDS_EXTENSION_PROMPT_RE_ENABLE_BUTTON;
296 break;
297 case PERMISSIONS_PROMPT:
298 id = IDS_EXTENSION_PROMPT_PERMISSIONS_BUTTON;
299 break;
300 case EXTERNAL_INSTALL_PROMPT:
301 if (extension_->is_app())
302 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_APP;
303 else if (extension_->is_theme())
304 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_THEME;
305 else
306 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ACCEPT_BUTTON_EXTENSION;
307 break;
308 case POST_INSTALL_PERMISSIONS_PROMPT:
309 if (GetRetainedFileCount() && GetRetainedDeviceCount()) {
310 id =
311 IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_FILES_AND_DEVICES_BUTTON;
312 } else if (GetRetainedFileCount()) {
313 id = IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_FILES_BUTTON;
314 } else if (GetRetainedDeviceCount()) {
315 id = IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_DEVICES_BUTTON;
316 }
317 // If there are neither retained files nor devices, leave id -1 so there
318 // will be no "accept" button.
319 break;
320 case REMOTE_INSTALL_PROMPT:
321 if (extension_->is_app())
322 id = IDS_EXTENSION_PROMPT_REMOTE_INSTALL_BUTTON_APP;
323 else
324 id = IDS_EXTENSION_PROMPT_REMOTE_INSTALL_BUTTON_EXTENSION;
325 break;
326 case REPAIR_PROMPT:
327 if (extension_->is_app())
328 id = IDS_EXTENSION_PROMPT_REPAIR_BUTTON_APP;
329 else
330 id = IDS_EXTENSION_PROMPT_REPAIR_BUTTON_EXTENSION;
331 break;
332 case DELEGATED_PERMISSIONS_PROMPT:
333 id = IDS_EXTENSION_PROMPT_INSTALL_BUTTON;
334 break;
335 case UNSET_PROMPT_TYPE:
336 case NUM_PROMPT_TYPES:
337 NOTREACHED();
[email protected]846606012012-10-19 18:42:25338 }
rdevlin.croninc7f8d132017-02-22 14:29:02339
340 return id != -1 ? l10n_util::GetStringUTF16(id) : base::string16();
[email protected]c82da8c42012-06-08 19:49:11341}
342
[email protected]6a72a632013-12-12 22:22:00343base::string16 ExtensionInstallPrompt::Prompt::GetAbortButtonLabel() const {
rdevlin.croninc7f8d132017-02-22 14:29:02344 int id = -1;
345 switch (type_) {
346 case INSTALL_PROMPT:
347 case INLINE_INSTALL_PROMPT:
348 case RE_ENABLE_PROMPT:
349 case REMOTE_INSTALL_PROMPT:
350 case REPAIR_PROMPT:
351 case DELEGATED_PERMISSIONS_PROMPT:
352 id = IDS_CANCEL;
353 break;
354 case PERMISSIONS_PROMPT:
355 id = IDS_EXTENSION_PROMPT_PERMISSIONS_ABORT_BUTTON;
356 break;
357 case EXTERNAL_INSTALL_PROMPT:
358 id = IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ABORT_BUTTON;
359 break;
360 case POST_INSTALL_PERMISSIONS_PROMPT:
361 id = IDS_CLOSE;
362 break;
363 case UNSET_PROMPT_TYPE:
364 case NUM_PROMPT_TYPES:
365 NOTREACHED();
366 }
367
368 return l10n_util::GetStringUTF16(id);
[email protected]c82da8c42012-06-08 19:49:11369}
370
gpdavis.chromium0fbac4d2014-09-19 20:57:54371base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsHeading(
372 PermissionsType permissions_type) const {
373 switch (permissions_type) {
rdevlin.croninc7f8d132017-02-22 14:29:02374 case REGULAR_PERMISSIONS: {
375 int id = -1;
376 switch (type_) {
377 case INSTALL_PROMPT:
378 case INLINE_INSTALL_PROMPT:
379 case EXTERNAL_INSTALL_PROMPT:
380 case REMOTE_INSTALL_PROMPT:
381 case DELEGATED_PERMISSIONS_PROMPT:
382 id = IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO;
383 break;
384 case RE_ENABLE_PROMPT:
385 id = IDS_EXTENSION_PROMPT_WILL_NOW_HAVE_ACCESS_TO;
386 break;
387 case PERMISSIONS_PROMPT:
388 id = IDS_EXTENSION_PROMPT_WANTS_ACCESS_TO;
389 break;
390 case POST_INSTALL_PERMISSIONS_PROMPT:
391 case REPAIR_PROMPT:
392 id = IDS_EXTENSION_PROMPT_CAN_ACCESS;
393 break;
394 case UNSET_PROMPT_TYPE:
395 case NUM_PROMPT_TYPES:
396 NOTREACHED();
397 }
398 return l10n_util::GetStringUTF16(id);
399 }
gpdavis.chromium0fbac4d2014-09-19 20:57:54400 case WITHHELD_PERMISSIONS:
401 return l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WITHHELD);
402 case ALL_PERMISSIONS:
gpdavis.chromium0fbac4d2014-09-19 20:57:54403 NOTREACHED();
404 return base::string16();
405 }
rdevlin.croninc7f8d132017-02-22 14:29:02406 NOTREACHED();
407 return base::string16();
[email protected]c82da8c42012-06-08 19:49:11408}
409
[email protected]6a72a632013-12-12 22:22:00410base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFilesHeading() const {
jshin3a6c36bb2015-04-09 21:58:08411 return l10n_util::GetPluralStringFUTF16(
412 IDS_EXTENSION_PROMPT_RETAINED_FILES, GetRetainedFileCount());
[email protected]8ab7e6c2013-07-11 21:15:03413}
414
reillygc64d3dd2014-09-29 21:10:11415base::string16 ExtensionInstallPrompt::Prompt::GetRetainedDevicesHeading()
416 const {
jshin3a6c36bb2015-04-09 21:58:08417 return l10n_util::GetPluralStringFUTF16(
418 IDS_EXTENSION_PROMPT_RETAINED_DEVICES, GetRetainedDeviceCount());
reillygc64d3dd2014-09-29 21:10:11419}
420
[email protected]f2cd8992013-06-11 17:30:18421bool ExtensionInstallPrompt::Prompt::ShouldShowPermissions() const {
gpdavis.chromium0fbac4d2014-09-19 20:57:54422 return GetPermissionCount(ALL_PERMISSIONS) > 0 ||
423 type_ == POST_INSTALL_PERMISSIONS_PROMPT;
[email protected]f2cd8992013-06-11 17:30:18424}
425
asargent0a1c15f2015-12-09 02:25:21426bool ExtensionInstallPrompt::Prompt::ShouldUseTabModalDialog() const {
427 // For inline install, we want the install prompt to be tab modal so that the
428 // dialog is always clearly associated with the page that made the inline
429 // install request.
430 return type_ == INLINE_INSTALL_PROMPT;
431}
432
[email protected]c82da8c42012-06-08 19:49:11433void ExtensionInstallPrompt::Prompt::AppendRatingStars(
434 StarAppender appender, void* data) const {
435 CHECK(appender);
rdevlin.cronin5f6b69d2014-09-20 01:23:35436 CHECK(AllowWebstoreData(type_));
[email protected]c82da8c42012-06-08 19:49:11437 int rating_integer = floor(average_rating_);
438 double rating_fractional = average_rating_ - rating_integer;
439
440 if (rating_fractional > 0.66) {
441 rating_integer++;
442 }
443
444 if (rating_fractional < 0.33 || rating_fractional > 0.66) {
445 rating_fractional = 0;
446 }
447
448 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
449 int i;
450 for (i = 0; i < rating_integer; i++) {
451 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_ON), data);
452 }
453 if (rating_fractional) {
454 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_HALF_LEFT), data);
455 i++;
456 }
457 for (; i < kMaxExtensionRating; i++) {
458 appender(rb.GetImageSkiaNamed(IDR_EXTENSIONS_RATING_STAR_OFF), data);
459 }
460}
461
[email protected]6a72a632013-12-12 22:22:00462base::string16 ExtensionInstallPrompt::Prompt::GetRatingCount() const {
rdevlin.cronin5f6b69d2014-09-20 01:23:35463 CHECK(AllowWebstoreData(type_));
[email protected]6725048e2013-10-24 21:47:14464 return l10n_util::GetStringFUTF16(IDS_EXTENSION_RATING_COUNT,
465 base::IntToString16(rating_count_));
[email protected]c82da8c42012-06-08 19:49:11466}
467
[email protected]6a72a632013-12-12 22:22:00468base::string16 ExtensionInstallPrompt::Prompt::GetUserCount() const {
rdevlin.cronin5f6b69d2014-09-20 01:23:35469 CHECK(AllowWebstoreData(type_));
[email protected]dcde34b32013-07-31 02:28:45470
471 if (show_user_count_) {
[email protected]6725048e2013-10-24 21:47:14472 return l10n_util::GetStringFUTF16(IDS_EXTENSION_USER_COUNT,
473 base::UTF8ToUTF16(localized_user_count_));
[email protected]dcde34b32013-07-31 02:28:45474 }
[email protected]6725048e2013-10-24 21:47:14475 return base::string16();
[email protected]c82da8c42012-06-08 19:49:11476}
477
gpdavis.chromium0fbac4d2014-09-19 20:57:54478size_t ExtensionInstallPrompt::Prompt::GetPermissionCount(
479 PermissionsType permissions_type) const {
480 switch (permissions_type) {
481 case REGULAR_PERMISSIONS:
482 return prompt_permissions_.permissions.size();
483 case WITHHELD_PERMISSIONS:
484 return withheld_prompt_permissions_.permissions.size();
485 case ALL_PERMISSIONS:
486 return prompt_permissions_.permissions.size() +
487 withheld_prompt_permissions_.permissions.size();
488 default:
489 NOTREACHED();
490 return 0u;
491 }
[email protected]c82da8c42012-06-08 19:49:11492}
493
gpdavis.chromium0fbac4d2014-09-19 20:57:54494size_t ExtensionInstallPrompt::Prompt::GetPermissionsDetailsCount(
495 PermissionsType permissions_type) const {
496 switch (permissions_type) {
497 case REGULAR_PERMISSIONS:
498 return prompt_permissions_.details.size();
499 case WITHHELD_PERMISSIONS:
500 return withheld_prompt_permissions_.details.size();
501 case ALL_PERMISSIONS:
502 return prompt_permissions_.details.size() +
503 withheld_prompt_permissions_.details.size();
504 default:
505 NOTREACHED();
506 return 0u;
507 }
[email protected]8ab7e6c2013-07-11 21:15:03508}
509
gpdavis.chromium0fbac4d2014-09-19 20:57:54510base::string16 ExtensionInstallPrompt::Prompt::GetPermission(
511 size_t index,
512 PermissionsType permissions_type) const {
513 const InstallPromptPermissions& install_permissions =
514 GetPermissionsForType(permissions_type);
515 CHECK_LT(index, install_permissions.permissions.size());
516 return install_permissions.permissions[index];
[email protected]c82da8c42012-06-08 19:49:11517}
518
[email protected]6a72a632013-12-12 22:22:00519base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsDetails(
gpdavis.chromium0fbac4d2014-09-19 20:57:54520 size_t index,
521 PermissionsType permissions_type) const {
522 const InstallPromptPermissions& install_permissions =
523 GetPermissionsForType(permissions_type);
524 CHECK_LT(index, install_permissions.details.size());
525 return install_permissions.details[index];
[email protected]8ab7e6c2013-07-11 21:15:03526}
527
[email protected]79a6f99a2013-08-29 00:32:58528bool ExtensionInstallPrompt::Prompt::GetIsShowingDetails(
529 DetailsType type, size_t index) const {
530 switch (type) {
531 case PERMISSIONS_DETAILS:
gpdavis.chromium0fbac4d2014-09-19 20:57:54532 CHECK_LT(index, prompt_permissions_.is_showing_details.size());
533 return prompt_permissions_.is_showing_details[index];
534 case WITHHELD_PERMISSIONS_DETAILS:
535 CHECK_LT(index, withheld_prompt_permissions_.is_showing_details.size());
536 return withheld_prompt_permissions_.is_showing_details[index];
[email protected]79a6f99a2013-08-29 00:32:58537 case RETAINED_FILES_DETAILS:
538 return is_showing_details_for_retained_files_;
reillygc64d3dd2014-09-29 21:10:11539 case RETAINED_DEVICES_DETAILS:
540 return is_showing_details_for_retained_devices_;
[email protected]79a6f99a2013-08-29 00:32:58541 }
542 return false;
543}
544
[email protected]a2886e8b2013-06-08 05:15:02545size_t ExtensionInstallPrompt::Prompt::GetRetainedFileCount() const {
546 return retained_files_.size();
547}
548
[email protected]6a72a632013-12-12 22:22:00549base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFile(size_t index)
550 const {
[email protected]a2886e8b2013-06-08 05:15:02551 CHECK_LT(index, retained_files_.size());
[email protected]6725048e2013-10-24 21:47:14552 return retained_files_[index].AsUTF16Unsafe();
[email protected]a2886e8b2013-06-08 05:15:02553}
554
reillygc64d3dd2014-09-29 21:10:11555size_t ExtensionInstallPrompt::Prompt::GetRetainedDeviceCount() const {
556 return retained_device_messages_.size();
557}
558
559base::string16 ExtensionInstallPrompt::Prompt::GetRetainedDeviceMessageString(
560 size_t index) const {
561 CHECK_LT(index, retained_device_messages_.size());
562 return retained_device_messages_[index];
563}
564
565bool ExtensionInstallPrompt::Prompt::ShouldDisplayRevokeButton() const {
566 return !retained_files_.empty() || !retained_device_messages_.empty();
567}
568
gpdavis.chromium0fbac4d2014-09-19 20:57:54569ExtensionInstallPrompt::Prompt::InstallPromptPermissions&
570ExtensionInstallPrompt::Prompt::GetPermissionsForType(
571 PermissionsType permissions_type) {
572 DCHECK_NE(ALL_PERMISSIONS, permissions_type);
573 return permissions_type == REGULAR_PERMISSIONS ? prompt_permissions_
574 : withheld_prompt_permissions_;
575}
576
577const ExtensionInstallPrompt::Prompt::InstallPromptPermissions&
578ExtensionInstallPrompt::Prompt::GetPermissionsForType(
579 PermissionsType permissions_type) const {
580 DCHECK_NE(ALL_PERMISSIONS, permissions_type);
581 return permissions_type == REGULAR_PERMISSIONS ? prompt_permissions_
582 : withheld_prompt_permissions_;
583}
584
[email protected]a2886e8b2013-06-08 05:15:02585bool ExtensionInstallPrompt::Prompt::ShouldDisplayRevokeFilesButton() const {
586 return !retained_files_.empty();
587}
588
[email protected]c82da8c42012-06-08 19:49:11589// static
rdevlin.croninf84cab72015-12-12 03:45:23590ExtensionInstallPrompt::PromptType
591ExtensionInstallPrompt::GetReEnablePromptTypeForExtension(
592 content::BrowserContext* context,
593 const extensions::Extension* extension) {
594 bool is_remote_install =
595 context &&
596 extensions::ExtensionPrefs::Get(context)->HasDisableReason(
597 extension->id(), extensions::Extension::DISABLE_REMOTE_INSTALL);
598
599 return is_remote_install ? REMOTE_INSTALL_PROMPT : RE_ENABLE_PROMPT;
600}
601
602// static
[email protected]c82da8c42012-06-08 19:49:11603scoped_refptr<Extension>
604 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay(
[email protected]023b3d12013-12-23 18:46:49605 const base::DictionaryValue* manifest,
[email protected]c422a862012-07-31 15:46:13606 int flags,
[email protected]c82da8c42012-06-08 19:49:11607 const std::string& id,
608 const std::string& localized_name,
609 const std::string& localized_description,
610 std::string* error) {
dchengc963c7142016-04-08 03:55:22611 std::unique_ptr<base::DictionaryValue> localized_manifest;
[email protected]c82da8c42012-06-08 19:49:11612 if (!localized_name.empty() || !localized_description.empty()) {
613 localized_manifest.reset(manifest->DeepCopy());
614 if (!localized_name.empty()) {
[email protected]6bf90612013-08-15 00:36:27615 localized_manifest->SetString(extensions::manifest_keys::kName,
[email protected]c82da8c42012-06-08 19:49:11616 localized_name);
617 }
618 if (!localized_description.empty()) {
[email protected]6bf90612013-08-15 00:36:27619 localized_manifest->SetString(extensions::manifest_keys::kDescription,
[email protected]c82da8c42012-06-08 19:49:11620 localized_description);
621 }
622 }
623
624 return Extension::Create(
rdevlin.cronin165732a42016-07-18 22:25:08625 base::FilePath(), Manifest::INTERNAL,
626 localized_manifest.get() ? *localized_manifest : *manifest, flags, id,
[email protected]c82da8c42012-06-08 19:49:11627 error);
628}
629
[email protected]7f165342014-02-12 09:22:22630ExtensionInstallPrompt::ExtensionInstallPrompt(content::WebContents* contents)
pkotwicza57a1f322014-10-21 00:24:30631 : profile_(ProfileForWebContents(contents)),
[email protected]c82da8c42012-06-08 19:49:11632 extension_(NULL),
pkotwicza57a1f322014-10-21 00:24:30633 install_ui_(extensions::CreateExtensionInstallUI(
634 ProfileForWebContents(contents))),
pkotwicz2f181782014-10-29 17:33:45635 show_params_(new ExtensionInstallPromptShowParams(contents)),
rdevlin.cronin3fe4bd32016-01-12 18:45:40636 did_call_show_dialog_(false),
637 weak_factory_(this) {
[email protected]d382baa2014-06-17 18:50:01638}
[email protected]5db2e882012-12-20 10:17:26639
pkotwicz2175c622014-10-22 19:56:28640ExtensionInstallPrompt::ExtensionInstallPrompt(Profile* profile,
641 gfx::NativeWindow native_window)
pkotwicza57a1f322014-10-21 00:24:30642 : profile_(profile),
[email protected]5db2e882012-12-20 10:17:26643 extension_(NULL),
pkotwicza57a1f322014-10-21 00:24:30644 install_ui_(extensions::CreateExtensionInstallUI(profile)),
pkotwicz2f181782014-10-29 17:33:45645 show_params_(
646 new ExtensionInstallPromptShowParams(profile, native_window)),
rdevlin.cronin3fe4bd32016-01-12 18:45:40647 did_call_show_dialog_(false),
648 weak_factory_(this) {
[email protected]d382baa2014-06-17 18:50:01649}
[email protected]c82da8c42012-06-08 19:49:11650
651ExtensionInstallPrompt::~ExtensionInstallPrompt() {
652}
653
rdevlin.croninf84cab72015-12-12 03:45:23654void ExtensionInstallPrompt::ShowDialog(
rdevlin.cronin41593052016-01-08 01:40:12655 const DoneCallback& done_callback,
[email protected]c82da8c42012-06-08 19:49:11656 const Extension* extension,
rdevlin.croninf84cab72015-12-12 03:45:23657 const SkBitmap* icon,
658 const ShowDialogCallback& show_dialog_callback) {
rdevlin.cronin41593052016-01-08 01:40:12659 ShowDialog(done_callback, extension, icon,
ricea91d6fc122016-08-30 08:47:14660 base::MakeUnique<Prompt>(INSTALL_PROMPT), show_dialog_callback);
rdevlin.cronin2e252692015-12-15 21:47:02661}
662
663void ExtensionInstallPrompt::ShowDialog(
rdevlin.cronin41593052016-01-08 01:40:12664 const DoneCallback& done_callback,
rdevlin.cronin2e252692015-12-15 21:47:02665 const Extension* extension,
666 const SkBitmap* icon,
dchengc963c7142016-04-08 03:55:22667 std::unique_ptr<Prompt> prompt,
rdevlin.cronin2e252692015-12-15 21:47:02668 const ShowDialogCallback& show_dialog_callback) {
rdevlin.cronin41593052016-01-08 01:40:12669 ShowDialog(done_callback, extension, icon, std::move(prompt), nullptr,
rdevlin.croninf84cab72015-12-12 03:45:23670 show_dialog_callback);
671}
672
673void ExtensionInstallPrompt::ShowDialog(
rdevlin.cronin41593052016-01-08 01:40:12674 const DoneCallback& done_callback,
rdevlin.croninf84cab72015-12-12 03:45:23675 const Extension* extension,
676 const SkBitmap* icon,
dchengc963c7142016-04-08 03:55:22677 std::unique_ptr<Prompt> prompt,
678 std::unique_ptr<const PermissionSet> custom_permissions,
rdevlin.croninf84cab72015-12-12 03:45:23679 const ShowDialogCallback& show_dialog_callback) {
fdorayc16c6f82016-06-29 15:27:32680 DCHECK(ui_thread_checker_.CalledOnValidThread());
rdevlin.cronin2e252692015-12-15 21:47:02681 DCHECK(prompt);
[email protected]c82da8c42012-06-08 19:49:11682 extension_ = extension;
rdevlin.cronin41593052016-01-08 01:40:12683 done_callback_ = done_callback;
rdevlin.croninfc1499f2015-12-21 18:22:00684 if (icon && !icon->empty())
685 SetIcon(icon);
dcheng1fc00f12015-12-26 22:18:03686 prompt_ = std::move(prompt);
687 custom_permissions_ = std::move(custom_permissions);
[email protected]af6efb22012-10-12 02:23:05688 show_dialog_callback_ = show_dialog_callback;
[email protected]c82da8c42012-06-08 19:49:11689
690 // We special-case themes to not show any confirm UI. Instead they are
691 // immediately installed, and then we show an infobar (see OnInstallSuccess)
692 // to allow the user to revert if they don't like it.
rdevlin.cronin10f34542017-02-06 18:22:47693 if (extension->is_theme() && extension->from_webstore()) {
694 base::ResetAndReturn(&done_callback_).Run(Result::ACCEPTED);
695 return;
[email protected]c82da8c42012-06-08 19:49:11696 }
697
698 LoadImageIfNeeded();
699}
700
[email protected]c82da8c42012-06-08 19:49:11701void ExtensionInstallPrompt::OnInstallSuccess(const Extension* extension,
702 SkBitmap* icon) {
703 extension_ = extension;
704 SetIcon(icon);
705
706 install_ui_->OnInstallSuccess(extension, &icon_);
707}
708
[email protected]bf3d9df2012-07-24 23:20:27709void ExtensionInstallPrompt::OnInstallFailure(
ginkage47e603e2015-02-27 08:42:41710 const extensions::CrxInstallError& error) {
[email protected]c82da8c42012-06-08 19:49:11711 install_ui_->OnInstallFailure(error);
712}
713
714void ExtensionInstallPrompt::SetIcon(const SkBitmap* image) {
715 if (image)
716 icon_ = *image;
717 else
718 icon_ = SkBitmap();
[email protected]dd46a4ce2012-09-15 10:50:50719 if (icon_.empty()) {
720 // Let's set default icon bitmap whose size is equal to the default icon's
721 // pixel size under maximal supported scale factor. If the bitmap is larger
722 // than the one we need, it will be scaled down by the ui code.
treibd9e1d9d2015-04-24 11:17:04723 icon_ = GetDefaultIconBitmapForMaxScaleFactor(
724 extension_ ? extension_->is_app() : false);
[email protected]dd46a4ce2012-09-15 10:50:50725 }
[email protected]c82da8c42012-06-08 19:49:11726}
727
[email protected]ec7de0c5a2012-11-16 07:40:47728void ExtensionInstallPrompt::OnImageLoaded(const gfx::Image& image) {
[email protected]c82da8c42012-06-08 19:49:11729 SetIcon(image.IsEmpty() ? NULL : image.ToSkBitmap());
[email protected]4e494872013-09-06 09:13:54730 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11731}
732
733void ExtensionInstallPrompt::LoadImageIfNeeded() {
treib3d41d9f2016-04-12 08:53:01734 // Don't override an icon that was passed in. Also, |profile_| can be null in
735 // unit tests.
736 if (!icon_.empty() || !profile_) {
[email protected]4e494872013-09-06 09:13:54737 ShowConfirmation();
[email protected]c82da8c42012-06-08 19:49:11738 return;
739 }
740
[email protected]993da5e2013-03-23 21:25:16741 extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
[email protected]702d8b42013-02-27 20:55:50742 extension_,
743 extension_misc::EXTENSION_ICON_LARGE,
744 ExtensionIconSet::MATCH_BIGGER);
[email protected]0d0ba182014-06-03 12:40:43745
746 // Load the image asynchronously. The response will be sent to OnImageLoaded.
pkotwicza57a1f322014-10-21 00:24:30747 extensions::ImageLoader* loader = extensions::ImageLoader::Get(profile_);
[email protected]0d0ba182014-06-03 12:40:43748
749 std::vector<extensions::ImageLoader::ImageRepresentation> images_list;
750 images_list.push_back(extensions::ImageLoader::ImageRepresentation(
751 image,
752 extensions::ImageLoader::ImageRepresentation::NEVER_RESIZE,
753 gfx::Size(),
754 ui::SCALE_FACTOR_100P));
755 loader->LoadImagesAsync(
756 extension_,
757 images_list,
rdevlin.cronin3fe4bd32016-01-12 18:45:40758 base::Bind(&ExtensionInstallPrompt::OnImageLoaded,
759 weak_factory_.GetWeakPtr()));
[email protected]c82da8c42012-06-08 19:49:11760}
761
762void ExtensionInstallPrompt::ShowConfirmation() {
dchengc963c7142016-04-08 03:55:22763 std::unique_ptr<const PermissionSet> permissions_wrapper;
rdevlin.cronine2d0fd02015-09-24 22:35:49764 const PermissionSet* permissions_to_display = nullptr;
gpdavis.chromium0fbac4d2014-09-19 20:57:54765 if (custom_permissions_.get()) {
rdevlin.cronine2d0fd02015-09-24 22:35:49766 permissions_to_display = custom_permissions_.get();
gpdavis.chromium0fbac4d2014-09-19 20:57:54767 } else if (extension_) {
768 // Initialize permissions if they have not already been set so that
769 // withheld permissions are displayed properly in the install prompt.
770 extensions::PermissionsUpdater(
pkotwicza57a1f322014-10-21 00:24:30771 profile_, extensions::PermissionsUpdater::INIT_FLAG_TRANSIENT)
gpdavis.chromium0fbac4d2014-09-19 20:57:54772 .InitializePermissions(extension_);
773 permissions_to_display =
rdevlin.cronind630c302015-09-30 20:19:33774 &extension_->permissions_data()->active_permissions();
treib7496f63c2015-03-04 12:18:53775 // For delegated installs, all optional permissions are pre-approved by the
776 // person who triggers the install, so add them to the list.
treib3d41d9f2016-04-12 08:53:01777 if (prompt_->type() == DELEGATED_PERMISSIONS_PROMPT) {
rdevlin.cronind630c302015-09-30 20:19:33778 const PermissionSet& optional_permissions =
treib7496f63c2015-03-04 12:18:53779 extensions::PermissionsParser::GetOptionalPermissions(extension_);
rdevlin.cronine2d0fd02015-09-24 22:35:49780 permissions_wrapper = PermissionSet::CreateUnion(*permissions_to_display,
rdevlin.cronind630c302015-09-30 20:19:33781 optional_permissions);
rdevlin.cronine2d0fd02015-09-24 22:35:49782 permissions_to_display = permissions_wrapper.get();
treib7496f63c2015-03-04 12:18:53783 }
gpdavis.chromium0fbac4d2014-09-19 20:57:54784 }
785
rdevlin.cronine2d0fd02015-09-24 22:35:49786 if (permissions_to_display &&
[email protected]a397ec02014-08-08 15:48:13787 (!extension_ ||
788 !extensions::PermissionsData::ShouldSkipPermissionWarnings(
789 extension_->id()))) {
790 Manifest::Type type =
791 extension_ ? extension_->GetType() : Manifest::TYPE_UNKNOWN;
792 const extensions::PermissionMessageProvider* message_provider =
793 extensions::PermissionMessageProvider::Get();
treib7b45a34b2015-04-16 11:48:02794
treib8d2de482015-08-04 16:36:48795 prompt_->SetPermissions(message_provider->GetPermissionMessages(
796 message_provider->GetAllPermissionIDs(
rdevlin.cronind630c302015-09-30 20:19:33797 *permissions_to_display, type)),
gpdavis.chromium0fbac4d2014-09-19 20:57:54798 REGULAR_PERMISSIONS);
gpdavis.chromium0fbac4d2014-09-19 20:57:54799
rdevlin.cronine2d0fd02015-09-24 22:35:49800 const PermissionSet* withheld =
rdevlin.cronind630c302015-09-30 20:19:33801 extension_ ? &extension_->permissions_data()->withheld_permissions()
treiba21dcd92015-04-03 05:26:41802 : nullptr;
803 if (withheld && !withheld->IsEmpty()) {
gpdavis.chromium0fbac4d2014-09-19 20:57:54804 prompt_->SetPermissions(
treib8d2de482015-08-04 16:36:48805 message_provider->GetPermissionMessages(
rdevlin.cronind630c302015-09-30 20:19:33806 message_provider->GetAllPermissionIDs(*withheld, type)),
treib8d2de482015-08-04 16:36:48807 WITHHELD_PERMISSIONS);
gpdavis.chromium0fbac4d2014-09-19 20:57:54808 }
[email protected]bebe1d02012-08-02 20:17:09809 }
[email protected]c82da8c42012-06-08 19:49:11810
rdevlin.croninc7f8d132017-02-22 14:29:02811 prompt_->set_extension(extension_);
treibd9e1d9d2015-04-24 11:17:04812 prompt_->set_icon(gfx::Image::CreateFrom1xBitmap(icon_));
[email protected]af6efb22012-10-12 02:23:05813
pkotwicz2f181782014-10-29 17:33:45814 if (show_params_->WasParentDestroyed()) {
rdevlin.cronin41593052016-01-08 01:40:12815 base::ResetAndReturn(&done_callback_).Run(Result::ABORTED);
pkotwicz2f181782014-10-29 17:33:45816 return;
817 }
818
rdevlin.croninca5bf2da2015-12-17 21:21:08819 g_last_prompt_type_for_tests = prompt_->type();
820 did_call_show_dialog_ = true;
821
rdevlin.cronin41593052016-01-08 01:40:12822 if (AutoConfirmPrompt(&done_callback_))
rdevlin.croninca5bf2da2015-12-17 21:21:08823 return;
824
[email protected]5db2e882012-12-20 10:17:26825 if (show_dialog_callback_.is_null())
rdevlin.cronin41593052016-01-08 01:40:12826 show_dialog_callback_ = GetDefaultShowDialogCallback();
827 base::ResetAndReturn(&show_dialog_callback_)
828 .Run(show_params_.get(), base::ResetAndReturn(&done_callback_),
829 std::move(prompt_));
[email protected]c82da8c42012-06-08 19:49:11830}