Home | History | Annotate | Download | only in extensions
      1 // Copyright 2014 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/proxy_overridden_bubble_controller.h"
      6 
      7 #include "base/metrics/histogram.h"
      8 #include "chrome/browser/extensions/extension_service.h"
      9 #include "chrome/browser/extensions/extension_toolbar_model.h"
     10 #include "chrome/browser/extensions/settings_api_helpers.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "chrome/common/url_constants.h"
     13 #include "extensions/browser/extension_registry.h"
     14 #include "extensions/browser/extension_system.h"
     15 #include "grit/generated_resources.h"
     16 #include "ui/base/l10n/l10n_util.h"
     17 
     18 namespace extensions {
     19 
     20 namespace {
     21 
     22 // The minimum time to wait (since the extension was installed) before notifying
     23 // the user about it.
     24 const int kDaysSinceInstallMin = 7;
     25 
     26 ////////////////////////////////////////////////////////////////////////////////
     27 // ProxyOverriddenBubbleDelegate
     28 
     29 class ProxyOverriddenBubbleDelegate
     30     : public ExtensionMessageBubbleController::Delegate {
     31  public:
     32   ProxyOverriddenBubbleDelegate(ExtensionService* service, Profile* profile);
     33   virtual ~ProxyOverriddenBubbleDelegate();
     34 
     35   // ExtensionMessageBubbleController::Delegate methods.
     36   virtual bool ShouldIncludeExtension(const std::string& extension_id) OVERRIDE;
     37   virtual void AcknowledgeExtension(
     38       const std::string& extension_id,
     39       ExtensionMessageBubbleController::BubbleAction
     40           user_action) OVERRIDE;
     41   virtual void PerformAction(const ExtensionIdList& list) OVERRIDE;
     42   virtual void OnClose() OVERRIDE;
     43   virtual base::string16 GetTitle() const OVERRIDE;
     44   virtual base::string16 GetMessageBody(
     45       bool anchored_to_browser_action) const OVERRIDE;
     46   virtual base::string16 GetOverflowText(
     47       const base::string16& overflow_count) const OVERRIDE;
     48   virtual base::string16 GetLearnMoreLabel() const OVERRIDE;
     49   virtual GURL GetLearnMoreUrl() const OVERRIDE;
     50   virtual base::string16 GetActionButtonLabel() const OVERRIDE;
     51   virtual base::string16 GetDismissButtonLabel() const OVERRIDE;
     52   virtual bool ShouldShowExtensionList() const OVERRIDE;
     53   virtual void RestrictToSingleExtension(
     54       const std::string& extension_id) OVERRIDE;
     55   virtual void LogExtensionCount(size_t count) OVERRIDE;
     56   virtual void LogAction(
     57       ExtensionMessageBubbleController::BubbleAction
     58           action) OVERRIDE;
     59 
     60  private:
     61   // Our extension service. Weak, not owned by us.
     62   ExtensionService* service_;
     63 
     64   // A weak pointer to the profile we are associated with. Not owned by us.
     65   Profile* profile_;
     66 
     67   // The ID of the extension we are showing the bubble for.
     68   std::string extension_id_;
     69 
     70   DISALLOW_COPY_AND_ASSIGN(ProxyOverriddenBubbleDelegate);
     71 };
     72 
     73 ProxyOverriddenBubbleDelegate::ProxyOverriddenBubbleDelegate(
     74     ExtensionService* service,
     75     Profile* profile)
     76     : service_(service), profile_(profile) {}
     77 
     78 ProxyOverriddenBubbleDelegate::~ProxyOverriddenBubbleDelegate() {}
     79 
     80 bool ProxyOverriddenBubbleDelegate::ShouldIncludeExtension(
     81     const std::string& extension_id) {
     82   if (!extension_id_.empty() && extension_id_ != extension_id)
     83     return false;
     84 
     85   const Extension* extension =
     86       ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID(
     87           extension_id);
     88   if (!extension)
     89     return false;  // The extension provided is no longer enabled.
     90 
     91   const Extension* overriding = GetExtensionOverridingProxy(profile_);
     92   if (!overriding || overriding->id() != extension_id)
     93     return false;
     94 
     95   ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_);
     96   base::TimeDelta since_install =
     97       base::Time::Now() - prefs->GetInstallTime(extension->id());
     98   if (since_install.InDays() < kDaysSinceInstallMin)
     99     return false;
    100 
    101   if (ExtensionPrefs::Get(profile_)->HasProxyOverriddenBubbleBeenAcknowledged(
    102       extension_id))
    103     return false;
    104 
    105   return true;
    106 }
    107 
    108 void ProxyOverriddenBubbleDelegate::AcknowledgeExtension(
    109     const std::string& extension_id,
    110     ExtensionMessageBubbleController::BubbleAction user_action) {
    111   if (user_action != ExtensionMessageBubbleController::ACTION_EXECUTE) {
    112     ExtensionPrefs::Get(profile_)->SetProxyOverriddenBubbleBeenAcknowledged(
    113         extension_id, true);
    114   }
    115 }
    116 
    117 void ProxyOverriddenBubbleDelegate::PerformAction(const ExtensionIdList& list) {
    118   for (size_t i = 0; i < list.size(); ++i)
    119     service_->DisableExtension(list[i], Extension::DISABLE_USER_ACTION);
    120 }
    121 
    122 void ProxyOverriddenBubbleDelegate::OnClose() {
    123   ExtensionToolbarModel* toolbar_model =
    124       ExtensionToolbarModel::Get(profile_);
    125   if (toolbar_model)
    126     toolbar_model->StopHighlighting();
    127 }
    128 
    129 base::string16 ProxyOverriddenBubbleDelegate::GetTitle() const {
    130   return l10n_util::GetStringUTF16(
    131       IDS_EXTENSIONS_PROXY_CONTROLLED_TITLE_HOME_PAGE_BUBBLE);
    132 }
    133 
    134 base::string16 ProxyOverriddenBubbleDelegate::GetMessageBody(
    135     bool anchored_to_browser_action) const {
    136   if (anchored_to_browser_action) {
    137     return l10n_util::GetStringUTF16(
    138         IDS_EXTENSIONS_PROXY_CONTROLLED_FIRST_LINE_EXTENSION_SPECIFIC);
    139   } else {
    140     return l10n_util::GetStringUTF16(
    141         IDS_EXTENSIONS_PROXY_CONTROLLED_FIRST_LINE);
    142   }
    143 }
    144 
    145 base::string16 ProxyOverriddenBubbleDelegate::GetOverflowText(
    146     const base::string16& overflow_count) const {
    147   // Does not have more than one extension in the list at a time.
    148   NOTREACHED();
    149   return base::string16();
    150 }
    151 
    152 base::string16 ProxyOverriddenBubbleDelegate::GetLearnMoreLabel() const {
    153   return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
    154 }
    155 
    156 GURL ProxyOverriddenBubbleDelegate::GetLearnMoreUrl() const {
    157   return GURL(chrome::kExtensionControlledSettingLearnMoreURL);
    158 }
    159 
    160 base::string16 ProxyOverriddenBubbleDelegate::GetActionButtonLabel() const {
    161   return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_RESTORE_SETTINGS);
    162 }
    163 
    164 base::string16 ProxyOverriddenBubbleDelegate::GetDismissButtonLabel() const {
    165   return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_KEEP_CHANGES);
    166 }
    167 
    168 bool ProxyOverriddenBubbleDelegate::ShouldShowExtensionList() const {
    169   return false;
    170 }
    171 
    172 void ProxyOverriddenBubbleDelegate::RestrictToSingleExtension(
    173     const std::string& extension_id) {
    174   extension_id_ = extension_id;
    175 }
    176 
    177 void ProxyOverriddenBubbleDelegate::LogExtensionCount(size_t count) {
    178   UMA_HISTOGRAM_COUNTS_100("ProxyOverriddenBubble.ExtensionCount", count);
    179 }
    180 
    181 void ProxyOverriddenBubbleDelegate::LogAction(
    182     ExtensionMessageBubbleController::BubbleAction action) {
    183   UMA_HISTOGRAM_ENUMERATION("ProxyOverriddenBubble.UserSelection",
    184                             action,
    185                             ExtensionMessageBubbleController::ACTION_BOUNDARY);
    186 }
    187 
    188 }  // namespace
    189 
    190 ////////////////////////////////////////////////////////////////////////////////
    191 // ProxyOverriddenBubbleController
    192 
    193 ProxyOverriddenBubbleController::ProxyOverriddenBubbleController(
    194     Profile* profile)
    195     : ExtensionMessageBubbleController(
    196           new ProxyOverriddenBubbleDelegate(
    197               ExtensionSystem::Get(profile)->extension_service(),
    198               profile),
    199           profile),
    200       profile_(profile) {}
    201 
    202 ProxyOverriddenBubbleController::~ProxyOverriddenBubbleController() {}
    203 
    204 bool ProxyOverriddenBubbleController::ShouldShow(
    205     const std::string& extension_id) {
    206   if (!delegate()->ShouldIncludeExtension(extension_id))
    207     return false;
    208 
    209   delegate()->RestrictToSingleExtension(extension_id);
    210   return true;
    211 }
    212 
    213 bool ProxyOverriddenBubbleController::CloseOnDeactivate() {
    214   return true;
    215 }
    216 
    217 }  // namespace extensions
    218