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"
8 #include "base/lazy_instance.h"
9 #include "base/metrics/histogram.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/extensions/extension_message_bubble.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_finder.h"
15 #include "chrome/common/url_constants.h"
16 #include "content/public/browser/user_metrics.h"
17 #include "extensions/browser/extension_prefs.h"
18 #include "extensions/browser/extension_system.h"
19 #include "grit/chromium_strings.h"
20 #include "grit/generated_resources.h"
21 #include "ui/base/l10n/l10n_util.h"
25 base::LazyInstance
<std::set
<Profile
*> > g_shown_for_profiles
=
26 LAZY_INSTANCE_INITIALIZER
;
28 ////////////////////////////////////////////////////////////////////////////////
29 // SuspiciousExtensionBubbleDelegate
31 SuspiciousExtensionBubbleDelegate::SuspiciousExtensionBubbleDelegate(
32 ExtensionService
* service
)
36 SuspiciousExtensionBubbleDelegate::~SuspiciousExtensionBubbleDelegate() {
39 bool SuspiciousExtensionBubbleDelegate::ShouldIncludeExtension(
40 const std::string
& extension_id
) {
41 extensions::ExtensionPrefs
* prefs
= service_
->extension_prefs();
42 if (!prefs
->IsExtensionDisabled(extension_id
))
45 int disble_reasons
= prefs
->GetDisableReasons(extension_id
);
46 if (disble_reasons
& extensions::Extension::DISABLE_NOT_VERIFIED
)
47 return !prefs
->HasWipeoutBeenAcknowledged(extension_id
);
52 void SuspiciousExtensionBubbleDelegate::AcknowledgeExtension(
53 const std::string
& extension_id
,
54 ExtensionMessageBubbleController::BubbleAction user_action
) {
55 extensions::ExtensionPrefs
* prefs
= service_
->extension_prefs();
56 prefs
->SetWipeoutAcknowledged(extension_id
, true);
59 void SuspiciousExtensionBubbleDelegate::PerformAction(
60 const extensions::ExtensionIdList
& list
) {
61 // This bubble solicits no action from the user. Or as Nimoy would have it:
62 // "Well, my work here is done".
65 base::string16
SuspiciousExtensionBubbleDelegate::GetTitle() const {
66 return l10n_util::GetStringUTF16(IDS_EXTENSIONS_SUSPICIOUS_DISABLED_TITLE
);
69 base::string16
SuspiciousExtensionBubbleDelegate::GetMessageBody() const {
70 return l10n_util::GetStringFUTF16(IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BODY
,
71 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE
));
74 base::string16
SuspiciousExtensionBubbleDelegate::GetOverflowText(
75 const base::string16
& overflow_count
) const {
76 base::string16 overflow_string
= l10n_util::GetStringUTF16(
77 IDS_EXTENSIONS_SUSPICIOUS_DISABLED_AND_N_MORE
);
78 base::string16 new_string
;
80 // Just before string freeze, we checked in # as a substitution value for
81 // this string, whereas we should have used $1. It was discovered too late,
82 // so we do the substitution by hand in that case.
83 if (overflow_string
.find(base::ASCIIToUTF16("#")) != base::string16::npos
) {
84 base::ReplaceChars(overflow_string
, base::ASCIIToUTF16("#").c_str(),
85 overflow_count
, &new_string
);
87 new_string
= l10n_util::GetStringFUTF16(
88 IDS_EXTENSIONS_SUSPICIOUS_DISABLED_AND_N_MORE
,
96 SuspiciousExtensionBubbleDelegate::GetLearnMoreLabel() const {
97 return l10n_util::GetStringUTF16(IDS_LEARN_MORE
);
100 GURL
SuspiciousExtensionBubbleDelegate::GetLearnMoreUrl() const {
101 return GURL(chrome::kRemoveNonCWSExtensionURL
);
105 SuspiciousExtensionBubbleDelegate::GetActionButtonLabel() const {
106 return base::string16();
110 SuspiciousExtensionBubbleDelegate::GetDismissButtonLabel() const {
111 return l10n_util::GetStringUTF16(IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BUTTON
);
115 SuspiciousExtensionBubbleDelegate::ShouldShowExtensionList() const {
119 void SuspiciousExtensionBubbleDelegate::LogExtensionCount(
121 UMA_HISTOGRAM_COUNTS_100(
122 "ExtensionWipeoutBubble.ExtensionWipeoutCount", count
);
125 void SuspiciousExtensionBubbleDelegate::LogAction(
126 ExtensionMessageBubbleController::BubbleAction action
) {
127 UMA_HISTOGRAM_ENUMERATION(
128 "ExtensionWipeoutBubble.UserSelection",
129 action
, ExtensionMessageBubbleController::ACTION_BOUNDARY
);
134 namespace extensions
{
136 ////////////////////////////////////////////////////////////////////////////////
137 // SuspiciousExtensionBubbleController
140 void SuspiciousExtensionBubbleController::ClearProfileListForTesting() {
141 g_shown_for_profiles
.Get().clear();
144 SuspiciousExtensionBubbleController::SuspiciousExtensionBubbleController(
146 : ExtensionMessageBubbleController(
147 new SuspiciousExtensionBubbleDelegate(
148 extensions::ExtensionSystem::Get(profile
)->extension_service()),
153 SuspiciousExtensionBubbleController::~SuspiciousExtensionBubbleController() {
156 bool SuspiciousExtensionBubbleController::ShouldShow() {
157 return !g_shown_for_profiles
.Get().count(profile_
) &&
158 !GetExtensionList().empty();
161 void SuspiciousExtensionBubbleController::Show(ExtensionMessageBubble
* bubble
) {
162 g_shown_for_profiles
.Get().insert(profile_
);
163 ExtensionMessageBubbleController::Show(bubble
);
166 } // namespace extensions