1 // Copyright (c) 2013 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.
5 #include "chrome/browser/extensions/suspicious_extension_bubble_controller.h"
7 #include "base/lazy_instance.h"
8 #include "base/metrics/histogram.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/extensions/extension_message_bubble.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/common/url_constants.h"
15 #include "chrome/grit/chromium_strings.h"
16 #include "chrome/grit/generated_resources.h"
17 #include "extensions/browser/extension_prefs.h"
18 #include "extensions/browser/extension_system.h"
19 #include "extensions/common/extension.h"
20 #include "grit/components_strings.h"
21 #include "ui/base/l10n/l10n_util.h"
23 using extensions::ExtensionMessageBubbleController
;
27 // Whether the user has been notified about extension being wiped out.
28 const char kWipeoutAcknowledged
[] = "ack_wiped";
30 base::LazyInstance
<std::set
<Profile
*> > g_shown_for_profiles
=
31 LAZY_INSTANCE_INITIALIZER
;
33 ////////////////////////////////////////////////////////////////////////////////
34 // SuspiciousExtensionBubbleDelegate
36 class SuspiciousExtensionBubbleDelegate
37 : public ExtensionMessageBubbleController::Delegate
{
39 explicit SuspiciousExtensionBubbleDelegate(Profile
* profile
);
40 ~SuspiciousExtensionBubbleDelegate() override
;
42 // ExtensionMessageBubbleController::Delegate methods.
43 bool ShouldIncludeExtension(const std::string
& extension_id
) override
;
44 void AcknowledgeExtension(
45 const std::string
& extension_id
,
46 ExtensionMessageBubbleController::BubbleAction user_action
) override
;
47 void PerformAction(const extensions::ExtensionIdList
& list
) override
;
48 base::string16
GetTitle() const override
;
49 base::string16
GetMessageBody(bool anchored_to_browser_action
,
50 int extension_count
) const override
;
51 base::string16
GetOverflowText(
52 const base::string16
& overflow_count
) const override
;
53 GURL
GetLearnMoreUrl() const override
;
54 base::string16
GetActionButtonLabel() const override
;
55 base::string16
GetDismissButtonLabel() const override
;
56 bool ShouldShowExtensionList() const override
;
57 bool ShouldHighlightExtensions() const override
;
58 void LogExtensionCount(size_t count
) override
;
60 ExtensionMessageBubbleController::BubbleAction action
) override
;
62 DISALLOW_COPY_AND_ASSIGN(SuspiciousExtensionBubbleDelegate
);
65 SuspiciousExtensionBubbleDelegate::SuspiciousExtensionBubbleDelegate(
67 : extensions::ExtensionMessageBubbleController::Delegate(profile
) {
68 set_acknowledged_flag_pref_name(kWipeoutAcknowledged
);
71 SuspiciousExtensionBubbleDelegate::~SuspiciousExtensionBubbleDelegate() {
74 bool SuspiciousExtensionBubbleDelegate::ShouldIncludeExtension(
75 const std::string
& extension_id
) {
76 extensions::ExtensionPrefs
* prefs
= extensions::ExtensionPrefs::Get(
78 if (!prefs
->IsExtensionDisabled(extension_id
))
81 int disable_reasons
= prefs
->GetDisableReasons(extension_id
);
82 if (disable_reasons
& extensions::Extension::DISABLE_NOT_VERIFIED
)
83 return !HasBubbleInfoBeenAcknowledged(extension_id
);
88 void SuspiciousExtensionBubbleDelegate::AcknowledgeExtension(
89 const std::string
& extension_id
,
90 ExtensionMessageBubbleController::BubbleAction user_action
) {
91 SetBubbleInfoBeenAcknowledged(extension_id
, true);
94 void SuspiciousExtensionBubbleDelegate::PerformAction(
95 const extensions::ExtensionIdList
& list
) {
96 // This bubble solicits no action from the user. Or as Nimoy would have it:
97 // "Well, my work here is done".
100 base::string16
SuspiciousExtensionBubbleDelegate::GetTitle() const {
101 return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_TITLE
);
104 base::string16
SuspiciousExtensionBubbleDelegate::GetMessageBody(
105 bool anchored_to_browser_action
,
106 int extension_count
) const {
107 int message_id
= extension_count
== 1 ?
108 IDS_EXTENSIONS_SINGLE_UNSUPPORTED_DISABLED_BODY
:
109 IDS_EXTENSIONS_MULTIPLE_UNSUPPORTED_DISABLED_BODY
;
110 return l10n_util::GetStringFUTF16(
111 message_id
, l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE
));
114 base::string16
SuspiciousExtensionBubbleDelegate::GetOverflowText(
115 const base::string16
& overflow_count
) const {
116 return l10n_util::GetStringFUTF16(
117 IDS_EXTENSIONS_DISABLED_AND_N_MORE
,
121 GURL
SuspiciousExtensionBubbleDelegate::GetLearnMoreUrl() const {
122 return GURL(chrome::kRemoveNonCWSExtensionURL
);
126 SuspiciousExtensionBubbleDelegate::GetActionButtonLabel() const {
127 return base::string16();
131 SuspiciousExtensionBubbleDelegate::GetDismissButtonLabel() const {
132 return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BUTTON
);
135 bool SuspiciousExtensionBubbleDelegate::ShouldShowExtensionList() const {
139 bool SuspiciousExtensionBubbleDelegate::ShouldHighlightExtensions() const {
143 void SuspiciousExtensionBubbleDelegate::LogExtensionCount(
145 UMA_HISTOGRAM_COUNTS_100(
146 "ExtensionBubble.ExtensionWipeoutCount", count
);
149 void SuspiciousExtensionBubbleDelegate::LogAction(
150 ExtensionMessageBubbleController::BubbleAction action
) {
151 UMA_HISTOGRAM_ENUMERATION(
152 "ExtensionBubble.WipeoutUserSelection",
153 action
, ExtensionMessageBubbleController::ACTION_BOUNDARY
);
158 namespace extensions
{
160 ////////////////////////////////////////////////////////////////////////////////
161 // SuspiciousExtensionBubbleController
164 void SuspiciousExtensionBubbleController::ClearProfileListForTesting() {
165 g_shown_for_profiles
.Get().clear();
168 SuspiciousExtensionBubbleController::SuspiciousExtensionBubbleController(
170 : ExtensionMessageBubbleController(
171 new SuspiciousExtensionBubbleDelegate(profile
),
175 SuspiciousExtensionBubbleController::~SuspiciousExtensionBubbleController() {
178 bool SuspiciousExtensionBubbleController::ShouldShow() {
179 return !g_shown_for_profiles
.Get().count(profile_
->GetOriginalProfile()) &&
180 !GetExtensionList().empty();
183 void SuspiciousExtensionBubbleController::Show(ExtensionMessageBubble
* bubble
) {
184 g_shown_for_profiles
.Get().insert(profile_
->GetOriginalProfile());
185 ExtensionMessageBubbleController::Show(bubble
);
188 } // namespace extensions