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