1 // 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_error_ui_default.h"
6
7 #include "base/check.h"
8 #include "base/notreached.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_finder.h"
14 #include "chrome/browser/ui/chrome_pages.h"
15 #include "chrome/browser/ui/global_error/global_error_bubble_view_base.h"
16 #include "chrome/grit/generated_resources.h"
17 #include "extensions/browser/blocklist_state.h"
18 #include "extensions/browser/disable_reason.h"
19 #include "extensions/browser/extension_prefs.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_set.h"
22 #include "ui/base/l10n/l10n_util.h"
23
24 namespace extensions {
25
26 namespace {
27
GenerateTitle(const ExtensionSet & forbidden)28 base::string16 GenerateTitle(const ExtensionSet& forbidden) {
29 int app_count = 0;
30 int extension_count = 0;
31 for (const auto& extension : forbidden) {
32 if (extension->is_app())
33 app_count++;
34 else
35 extension_count++;
36 }
37
38 if ((app_count > 0) && (extension_count > 0)) {
39 return l10n_util::GetStringUTF16(IDS_EXTENSION_AND_APP_ALERT_TITLE);
40 }
41 if (app_count > 0) {
42 return l10n_util::GetPluralStringFUTF16(IDS_APP_ALERT_TITLE, app_count);
43 }
44 return l10n_util::GetPluralStringFUTF16(IDS_EXTENSION_ALERT_TITLE,
45 extension_count);
46 }
47
GenerateMessage(const ExtensionSet & forbidden,content::BrowserContext * browser_context)48 std::vector<base::string16> GenerateMessage(
49 const ExtensionSet& forbidden,
50 content::BrowserContext* browser_context) {
51 std::vector<base::string16> message;
52 message.reserve(forbidden.size());
53 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context);
54 for (const auto& extension : forbidden) {
55 BlocklistState blocklist_state =
56 prefs->GetExtensionBlocklistState(extension->id());
57 bool disable_remotely_for_malware = prefs->HasDisableReason(
58 extension->id(), disable_reason::DISABLE_REMOTELY_FOR_MALWARE);
59 int id = 0;
60 if (disable_remotely_for_malware ||
61 (blocklist_state == BlocklistState::BLOCKLISTED_MALWARE)) {
62 id = IDS_EXTENSION_ALERT_ITEM_BLOCKLISTED_MALWARE;
63 } else {
64 id = extension->is_app() ? IDS_APP_ALERT_ITEM_BLOCKLISTED_OTHER
65 : IDS_EXTENSION_ALERT_ITEM_BLOCKLISTED_OTHER;
66 }
67 message.push_back(
68 l10n_util::GetStringFUTF16(id, base::UTF8ToUTF16(extension->name())));
69 }
70 return message;
71 }
72
73 } // namespace
74
75 class ExtensionGlobalError : public GlobalErrorWithStandardBubble {
76 public:
ExtensionGlobalError(ExtensionErrorUI::Delegate * delegate)77 explicit ExtensionGlobalError(ExtensionErrorUI::Delegate* delegate)
78 : delegate_(delegate) {}
79
80 private:
81 // GlobalError overrides:
HasMenuItem()82 bool HasMenuItem() override { return false; }
83
MenuItemCommandID()84 int MenuItemCommandID() override {
85 NOTREACHED();
86 return 0;
87 }
88
MenuItemLabel()89 base::string16 MenuItemLabel() override {
90 NOTREACHED();
91 return {};
92 }
93
ExecuteMenuItem(Browser * browser)94 void ExecuteMenuItem(Browser* browser) override { NOTREACHED(); }
95
GetBubbleViewTitle()96 base::string16 GetBubbleViewTitle() override {
97 return GenerateTitle(delegate_->GetBlocklistedExtensions());
98 }
99
GetBubbleViewMessages()100 std::vector<base::string16> GetBubbleViewMessages() override {
101 return GenerateMessage(delegate_->GetBlocklistedExtensions(),
102 delegate_->GetContext());
103 }
104
GetBubbleViewAcceptButtonLabel()105 base::string16 GetBubbleViewAcceptButtonLabel() override {
106 return l10n_util::GetStringUTF16(IDS_EXTENSION_ALERT_ITEM_OK);
107 }
108
GetBubbleViewCancelButtonLabel()109 base::string16 GetBubbleViewCancelButtonLabel() override { return {}; }
110
GetBubbleViewDetailsButtonLabel()111 base::string16 GetBubbleViewDetailsButtonLabel() override {
112 return l10n_util::GetStringUTF16(IDS_EXTENSION_ALERT_ITEM_DETAILS);
113 }
114
OnBubbleViewDidClose(Browser * browser)115 void OnBubbleViewDidClose(Browser* browser) override {
116 delegate_->OnAlertClosed();
117 }
118
BubbleViewAcceptButtonPressed(Browser * browser)119 void BubbleViewAcceptButtonPressed(Browser* browser) override {
120 delegate_->OnAlertAccept();
121 }
122
BubbleViewCancelButtonPressed(Browser * browser)123 void BubbleViewCancelButtonPressed(Browser* browser) override {
124 NOTREACHED();
125 }
126
BubbleViewDetailsButtonPressed(Browser * browser)127 void BubbleViewDetailsButtonPressed(Browser* browser) override {
128 delegate_->OnAlertDetails();
129 }
130
131 ExtensionErrorUI::Delegate* delegate_;
132
133 ExtensionGlobalError(const ExtensionGlobalError&) = delete;
134 ExtensionGlobalError& operator=(const ExtensionGlobalError&) = delete;
135 };
136
ExtensionErrorUIDefault(ExtensionErrorUI::Delegate * delegate)137 ExtensionErrorUIDefault::ExtensionErrorUIDefault(
138 ExtensionErrorUI::Delegate* delegate)
139 : profile_(Profile::FromBrowserContext(delegate->GetContext())),
140 global_error_(std::make_unique<ExtensionGlobalError>(delegate)) {}
141
142 ExtensionErrorUIDefault::~ExtensionErrorUIDefault() = default;
143
ShowErrorInBubbleView()144 bool ExtensionErrorUIDefault::ShowErrorInBubbleView() {
145 Browser* browser = chrome::FindLastActiveWithProfile(profile_);
146 if (!browser)
147 return false;
148
149 browser_ = browser;
150 global_error_->ShowBubbleView(browser);
151 return true;
152 }
153
ShowExtensions()154 void ExtensionErrorUIDefault::ShowExtensions() {
155 DCHECK(browser_);
156 chrome::ShowExtensions(browser_, std::string());
157 }
158
Close()159 void ExtensionErrorUIDefault::Close() {
160 if (global_error_->HasShownBubbleView()) {
161 // Will end up calling into |global_error_|->OnBubbleViewDidClose,
162 // possibly synchronously.
163 global_error_->GetBubbleView()->CloseBubbleView();
164 }
165 }
166
GetErrorForTesting()167 GlobalErrorWithStandardBubble* ExtensionErrorUIDefault::GetErrorForTesting() {
168 return global_error_.get();
169 }
170
171 } // namespace extensions
172