• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/extensions/suspicious_extension_bubble_controller.h"
6 
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 "extensions/browser/extension_prefs.h"
16 #include "extensions/browser/extension_system.h"
17 #include "extensions/common/extension.h"
18 #include "grit/chromium_strings.h"
19 #include "grit/generated_resources.h"
20 #include "ui/base/l10n/l10n_util.h"
21 
22 using extensions::ExtensionMessageBubbleController;
23 
24 namespace {
25 
26 base::LazyInstance<std::set<Profile*> > g_shown_for_profiles =
27   LAZY_INSTANCE_INITIALIZER;
28 
29 ////////////////////////////////////////////////////////////////////////////////
30 // SuspiciousExtensionBubbleDelegate
31 
32 class SuspiciousExtensionBubbleDelegate
33     : public ExtensionMessageBubbleController::Delegate {
34  public:
35   explicit SuspiciousExtensionBubbleDelegate(Profile* profile);
36   virtual ~SuspiciousExtensionBubbleDelegate();
37 
38   // ExtensionMessageBubbleController::Delegate methods.
39   virtual bool ShouldIncludeExtension(const std::string& extension_id) OVERRIDE;
40   virtual void AcknowledgeExtension(
41       const std::string& extension_id,
42       ExtensionMessageBubbleController::BubbleAction user_action) OVERRIDE;
43   virtual void PerformAction(const extensions::ExtensionIdList& list) OVERRIDE;
44   virtual base::string16 GetTitle() const OVERRIDE;
45   virtual base::string16 GetMessageBody(
46       bool anchored_to_browser_action) const OVERRIDE;
47   virtual base::string16 GetOverflowText(
48       const base::string16& overflow_count) const OVERRIDE;
49   virtual base::string16 GetLearnMoreLabel() const OVERRIDE;
50   virtual GURL GetLearnMoreUrl() const OVERRIDE;
51   virtual base::string16 GetActionButtonLabel() const OVERRIDE;
52   virtual base::string16 GetDismissButtonLabel() const OVERRIDE;
53   virtual bool ShouldShowExtensionList() const OVERRIDE;
54   virtual void LogExtensionCount(size_t count) OVERRIDE;
55   virtual void LogAction(
56       ExtensionMessageBubbleController::BubbleAction action) OVERRIDE;
57 
58  private:
59   // Our profile. Weak, not owned by us.
60   Profile* profile_;
61 
62   DISALLOW_COPY_AND_ASSIGN(SuspiciousExtensionBubbleDelegate);
63 };
64 
SuspiciousExtensionBubbleDelegate(Profile * profile)65 SuspiciousExtensionBubbleDelegate::SuspiciousExtensionBubbleDelegate(
66     Profile* profile)
67     : profile_(profile) {}
68 
~SuspiciousExtensionBubbleDelegate()69 SuspiciousExtensionBubbleDelegate::~SuspiciousExtensionBubbleDelegate() {
70 }
71 
ShouldIncludeExtension(const std::string & extension_id)72 bool SuspiciousExtensionBubbleDelegate::ShouldIncludeExtension(
73       const std::string& extension_id) {
74   extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_);
75   if (!prefs->IsExtensionDisabled(extension_id))
76     return false;
77 
78   int disble_reasons = prefs->GetDisableReasons(extension_id);
79   if (disble_reasons & extensions::Extension::DISABLE_NOT_VERIFIED)
80     return !prefs->HasWipeoutBeenAcknowledged(extension_id);
81 
82   return false;
83 }
84 
AcknowledgeExtension(const std::string & extension_id,ExtensionMessageBubbleController::BubbleAction user_action)85 void SuspiciousExtensionBubbleDelegate::AcknowledgeExtension(
86     const std::string& extension_id,
87     ExtensionMessageBubbleController::BubbleAction user_action) {
88   extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_);
89   prefs->SetWipeoutAcknowledged(extension_id, true);
90 }
91 
PerformAction(const extensions::ExtensionIdList & list)92 void SuspiciousExtensionBubbleDelegate::PerformAction(
93     const extensions::ExtensionIdList& list) {
94   // This bubble solicits no action from the user. Or as Nimoy would have it:
95   // "Well, my work here is done".
96 }
97 
GetTitle() const98 base::string16 SuspiciousExtensionBubbleDelegate::GetTitle() const {
99   return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_TITLE);
100 }
101 
GetMessageBody(bool anchored_to_browser_action) const102 base::string16 SuspiciousExtensionBubbleDelegate::GetMessageBody(
103     bool anchored_to_browser_action) const {
104   return l10n_util::GetStringFUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BODY,
105       l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE));
106 }
107 
GetOverflowText(const base::string16 & overflow_count) const108 base::string16 SuspiciousExtensionBubbleDelegate::GetOverflowText(
109     const base::string16& overflow_count) const {
110   return l10n_util::GetStringFUTF16(
111             IDS_EXTENSIONS_DISABLED_AND_N_MORE,
112             overflow_count);
113 }
114 
115 base::string16
GetLearnMoreLabel() const116 SuspiciousExtensionBubbleDelegate::GetLearnMoreLabel() const {
117   return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
118 }
119 
GetLearnMoreUrl() const120 GURL SuspiciousExtensionBubbleDelegate::GetLearnMoreUrl() const {
121   return GURL(chrome::kRemoveNonCWSExtensionURL);
122 }
123 
124 base::string16
GetActionButtonLabel() const125 SuspiciousExtensionBubbleDelegate::GetActionButtonLabel() const {
126   return base::string16();
127 }
128 
129 base::string16
GetDismissButtonLabel() const130 SuspiciousExtensionBubbleDelegate::GetDismissButtonLabel() const {
131   return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BUTTON);
132 }
133 
134 bool
ShouldShowExtensionList() const135 SuspiciousExtensionBubbleDelegate::ShouldShowExtensionList() const {
136   return true;
137 }
138 
LogExtensionCount(size_t count)139 void SuspiciousExtensionBubbleDelegate::LogExtensionCount(
140     size_t count) {
141   UMA_HISTOGRAM_COUNTS_100(
142       "ExtensionBubble.ExtensionWipeoutCount", count);
143 }
144 
LogAction(ExtensionMessageBubbleController::BubbleAction action)145 void SuspiciousExtensionBubbleDelegate::LogAction(
146     ExtensionMessageBubbleController::BubbleAction action) {
147   UMA_HISTOGRAM_ENUMERATION(
148       "ExtensionBubble.WipeoutUserSelection",
149       action, ExtensionMessageBubbleController::ACTION_BOUNDARY);
150 }
151 
152 }  // namespace
153 
154 namespace extensions {
155 
156 ////////////////////////////////////////////////////////////////////////////////
157 // SuspiciousExtensionBubbleController
158 
159 // static
ClearProfileListForTesting()160 void SuspiciousExtensionBubbleController::ClearProfileListForTesting() {
161   g_shown_for_profiles.Get().clear();
162 }
163 
SuspiciousExtensionBubbleController(Profile * profile)164 SuspiciousExtensionBubbleController::SuspiciousExtensionBubbleController(
165     Profile* profile)
166     : ExtensionMessageBubbleController(
167           new SuspiciousExtensionBubbleDelegate(profile),
168           profile),
169       profile_(profile) {}
170 
~SuspiciousExtensionBubbleController()171 SuspiciousExtensionBubbleController::~SuspiciousExtensionBubbleController() {
172 }
173 
ShouldShow()174 bool SuspiciousExtensionBubbleController::ShouldShow() {
175   return !g_shown_for_profiles.Get().count(profile_->GetOriginalProfile()) &&
176       !GetExtensionList().empty();
177 }
178 
Show(ExtensionMessageBubble * bubble)179 void SuspiciousExtensionBubbleController::Show(ExtensionMessageBubble* bubble) {
180   g_shown_for_profiles.Get().insert(profile_->GetOriginalProfile());
181   ExtensionMessageBubbleController::Show(bubble);
182 }
183 
184 }  // namespace extensions
185