blob: 43f9b3719c5ec876bd56563553b1a91ad3076f24 [file] [log] [blame]
[email protected]2894a512014-06-26 19:03:561// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/external_install_error.h"
6
avia2f4804a2015-12-24 23:11:137#include <stddef.h>
Peter Boströmf47f505d2021-04-15 05:03:208
9#include <memory>
dcheng1fc00f12015-12-26 22:18:0310#include <utility>
avia2f4804a2015-12-24 23:11:1311
[email protected]2894a512014-06-26 19:03:5612#include "base/bind.h"
fdoray283082bd2016-06-02 20:18:4613#include "base/location.h"
avia2f4804a2015-12-24 23:11:1314#include "base/macros.h"
probergebc529d62018-04-24 14:48:2615#include "base/metrics/field_trial_params.h"
rdevlin.croninb2daf2e42016-01-14 20:00:5416#include "base/metrics/histogram_macros.h"
fdoray283082bd2016-06-02 20:18:4617#include "base/single_thread_task_runner.h"
[email protected]2894a512014-06-26 19:03:5618#include "base/strings/utf_string_conversions.h"
fdoray283082bd2016-06-02 20:18:4619#include "base/threading/thread_task_runner_handle.h"
[email protected]2894a512014-06-26 19:03:5620#include "chrome/app/chrome_command_ids.h"
lazyboy0b9b30f2016-01-05 03:15:3721#include "chrome/browser/extensions/extension_install_error_menu_item_id_provider.h"
pkotwicz2f181782014-10-29 17:33:4522#include "chrome/browser/extensions/extension_install_prompt_show_params.h"
[email protected]2894a512014-06-26 19:03:5623#include "chrome/browser/extensions/extension_service.h"
probergebc529d62018-04-24 14:48:2624#include "chrome/browser/extensions/external_install_error_constants.h"
[email protected]2894a512014-06-26 19:03:5625#include "chrome/browser/extensions/external_install_manager.h"
26#include "chrome/browser/extensions/webstore_data_fetcher.h"
27#include "chrome/browser/profiles/profile.h"
28#include "chrome/browser/ui/browser.h"
29#include "chrome/browser/ui/browser_finder.h"
30#include "chrome/browser/ui/global_error/global_error.h"
31#include "chrome/browser/ui/global_error/global_error_service.h"
32#include "chrome/browser/ui/global_error/global_error_service_factory.h"
33#include "chrome/browser/ui/tabs/tab_strip_model.h"
probergebc529d62018-04-24 14:48:2634#include "chrome/common/chrome_features.h"
[email protected]af39f002014-08-22 10:18:1835#include "chrome/grit/generated_resources.h"
rdevlin.cronina1c3f1a2017-05-18 17:45:4636#include "components/keyed_service/content/browser_context_dependency_manager.h"
jamb84299e2016-04-12 16:58:5937#include "content/public/browser/storage_partition.h"
[email protected]2894a512014-06-26 19:03:5638#include "extensions/browser/extension_registry.h"
39#include "extensions/browser/extension_system.h"
[email protected]e43c61f2014-07-20 21:46:3440#include "extensions/browser/uninstall_reason.h"
[email protected]2894a512014-06-26 19:03:5641#include "extensions/common/constants.h"
42#include "extensions/common/extension.h"
[email protected]2894a512014-06-26 19:03:5643#include "ui/base/l10n/l10n_util.h"
44#include "ui/gfx/image/image.h"
rdevlin.cronin3fe4bd32016-01-12 18:45:4045#include "ui/gfx/image/image_skia.h"
[email protected]2894a512014-06-26 19:03:5646#include "ui/gfx/image/image_skia_operations.h"
47
48namespace extensions {
49
50namespace {
51
52// Return the menu label for a global error.
Jan Wilken Dörrief27844b2021-03-11 23:18:4853std::u16string GetMenuItemLabel(const Extension* extension) {
[email protected]2894a512014-06-26 19:03:5654 if (!extension)
Jan Wilken Dörrief27844b2021-03-11 23:18:4855 return std::u16string();
[email protected]2894a512014-06-26 19:03:5656
57 int id = -1;
58 if (extension->is_app())
59 id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_APP;
60 else if (extension->is_theme())
61 id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_THEME;
62 else
63 id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_EXTENSION;
64
65 return l10n_util::GetStringFUTF16(id, base::UTF8ToUTF16(extension->name()));
66}
67
probergebc529d62018-04-24 14:48:2668ExternalInstallError::DefaultDialogButtonSetting
69MapDefaultButtonStringToSetting(const std::string& button_setting_string) {
70 if (button_setting_string == kDefaultDialogButtonSettingOk)
71 return ExternalInstallError::DIALOG_BUTTON_OK;
72 if (button_setting_string == kDefaultDialogButtonSettingCancel)
73 return ExternalInstallError::DIALOG_BUTTON_CANCEL;
74 if (button_setting_string == kDefaultDialogButtonSettingNoDefault)
75 return ExternalInstallError::NO_DEFAULT_DIALOG_BUTTON;
76
77 NOTREACHED() << "Unexpected default button string: " << button_setting_string;
78 return ExternalInstallError::NOT_SPECIFIED;
79}
80
[email protected]2894a512014-06-26 19:03:5681// A global error that spawns a dialog when the menu item is clicked.
82class ExternalInstallMenuAlert : public GlobalError {
83 public:
84 explicit ExternalInstallMenuAlert(ExternalInstallError* error);
dchengae36a4a2014-10-21 12:36:3685 ~ExternalInstallMenuAlert() override;
[email protected]2894a512014-06-26 19:03:5686
87 private:
88 // GlobalError implementation.
dchengae36a4a2014-10-21 12:36:3689 Severity GetSeverity() override;
90 bool HasMenuItem() override;
91 int MenuItemCommandID() override;
Jan Wilken Dörrief27844b2021-03-11 23:18:4892 std::u16string MenuItemLabel() override;
dchengae36a4a2014-10-21 12:36:3693 void ExecuteMenuItem(Browser* browser) override;
94 bool HasBubbleView() override;
95 bool HasShownBubbleView() override;
96 void ShowBubbleView(Browser* browser) override;
97 GlobalErrorBubbleViewBase* GetBubbleView() override;
[email protected]2894a512014-06-26 19:03:5698
99 // The owning ExternalInstallError.
100 ExternalInstallError* error_;
101
lazyboy0b9b30f2016-01-05 03:15:37102 // Provides menu item id for GlobalError.
103 ExtensionInstallErrorMenuItemIdProvider id_provider_;
104
[email protected]2894a512014-06-26 19:03:56105 DISALLOW_COPY_AND_ASSIGN(ExternalInstallMenuAlert);
106};
107
108// A global error that spawns a bubble when the menu item is clicked.
109class ExternalInstallBubbleAlert : public GlobalErrorWithStandardBubble {
110 public:
rdevlin.cronin2e252692015-12-15 21:47:02111 ExternalInstallBubbleAlert(ExternalInstallError* error,
112 ExtensionInstallPrompt::Prompt* prompt);
dchengae36a4a2014-10-21 12:36:36113 ~ExternalInstallBubbleAlert() override;
[email protected]2894a512014-06-26 19:03:56114
115 private:
116 // GlobalError implementation.
dchengae36a4a2014-10-21 12:36:36117 Severity GetSeverity() override;
118 bool HasMenuItem() override;
119 int MenuItemCommandID() override;
Jan Wilken Dörrief27844b2021-03-11 23:18:48120 std::u16string MenuItemLabel() override;
dchengae36a4a2014-10-21 12:36:36121 void ExecuteMenuItem(Browser* browser) override;
[email protected]2894a512014-06-26 19:03:56122
123 // GlobalErrorWithStandardBubble implementation.
Jan Wilken Dörrief27844b2021-03-11 23:18:48124 std::u16string GetBubbleViewTitle() override;
125 std::vector<std::u16string> GetBubbleViewMessages() override;
126 std::u16string GetBubbleViewAcceptButtonLabel() override;
127 std::u16string GetBubbleViewCancelButtonLabel() override;
probergebc529d62018-04-24 14:48:26128 int GetDefaultDialogButton() const override;
dchengae36a4a2014-10-21 12:36:36129 void OnBubbleViewDidClose(Browser* browser) override;
130 void BubbleViewAcceptButtonPressed(Browser* browser) override;
131 void BubbleViewCancelButtonPressed(Browser* browser) override;
[email protected]2894a512014-06-26 19:03:56132
133 // The owning ExternalInstallError.
134 ExternalInstallError* error_;
lazyboy0b9b30f2016-01-05 03:15:37135 ExtensionInstallErrorMenuItemIdProvider id_provider_;
[email protected]2894a512014-06-26 19:03:56136
137 // The Prompt with all information, which we then use to populate the bubble.
rdevlin.cronin2e252692015-12-15 21:47:02138 // Owned by |error|.
[email protected]2894a512014-06-26 19:03:56139 ExtensionInstallPrompt::Prompt* prompt_;
140
141 DISALLOW_COPY_AND_ASSIGN(ExternalInstallBubbleAlert);
142};
143
144////////////////////////////////////////////////////////////////////////////////
145// ExternalInstallMenuAlert
146
147ExternalInstallMenuAlert::ExternalInstallMenuAlert(ExternalInstallError* error)
148 : error_(error) {
149}
150
151ExternalInstallMenuAlert::~ExternalInstallMenuAlert() {
152}
153
154GlobalError::Severity ExternalInstallMenuAlert::GetSeverity() {
155 return SEVERITY_LOW;
156}
157
158bool ExternalInstallMenuAlert::HasMenuItem() {
159 return true;
160}
161
162int ExternalInstallMenuAlert::MenuItemCommandID() {
lazyboy0b9b30f2016-01-05 03:15:37163 return id_provider_.menu_command_id();
[email protected]2894a512014-06-26 19:03:56164}
165
Jan Wilken Dörrief27844b2021-03-11 23:18:48166std::u16string ExternalInstallMenuAlert::MenuItemLabel() {
[email protected]2894a512014-06-26 19:03:56167 return GetMenuItemLabel(error_->GetExtension());
168}
169
170void ExternalInstallMenuAlert::ExecuteMenuItem(Browser* browser) {
171 error_->ShowDialog(browser);
172}
173
174bool ExternalInstallMenuAlert::HasBubbleView() {
175 return false;
176}
177
178bool ExternalInstallMenuAlert::HasShownBubbleView() {
179 NOTREACHED();
180 return true;
181}
182
183void ExternalInstallMenuAlert::ShowBubbleView(Browser* browser) {
184 NOTREACHED();
185}
186
187GlobalErrorBubbleViewBase* ExternalInstallMenuAlert::GetBubbleView() {
188 return NULL;
189}
190
191////////////////////////////////////////////////////////////////////////////////
192// ExternalInstallBubbleAlert
193
194ExternalInstallBubbleAlert::ExternalInstallBubbleAlert(
195 ExternalInstallError* error,
196 ExtensionInstallPrompt::Prompt* prompt)
197 : error_(error), prompt_(prompt) {
198 DCHECK(error_);
199 DCHECK(prompt_);
200}
201
202ExternalInstallBubbleAlert::~ExternalInstallBubbleAlert() {
203}
204
205GlobalError::Severity ExternalInstallBubbleAlert::GetSeverity() {
206 return SEVERITY_LOW;
207}
208
209bool ExternalInstallBubbleAlert::HasMenuItem() {
210 return true;
211}
212
213int ExternalInstallBubbleAlert::MenuItemCommandID() {
lazyboy0b9b30f2016-01-05 03:15:37214 return id_provider_.menu_command_id();
[email protected]2894a512014-06-26 19:03:56215}
216
Jan Wilken Dörrief27844b2021-03-11 23:18:48217std::u16string ExternalInstallBubbleAlert::MenuItemLabel() {
[email protected]2894a512014-06-26 19:03:56218 return GetMenuItemLabel(error_->GetExtension());
219}
220
221void ExternalInstallBubbleAlert::ExecuteMenuItem(Browser* browser) {
lazyboy1899eec42016-03-08 19:00:50222 // |browser| is nullptr in unit test.
223 if (browser)
224 ShowBubbleView(browser);
225 error_->DidOpenBubbleView();
[email protected]2894a512014-06-26 19:03:56226}
227
Jan Wilken Dörrief27844b2021-03-11 23:18:48228std::u16string ExternalInstallBubbleAlert::GetBubbleViewTitle() {
treib5e16e452015-06-19 09:55:39229 return l10n_util::GetStringFUTF16(
230 IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_BUBBLE_TITLE,
231 base::UTF8ToUTF16(prompt_->extension()->name()));
[email protected]2894a512014-06-26 19:03:56232}
233
Jan Wilken Dörrief27844b2021-03-11 23:18:48234std::vector<std::u16string>
[email protected]2894a512014-06-26 19:03:56235ExternalInstallBubbleAlert::GetBubbleViewMessages() {
Jan Wilken Dörrief27844b2021-03-11 23:18:48236 std::vector<std::u16string> messages;
treib5e16e452015-06-19 09:55:39237 int heading_id =
238 IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_BUBBLE_HEADING_EXTENSION;
239 if (prompt_->extension()->is_app())
240 heading_id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_BUBBLE_HEADING_APP;
241 else if (prompt_->extension()->is_theme())
242 heading_id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_BUBBLE_HEADING_THEME;
243 messages.push_back(l10n_util::GetStringUTF16(heading_id));
244
Devlin Cronind6e136a2018-05-15 23:39:32245 if (prompt_->GetPermissionCount()) {
246 messages.push_back(prompt_->GetPermissionsHeading());
247 for (size_t i = 0; i < prompt_->GetPermissionCount(); ++i) {
[email protected]2894a512014-06-26 19:03:56248 messages.push_back(l10n_util::GetStringFUTF16(
Devlin Cronind6e136a2018-05-15 23:39:32249 IDS_EXTENSION_PERMISSION_LINE, prompt_->GetPermission(i)));
[email protected]2894a512014-06-26 19:03:56250 }
251 }
252 // TODO(yoz): OAuth issue advice?
253 return messages;
254}
255
probergebc529d62018-04-24 14:48:26256int ExternalInstallBubbleAlert::GetDefaultDialogButton() const {
257 switch (error_->default_dialog_button_setting()) {
258 case ExternalInstallError::DIALOG_BUTTON_OK:
259 return ui::DIALOG_BUTTON_OK;
260 case ExternalInstallError::DIALOG_BUTTON_CANCEL:
261 return ui::DIALOG_BUTTON_CANCEL;
262 case ExternalInstallError::NO_DEFAULT_DIALOG_BUTTON:
263 return ui::DIALOG_BUTTON_NONE;
264 case ExternalInstallError::NOT_SPECIFIED:
265 break;
266 }
267 return GlobalErrorWithStandardBubble::GetDefaultDialogButton();
268}
269
Jan Wilken Dörrief27844b2021-03-11 23:18:48270std::u16string ExternalInstallBubbleAlert::GetBubbleViewAcceptButtonLabel() {
[email protected]2894a512014-06-26 19:03:56271 return prompt_->GetAcceptButtonLabel();
272}
273
Jan Wilken Dörrief27844b2021-03-11 23:18:48274std::u16string ExternalInstallBubbleAlert::GetBubbleViewCancelButtonLabel() {
[email protected]2894a512014-06-26 19:03:56275 return prompt_->GetAbortButtonLabel();
276}
277
278void ExternalInstallBubbleAlert::OnBubbleViewDidClose(Browser* browser) {
lazyboy1899eec42016-03-08 19:00:50279 error_->DidCloseBubbleView();
[email protected]2894a512014-06-26 19:03:56280}
281
282void ExternalInstallBubbleAlert::BubbleViewAcceptButtonPressed(
283 Browser* browser) {
rdevlin.cronin41593052016-01-08 01:40:12284 error_->OnInstallPromptDone(ExtensionInstallPrompt::Result::ACCEPTED);
[email protected]2894a512014-06-26 19:03:56285}
286
287void ExternalInstallBubbleAlert::BubbleViewCancelButtonPressed(
288 Browser* browser) {
rdevlin.cronin41593052016-01-08 01:40:12289 error_->OnInstallPromptDone(ExtensionInstallPrompt::Result::USER_CANCELED);
[email protected]2894a512014-06-26 19:03:56290}
291
292} // namespace
293
294////////////////////////////////////////////////////////////////////////////////
295// ExternalInstallError
296
probergebc529d62018-04-24 14:48:26297// static
298ExternalInstallError::DefaultDialogButtonSetting
299ExternalInstallError::GetDefaultDialogButton(
300 const base::Value& webstore_response) {
301 const base::Value* value = webstore_response.FindKeyOfType(
302 kExternalInstallDefaultButtonKey, base::Value::Type::STRING);
303 if (value) {
304 return MapDefaultButtonStringToSetting(value->GetString());
305 }
306
307 if (base::FeatureList::IsEnabled(
Oscar Johansson7f4c1b932018-06-12 06:11:58308 ::features::kExternalExtensionDefaultButtonControl)) {
probergebc529d62018-04-24 14:48:26309 std::string default_button = base::GetFieldTrialParamValueByFeature(
Oscar Johansson7f4c1b932018-06-12 06:11:58310 ::features::kExternalExtensionDefaultButtonControl,
probergebc529d62018-04-24 14:48:26311 kExternalInstallDefaultButtonKey);
312 if (!default_button.empty()) {
313 return MapDefaultButtonStringToSetting(default_button);
314 }
315 }
316
317 return NOT_SPECIFIED;
318}
319
[email protected]2894a512014-06-26 19:03:56320ExternalInstallError::ExternalInstallError(
321 content::BrowserContext* browser_context,
322 const std::string& extension_id,
323 AlertType alert_type,
324 ExternalInstallManager* manager)
325 : browser_context_(browser_context),
326 extension_id_(extension_id),
327 alert_type_(alert_type),
328 manager_(manager),
329 error_service_(GlobalErrorServiceFactory::GetForProfile(
Jeremy Roman495db682019-07-12 16:03:24330 Profile::FromBrowserContext(browser_context_))) {
Peter Boströmf47f505d2021-04-15 05:03:20331 prompt_ = std::make_unique<ExtensionInstallPrompt::Prompt>(
332 ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT);
[email protected]2894a512014-06-26 19:03:56333
Peter Boströmf47f505d2021-04-15 05:03:20334 webstore_data_fetcher_ =
335 std::make_unique<WebstoreDataFetcher>(this, GURL(), extension_id_);
Mark Pilgrim1a72e0512018-04-25 13:48:48336 webstore_data_fetcher_->Start(
337 content::BrowserContext::GetDefaultStoragePartition(browser_context_)
338 ->GetURLLoaderFactoryForBrowserProcess()
339 .get());
[email protected]2894a512014-06-26 19:03:56340}
341
342ExternalInstallError::~ExternalInstallError() {
rdevlin.cronina1c3f1a2017-05-18 17:45:46343#if DCHECK_IS_ON()
344 // Errors should only be removed while the profile is valid, since removing
345 // the error can trigger other subsystems listening for changes.
346 BrowserContextDependencyManager::GetInstance()
347 ->AssertBrowserContextWasntDestroyed(browser_context_);
348#endif
[email protected]2894a512014-06-26 19:03:56349 if (global_error_.get())
avi2451b252016-12-13 16:55:17350 error_service_->RemoveUnownedGlobalError(global_error_.get());
[email protected]2894a512014-06-26 19:03:56351}
352
rdevlin.cronin41593052016-01-08 01:40:12353void ExternalInstallError::OnInstallPromptDone(
354 ExtensionInstallPrompt::Result result) {
[email protected]2894a512014-06-26 19:03:56355 const Extension* extension = GetExtension();
rdevlin.croninb2daf2e42016-01-14 20:00:54356
357 // If the error isn't removed and deleted as part of handling the user's
358 // response (which can happen, e.g., if an uninstall fails), be sure to remove
359 // the error directly in order to ensure it's not called twice.
fdoray283082bd2016-06-02 20:18:46360 base::ThreadTaskRunnerHandle::Get()->PostTask(
tzik8d880ee2017-04-20 19:46:24361 FROM_HERE, base::BindOnce(&ExternalInstallError::RemoveError,
362 weak_factory_.GetWeakPtr()));
rdevlin.croninb2daf2e42016-01-14 20:00:54363
rdevlin.cronin41593052016-01-08 01:40:12364 switch (result) {
365 case ExtensionInstallPrompt::Result::ACCEPTED:
Tim Judkinse9221872020-01-25 01:37:53366 case ExtensionInstallPrompt::Result::ACCEPTED_AND_OPTION_CHECKED:
rdevlin.cronin41593052016-01-08 01:40:12367 if (extension) {
368 ExtensionSystem::Get(browser_context_)
369 ->extension_service()
370 ->GrantPermissionsAndEnableExtension(extension);
rdevlin.cronin41593052016-01-08 01:40:12371 }
372 break;
373 case ExtensionInstallPrompt::Result::USER_CANCELED:
374 if (extension) {
Devlin Cronin24cd22c32019-01-29 18:14:36375 ExtensionSystem::Get(browser_context_)
rdevlin.cronin41593052016-01-08 01:40:12376 ->extension_service()
377 ->UninstallExtension(extension_id_,
378 extensions::UNINSTALL_REASON_INSTALL_CANCELED,
rdevlin.cronin41593052016-01-08 01:40:12379 nullptr); // Ignore error.
rdevlin.cronin41593052016-01-08 01:40:12380 }
381 break;
382 case ExtensionInstallPrompt::Result::ABORTED:
lazyboy1899eec42016-03-08 19:00:50383 manager_->DidChangeInstallAlertVisibility(this, false);
rdevlin.cronin41593052016-01-08 01:40:12384 break;
[email protected]2894a512014-06-26 19:03:56385 }
rdevlin.croninb2daf2e42016-01-14 20:00:54386 // NOTE: We may be deleted here!
[email protected]2894a512014-06-26 19:03:56387}
388
lazyboy1899eec42016-03-08 19:00:50389void ExternalInstallError::DidOpenBubbleView() {
390 manager_->DidChangeInstallAlertVisibility(this, true);
391}
392
393void ExternalInstallError::DidCloseBubbleView() {
394 manager_->DidChangeInstallAlertVisibility(this, false);
395}
396
[email protected]2894a512014-06-26 19:03:56397void ExternalInstallError::ShowDialog(Browser* browser) {
398 DCHECK(install_ui_.get());
399 DCHECK(prompt_.get());
400 DCHECK(browser);
401 content::WebContents* web_contents = NULL;
[email protected]2894a512014-06-26 19:03:56402 web_contents = browser->tab_strip_model()->GetActiveWebContents();
Peter Boströmf47f505d2021-04-15 05:03:20403 install_ui_show_params_ =
404 std::make_unique<ExtensionInstallPromptShowParams>(web_contents);
lazyboy1899eec42016-03-08 19:00:50405 manager_->DidChangeInstallAlertVisibility(this, true);
[email protected]2894a512014-06-26 19:03:56406 ExtensionInstallPrompt::GetDefaultShowDialogCallback().Run(
rdevlin.cronin41593052016-01-08 01:40:12407 install_ui_show_params_.get(),
Yi Gu7fabef122020-12-16 13:03:31408 base::BindOnce(&ExternalInstallError::OnInstallPromptDone,
409 weak_factory_.GetWeakPtr()),
rdevlin.cronin41593052016-01-08 01:40:12410 std::move(prompt_));
[email protected]2894a512014-06-26 19:03:56411}
412
413const Extension* ExternalInstallError::GetExtension() const {
414 return ExtensionRegistry::Get(browser_context_)
415 ->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING);
416}
417
Toby Huang7b4816f2020-02-07 23:54:07418void ExternalInstallError::OnWebstoreRequestFailure(
419 const std::string& extension_id) {
[email protected]2894a512014-06-26 19:03:56420 OnFetchComplete();
421}
422
423void ExternalInstallError::OnWebstoreResponseParseSuccess(
Toby Huang7b4816f2020-02-07 23:54:07424 const std::string& extension_id,
dchengc963c7142016-04-08 03:55:22425 std::unique_ptr<base::DictionaryValue> webstore_data) {
[email protected]2894a512014-06-26 19:03:56426 std::string localized_user_count;
[email protected]96aebe22014-07-16 04:07:51427 double average_rating = 0;
428 int rating_count = 0;
[email protected]2894a512014-06-26 19:03:56429 if (!webstore_data->GetString(kUsersKey, &localized_user_count) ||
430 !webstore_data->GetDouble(kAverageRatingKey, &average_rating) ||
431 !webstore_data->GetInteger(kRatingCountKey, &rating_count)) {
432 // If we don't get a valid webstore response, short circuit, and continue
433 // to show a prompt without webstore data.
434 OnFetchComplete();
435 return;
436 }
437
probergebc529d62018-04-24 14:48:26438 default_dialog_button_setting_ = GetDefaultDialogButton(*webstore_data.get());
439
[email protected]2894a512014-06-26 19:03:56440 bool show_user_count = true;
441 webstore_data->GetBoolean(kShowUserCountKey, &show_user_count);
442
443 prompt_->SetWebstoreData(
444 localized_user_count, show_user_count, average_rating, rating_count);
445 OnFetchComplete();
446}
447
448void ExternalInstallError::OnWebstoreResponseParseFailure(
Toby Huang7b4816f2020-02-07 23:54:07449 const std::string& extension_id,
[email protected]2894a512014-06-26 19:03:56450 const std::string& error) {
451 OnFetchComplete();
452}
453
454void ExternalInstallError::OnFetchComplete() {
455 // Create a new ExtensionInstallPrompt. We pass in NULL for the UI
456 // components because we display at a later point, and don't want
457 // to pass ones which may be invalidated.
Peter Boströmf47f505d2021-04-15 05:03:20458 install_ui_ = base::WrapUnique(
[email protected]2894a512014-06-26 19:03:56459 new ExtensionInstallPrompt(Profile::FromBrowserContext(browser_context_),
Peter Boströmf47f505d2021-04-15 05:03:20460 /*native_window=*/nullptr));
[email protected]2894a512014-06-26 19:03:56461
Yi Gu7fabef122020-12-16 13:03:31462 install_ui_->ShowDialog(
463 base::BindOnce(&ExternalInstallError::OnInstallPromptDone,
464 weak_factory_.GetWeakPtr()),
465 GetExtension(),
466 nullptr, // Force a fetch of the icon.
467 std::move(prompt_),
468 base::BindRepeating(&ExternalInstallError::OnDialogReady,
469 weak_factory_.GetWeakPtr()));
[email protected]2894a512014-06-26 19:03:56470}
471
472void ExternalInstallError::OnDialogReady(
pkotwicz2f181782014-10-29 17:33:45473 ExtensionInstallPromptShowParams* show_params,
Yi Gu7fabef122020-12-16 13:03:31474 ExtensionInstallPrompt::DoneCallback callback,
dchengc963c7142016-04-08 03:55:22475 std::unique_ptr<ExtensionInstallPrompt::Prompt> prompt) {
dcheng1fc00f12015-12-26 22:18:03476 prompt_ = std::move(prompt);
[email protected]2894a512014-06-26 19:03:56477
478 if (alert_type_ == BUBBLE_ALERT) {
Peter Boströmf47f505d2021-04-15 05:03:20479 global_error_ =
480 std::make_unique<ExternalInstallBubbleAlert>(this, prompt_.get());
avi2451b252016-12-13 16:55:17481 error_service_->AddUnownedGlobalError(global_error_.get());
[email protected]2894a512014-06-26 19:03:56482
lazyboy1899eec42016-03-08 19:00:50483 if (!manager_->has_currently_visible_install_alert()) {
484 // |browser| is nullptr during unit tests, so call
485 // DidChangeInstallAlertVisibility() regardless because we depend on this
486 // in unit tests.
487 manager_->DidChangeInstallAlertVisibility(this, true);
488 Browser* browser = chrome::FindTabbedBrowser(
489 Profile::FromBrowserContext(browser_context_), true);
490 if (browser)
491 global_error_->ShowBubbleView(browser);
492 }
[email protected]2894a512014-06-26 19:03:56493 } else {
494 DCHECK(alert_type_ == MENU_ALERT);
Peter Boströmf47f505d2021-04-15 05:03:20495 global_error_ = std::make_unique<ExternalInstallMenuAlert>(this);
avi2451b252016-12-13 16:55:17496 error_service_->AddUnownedGlobalError(global_error_.get());
[email protected]2894a512014-06-26 19:03:56497 }
498}
499
rdevlin.croninb2daf2e42016-01-14 20:00:54500void ExternalInstallError::RemoveError() {
501 manager_->RemoveExternalInstallError(extension_id_);
502}
503
[email protected]2894a512014-06-26 19:03:56504} // namespace extensions