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/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_finder.h"
16 #include "chrome/common/url_constants.h"
17 #include "content/public/browser/user_metrics.h"
18 #include "extensions/browser/extension_prefs.h"
19 #include "extensions/browser/extension_system.h"
20 #include "grit/chromium_strings.h"
21 #include "grit/generated_resources.h"
22 #include "ui/base/l10n/l10n_util.h"
26 base::LazyInstance<std::set<Profile*> > g_shown_for_profiles =
27 LAZY_INSTANCE_INITIALIZER;
29 ////////////////////////////////////////////////////////////////////////////////
30 // SuspiciousExtensionBubbleDelegate
32 SuspiciousExtensionBubbleDelegate::SuspiciousExtensionBubbleDelegate(
34 : profile_(profile) {}
36 SuspiciousExtensionBubbleDelegate::~SuspiciousExtensionBubbleDelegate() {
39 bool SuspiciousExtensionBubbleDelegate::ShouldIncludeExtension(
40 const std::string& extension_id) {
41 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_);
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 = extensions::ExtensionPrefs::Get(profile_);
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 // TODO(asargent/finnur) - we've temporarily borrowed an already translated
67 // string that has another purpose so we could change this on a release
68 // branch. crbug.com/370517
69 return l10n_util::GetStringUTF16(
70 IDS_PERFORMANCE_MONITOR_EXTENSION_DISABLE_EVENT_MOUSEOVER);
73 base::string16 SuspiciousExtensionBubbleDelegate::GetMessageBody() const {
74 return l10n_util::GetStringFUTF16(IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BODY,
75 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE));
78 base::string16 SuspiciousExtensionBubbleDelegate::GetOverflowText(
79 const base::string16& overflow_count) const {
80 base::string16 overflow_string = l10n_util::GetStringUTF16(
81 IDS_EXTENSIONS_SUSPICIOUS_DISABLED_AND_N_MORE);
82 base::string16 new_string;
84 // Just before string freeze, we checked in # as a substitution value for
85 // this string, whereas we should have used $1. It was discovered too late,
86 // so we do the substitution by hand in that case.
87 if (overflow_string.find(base::ASCIIToUTF16("#")) != base::string16::npos) {
88 base::ReplaceChars(overflow_string, base::ASCIIToUTF16("#").c_str(),
89 overflow_count, &new_string);
91 new_string = l10n_util::GetStringFUTF16(
92 IDS_EXTENSIONS_SUSPICIOUS_DISABLED_AND_N_MORE,
100 SuspiciousExtensionBubbleDelegate::GetLearnMoreLabel() const {
101 return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
104 GURL SuspiciousExtensionBubbleDelegate::GetLearnMoreUrl() const {
105 return GURL(chrome::kRemoveNonCWSExtensionURL);
109 SuspiciousExtensionBubbleDelegate::GetActionButtonLabel() const {
110 return base::string16();
114 SuspiciousExtensionBubbleDelegate::GetDismissButtonLabel() const {
115 return l10n_util::GetStringUTF16(IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BUTTON);
119 SuspiciousExtensionBubbleDelegate::ShouldShowExtensionList() const {
123 void SuspiciousExtensionBubbleDelegate::LogExtensionCount(
125 UMA_HISTOGRAM_COUNTS_100(
126 "ExtensionWipeoutBubble.ExtensionWipeoutCount", count);
129 void SuspiciousExtensionBubbleDelegate::LogAction(
130 ExtensionMessageBubbleController::BubbleAction action) {
131 UMA_HISTOGRAM_ENUMERATION(
132 "ExtensionWipeoutBubble.UserSelection",
133 action, ExtensionMessageBubbleController::ACTION_BOUNDARY);
138 namespace extensions {
140 ////////////////////////////////////////////////////////////////////////////////
141 // SuspiciousExtensionBubbleController
144 void SuspiciousExtensionBubbleController::ClearProfileListForTesting() {
145 g_shown_for_profiles.Get().clear();
148 SuspiciousExtensionBubbleController::SuspiciousExtensionBubbleController(
150 : ExtensionMessageBubbleController(
151 new SuspiciousExtensionBubbleDelegate(profile),
155 SuspiciousExtensionBubbleController::~SuspiciousExtensionBubbleController() {
158 bool SuspiciousExtensionBubbleController::ShouldShow() {
159 return !g_shown_for_profiles.Get().count(profile_) &&
160 !GetExtensionList().empty();
163 void SuspiciousExtensionBubbleController::Show(ExtensionMessageBubble* bubble) {
164 g_shown_for_profiles.Get().insert(profile_);
165 ExtensionMessageBubbleController::Show(bubble);
168 } // namespace extensions